2011年5月31日火曜日

イライラするなぁ

どうもStellarisを使っているとイライラする。

○データシートに書いてある内容が不十分
○データシートに書いてある内容どおりに動かない
○StellarisWareは間違いだらけ

確かに、アプリケーションノートやサンプルあること”だけ”をやっている限りはちゃんと動くし、パフォーマンスもそこそこよいと思う。もちろん、CPU以外の機能についても豊富で充実はしている。

しかし、そのCPU以外の周辺機能は、本来想定された正常な動作から外れるともうガタガタだと言わざるを得ない。エラー時の対応・回復処理とか、処理途中でキャンセルするとか、そういうことをやろうとするととたんに不可解な動作をし始める。

例えば、uDMAのキャンセル方法。
データシートによると、DMAENCLRの該当ビットに1を書き込めばDMA動作を停止するとあるが、実際にはちゃんと止まってくれない。いや、確かに“止まっている”のだけれど、uDMAコントローラ内部では転送途中の状態をまだ記憶しているようで、新しい別の転送先/転送元アドレスを指定してDMAENSETのビットをセットしても、新しいアドレスには転送してくれない。
結局、DMAを停止させるために、まずDMAの要求トリガを発生させる機能(UARTやUSBなど)でDMA要求を出させないようにした上で、そのDMAチャンネルにソフトウェアトリガを繰り返し発行してDMA転送を“本当に”完了させる、という方法を採用するしかなかった。

他にも、USBの転送のキャンセル方法についても不具合発見。
USBデバイスとして機能させ、USBデバイス→ホスト方向への転送を途中で止めたくなったとする。つまり、ホストへ転送するためにFIFOに入れておいたパケットの内容を取り消して、ホストからIN-NAKとさせたい訳だけれど、データシートどおりにUSBTXCSRLnのFLUSHに1を書いてみてもFIFOの内容は消えていない(ホストからINトークンでパケットが取れる)し、TXRDYビットがクリアされると書いてあるけれど実際には自分で0を書いて消さなければ消えない。どうやら、FLUSHビットへに書き込みは、FIFO内部のポインタをリセットするだけでFIFOの内容を消したり、USBコントローラに送信可能(TXRDY)であることをキャンセルさせたりはしていないようだ。
しかも、FLUSHでFIFOをクリアすると(正確にはクリアするためにTXRDYに0を書き込むと)割り込みが発生する。その割り込みは要らないだろう。しかも、このデバイスは割り込みを発生させた細かい要因を教えてくれないので、「FIFOクリア直前にホストがINトークンでパケットを転送した」のか、「FLUSHによるキャンセルが要因」なのか区別がつかないじゃないか!バカヤロウ!

全体的に見て、正常な場合の動作しか想定しておらず、「もしもこういうことが起きたら・・・」という異常系での振る舞いについてはほとんど考えられていないのではないだろうか?あるいは、文化的な違いから、青い目の人は「異常が起きたら全部リセットして最初からやり直し、それでいいじゃん?」的な考えなんだろうか。

とまぁ、悪態をついてみたところで、巨大企業であるTIが動いてくれるわけでもなく、せいぜいこんないところを愚痴を書き連ねるのが関の山って所か・・・、orz

2011年5月6日金曜日

Stellarisのバグ?(その2)

UART+uDMAを使った受信において気づいたこと。

例として、10バイトのデータをuDMAを使って受信することを考える。データシートやサンプルに従って設定すれば期待通りに動作した。しかし、不測のデータ受信やエラーリカバリ処理に難儀した。

通信相手が10バイトではなく13バイト送ってきたと仮定する。
uDMAをBASICモードで設定していれば、まず最初の10バイトをDMA受信した時点で割り込みが発生した。これは期待通り。uDMAをBASICモードで設定しているので、この時点でuDMAの動作はSTOPになっている。
問題は、このあと残りの3バイトを受信したときにStellarisがどのように振る舞うかだ。
このときStellarisは残り3バイトについて、通常の(DMAを使わない)ソフトウェア+割り込みを使う方法と同じように、受信割り込みを発生させてしまう。ここで誤ってその3バイトの受信データをソフトウェアで読み出してしまうと話がややこしくなる。

UART自体は、RXDMAEフラグがセットされている以上は受信データが1バイトでも検出されると、そのUART回路内部でDMAリクエストを保持してuDMAコントローラの方に送っているようで、たとえUARTの受信FIFOの内容をすべてソフトウェアで読み取った後でもそのDMAリクエストはUART内部で残り続けている。つまり、余分な3バイトをソフトウェアで読み取ってもうFIFOには受信データが残っていなくても、次回uDMAの受信設定を行うとまだ保持され続けているUARTからのDMAリクエストによって1バイト分の受信データ転送トランザクションが発生してしまう、という誤動作につながるようだ。

これを回避する方法としては、

(A)DMAを使うときはソフトウェアで直接FIFOを読み出すようなことはしないこと。

(B)上記のような3バイトを「余分なデータ」として読み捨てる場合は、ソフトウェアでFIFOを読み出しても良いが、次回DMAを設定する前にUARTからのDMAリクエストをクリアする方法を行うこと。

の2案が考えられる。
上記の例で余分に受信された3バイト分が、本来次に受信されるべき10バイトのうちの先頭3バイトであれば(=すなわち、正常な次のパケットの一部などであれば)、この(A)を採用してそのまま次のDMA受信を設定&開始すれば問題なく(DMAで)受信される。

しかし、受信された3バイトが本来必要ではないゴミデータであればそれを読み捨てる(B)案を採用せざるを得ない。その(B)案を行う具体的な方法としては、

(B-1)Software Reset Control 1レジスタのUARTnビットを使ってUARTそのものをリセットしてしまう方法

(B-2)UART ControlレジスタのUARTENフラグにいったん0を書いて、1に戻すという方法

の2つが有効であるようだ。
(B-1)の方法は、UARTの設定そのものがリセットされてしまうので、再設定を余儀なくされる。
(B-2)の方法は、UARTの設定は保持されるがUARTENに0を設定している瞬間は受信処理が止まるのでその瞬間に受信データが来ると受信し損ねてしまう、という問題が残る。
どちらにしてもUARTの動作は一瞬でも止まるので、データを受信し損ねる可能性は排除できない。

もうちょっとうまいエラーリカバリ方法を用意してくれないものかなぁ。

2011年5月2日月曜日

Visual Studio 2008の「へぇ~」な機能

Windows VISTAや7では、システム関係のファイルの書き換えに関してちょっとした保護機能が追加されている。WINDOWSフォルダやProgram Filesフォルダは、ファイルを変更しようとするといくらadmin権限でも確認ダイアログが出てくるし、アプリケーションでProgram Files以下に自分用の設定ファイルを保存するような(お行儀の悪い)アプリケーションでは、ファイルの保存先をコッソリとすげ替えさせられている。
特にUAC関連では叩かれることの多いMSだけれども、今回はその件をとやかく言うつもりはない。

今回、Visual Studioを使ってちょっとしたインストーラを作っていて気づいたことがありました。インストーラをデバッグ実行してもデバッグできなかった。理由は上のとおりで、Visual Studioから起動されるプロセスはVisual Studio自体のユーザー特権で実行されるから、Program Filesへの書き込みが禁止されているという訳だった。これまでは、ほとんどの開発をXPでやっていたから気づかなかったし、またReleaseビルドのときは親インストーラである”setup.exe"からの子プロセスとして実行されるインストーラだったので、特権レベルが"インストーラ"レベルに昇格されていて問題なく動いていた。が、開発環境を7で、Visual Studioから直接起動するとこの特権問題が露見した、という具合だったようです。

で、回避策として、Debugフォルダにあるデバッグ対象のインストーラ.exe自体を、エクスプローラ上からプロパティ変更して「管理者として実行する」に変更してみた。すると・・・、

Visual Studioはデバッグセッション開始時に、デバッグ対象.exeが「管理者として実行する」ことを要求していることを自動的に検知してダイアログを表示し、デバッグ処理を継続させるとVisual Studio自体が「管理者」権限で再起動した。

残念ながらそのままデバッグは開始しなかったけれど、この段階ではもうVisual Studioは管理者で実行されているので、再度F5でデバッグを開始すると難なくデバッグプロセスが開始され、以降ステップ実行やら変数インスペクションができた。もちろんインストーラとしてProgram Filesフォルダへのアクセスも自由にできている。

なかなか気が利いている、と思った。
しかし、起動している子プロセス(というかexeファイル)が管理者権限での実行を要求している、ということはどうやって検知しているのだろう?

2011年4月23日土曜日

Windows7 SP1・・・もうリリースされてたの?

今になってSP1が出ていることに気がつきました。だって、Windows Updateは教えてくれなかったし・・・。
いや、ネットで調べてみるとWindows UpdateがSP1を自動検出してインストールされるはず、となっているのだけれど、いま使っているこのLet's Note S9では何度Windows UpdateやってもService Pack 1という文字が出てこなかった。なんでだろう?

と思って調べてみると、どうもS9で使っているビデオドライバのバージョンによってはWin7のSP1が検出すらされないらしい。いったいどういう因果関係になっているのかまったく理解不能だけれど、パナソニックのHPの情報によると、ビデオドライバのバージョンが8.15.10.2104あたりだとダメらしく、2011年3月16日に公開された8.15.10.2281を入れるとうまくいくと書いてある。

で、まずこのビデオドライバをインストールしてみた。そしておもむろにWindows Updateすると、あぁ、確かにService Pack 1という文字が出た!

というわけで、いまはそのSP1が入ったLet's Note S9から書いているわけだけれど、こんな重要な情報は教えてくれないなきゃダメでしょう?>パナソニックさん。
というか、ドライバのアップデートなんかは普通は自分で調べてやるかやらないかを決めるモンだとは思いますが、付属している「PC情報ポップアップ」という(妙な)ソフトが入っているのなら、「修理をご依頼されるお客様へのお願い」なんてしょうもないお知らせを流すよりも、こちらの方が重要だと思うんだけどなぁ。「修理をご依頼される~」は、実際に修理をお願いするときに直接お客さんに伝えた方がよっぽど意味があると思う。

2011年4月20日水曜日

Stellarisのバグ?

らしきものを発見!
と言ってももともとエラッタの多いCPUなので驚かないけどちょっとハマったのでメモ。

uDMAをping-pongタイプで使用するときは注意が必要。

もしDMA動作を中断させる場合はDMAENSETの対応ビットをクリアすればよいのだが、再度DMAを開始するときはPrimaryとAlternateをソフトウェアで変更してはダメ!

DMAALTSET/DMAALTCLRというレジスタでソフトウェア的にPrimary側のDMAレジスタを使うか、Alternate側のレジスタを使うかを選択できる訳だけれど、ping-pongモードを使用してこのレジスタを変更した場合、次のDMAリクエストでDMA転送は行われるけれどDMA転送完了時に割り込みが発生しない、という問題が生じている。
具体的に以下の手順。

  1. ping-pongモードでDMA転送を行うよう設定する。
  2. DMAリクエストが発生して、次のDMA転送がAlternate側(DMAALTSETレジスタのビットが'1')となっているときに何らかの理由でDMAを中断させたとする(DMAENACLRに'1'を書く)
  3. 再度DMA転送を開始するために、DMAALTCLRに1を書いてPrimary側を使うよう初期設定し直したのち、Primary側/Alternate側のChannel Control Structureを正しく設定する。
  4. 次にDMAリクエストを発生させると、現在選択されているPrimary側のChannel Control Structureを見ると確かにXFREMODEがping-pong(=3)からstop(=0)になっていることが分かる。しかし、割り込みは発生しない。
  5. このとき、DMAALTSETレジスタはセットされている(ping-pongモードなのでuDMA自身がPrimary/Alternateを自動的に切り替える)。引き続き、次のDMAリクエストを発生させると、今度はAlternate側のXFREMODEがSTOPに変わると同時に割り込みも発生する。
このことから、どうやらDMAモジュール内部では割り込み関係に関してPrimary/Alternateを選択する内部レジスタのようなものがあるが、それはDMAALTSET/DMAALTCLRとは連動していないのでソフトウェアから変更したAlternateの選択状態をうまく反映できていないようだ。

回避策としては、ping-pongモードを使う場合、DMAALTSETレジスタが示す現在のPrimary/Alternateの選択状況に応じて、Primary→Alternateの順か、Alternate→Primaryの順のどちらかでDMA転送を行うようChannel Control Structureを使い分けなければ行けない。

2011年4月15日金曜日

Visual Studioでビルドした実行コードが・・・

なんか肥大したなぁ。

元は1800KBytesくらいだったはずだが、少し変更してビルドするだけでいまは3000KByteを超えている!そんなに変更してないんだけどな~。テンプレートを追加したわけでもないし。
心当たりと言えば・・・

もしかして、昨日のWindows Updateですかね?そういえば、Visual Studioの再頒布可能パッケージがどうのこうの出てたっけ?

と思って昨日のMS11-025を調べてみると・・・、ありました!KB2465361ですな。ここには脆弱性の改善だのなんだのとかしか書いてなくて、ライブラリが大きくなったとは書いてないな。でも、ネットでしらべるとWin2Kで動かなくなっただの、実行ファイルが大きくなっただの、そういう書き込みがあるので原因はこれだろう。
ってか、本当にこれが原因かどうか調べたいんだけれど、KB2465361のアンインストールの仕方が書いてない。ちょっと調べようがないな~。TrueImageで2、3日前に戻せば分かるんだろうけど、普通そこまでしないよな~。

というわけで、とりあえず動いているようなのでモーマンタイとする(悪)。というより、MFCのスタティックリンクしている時点で“アウト”なのかも・・・。

2011年4月11日月曜日

初IKEA

IKEAに行くのが初めてってわけではなく、相方(=妻)と話のタネに何度か行ってみたり、何かを買うつもりで行ったりしたこともあるのだけれど、いつも「何となく欲しいものがないな」「ピンとくるものがないな」ということで手ぶらで帰ってくるだけだった。が、今回はどうしてもチェストと本棚を買うつもりで出かけました。

先日の引っ越しでIKEAまでの距離は遠くなったものの、高速道路の接続が良くなったりで1時間かからずに行けるようになったのは良かった。
いつものようにまずはコーディネートされたショールームのような部屋を回りながらイメージを膨らませていくわけだけれど、どれも上手にまとめられていて「いいね」と相方と話すものの「欲しいな」と思うところまではいかない。私たちは「何でも良い」とか口では言うものの、やはり人とは一ひねり違う「何か」が欲しいがための何か物足りなく、でもその「何か」を具体的に説明できるほどの想像力と申しますか、妄想力もなく、お店側としては一番やりにくい客のタイプではないかと。

それはさておき、今回は必要に迫られてきているわけだし、多少満足できないorしっくりこない部分があっても、それはそれで「妥協する」ということも覚えなければいけないわけで。まあ、その点ではスウェーデンハウスを建てるにあたって妥協の連続を克服してきた私たちですから、今回は何とか折り合いをつけられるくらいには成長しているはず。
そして、とりあえずといっては何だが、チェストを2種類と本棚を(何とか時間切れの感もあってか)チョイスすることができて、カートを押して別フロアの商品棚に移動。そう!「初IKEA」というのは、これまで何度か足を運んでおきながら、「初めてIKEAで買い物をする」という意味だったのです。
自分の欲しい商品があの巨大な棚の上の方に置いてあったらどうやって下ろすのだろう、とか思いながら見て回っていましたが、なるほど縦方向はすべて同じ商品で上部の棚は在庫分なのだと、今更ながら納得。
で、まずは目的のチェストと同じ番号を発見して、カートに移動させる。がっ、やけに重いではないか!まあ成人男子としては筋力はない方ではないので、フンッ!と踏ん張ればカートに乗せ替えるのはそんなに大変な訳ではない。そして、もう1種類のチェストも見つけてカートに移動。こちらはさほど重くない。
最後に本棚を探す。売れ筋商品だけあって、色のバリエーションの他、付属品も多く探すのにちょっと時間がかかったが棚の前に到着。この棚は高さが2mちょいあるのである程度重いということは予想していたが、積んである商品の一つをちょっと手前に滑り出させるだけでも一苦労。ここで初めて気がついた。箱の横に重さが書いてある。「なっ、なにぃ~、39Kgぉ~!!」

まさかそんなに重いものとは思っていなかった。だって、IKEAはDIY商品、自分で組み立てるから安く上がるのがウリだと思っていたから、まぁ普通の健康な成人なら持って帰られるくらいのものかと思っていた。39Kgというとちょっと力のある人でも気合いを入れないと持てない重さではないか。まして体力のない人なら男子でもまずムリ!あーなるほど、先ほどすれ違った家族連れが若夫婦だけでなくその父親も連れてきていたのはそういうことか。確かに見回してみると、ベッドを持って帰るのに父と息子らしき男性が二人で必死になって棚からだそうとしているな。
と感心している場合ではない。この39Kg、しかも2mもの長尺の物体をどうやって持って帰るか。妻は成人といえども女性だし、39Kgの片側をかかえることは難しそうだ。まして、今日は乳飲み子をかかえている。。。相談して、今日のところは本棚は諦めることにした。
この本棚、特に気に入ったというほどでもないけれど、値段的には割安だし、新居に本棚が必要だし、それにようやく妥協点を見つけて買うと決心したところなのに、こんな理由で買って帰れないとなると今度はむしろ買えないことが悔しく思えてくるのはなぜだろう?
まあ、今回買って帰るチェストも結構重かったし、私の老体のことも考えて潔く諦めることにしよう。レジの方に向かいつつ、ちなみにこのチェストの重さがいったいどれくらいなのか?と思ってカートの横を見てみると・・・「な、なにぃ~、35Kgですか!」。そりゃ重いはずだ。
というか、私はいつの間にか35Kgものものを運んでいたんだな。しかも2つも!となると、先ほど諦めたばかりの本棚39Kg、ここまで重くなれば4Kgくらいの差は目クソ鼻クソ五十歩百歩ではないかと思えてきた。やっぱり買って帰ろうかといろいろと思考するも、やはり重さだけでなく、2m超という長さも侮れないな~。一人でバランスよく持つことを考えると、チェスト35Kgの1.5倍くらいの重さ=50Kg超のものを持てるくらいの怪力の持ち主でなければ持てないかもしれない。そう思うと、やはり今回は諦めて誰か男手をもう一人つれて来るしかないと、自らを納得させるのであった。

というわけで買い物終了。これだけのものを買って2万円台で済むのだから安いのは安い!しかし、もう身体が痛くなってきた・・・。先日お世話になったばかりだけれど、本当に引っ越し業の方や配送業の方の体力はある意味「特殊技能」だなぁ・・・感謝感謝。

2011年3月30日水曜日

引っ越し完了?

先日、引っ越し完了!前日は深夜まで荷造りしてたのでクタクタ。まだ身体がダルい。

新居は一部のコアなファンの間では人気の高いスウェーデンハウス。
私たち夫婦はもともとスウェーデンハウスにするつもりなんて毛頭無かった、というのが正直なところ。「木の香りのする和風な家がいいね」「縁側とかあったらいいなぁ」なんて言っていたし、実際近所に立ち並んでいるスウェーデンハウスを見るたびに「こんな家が好みの人もいるんだなぁ」「和室とか無さそう、雰囲気に合わなさそう」とか言ってたし、モデルハウスを始めて見たときも「これだっ!」というインスピレーションがあったわけでもないのだけれど、だからといってシェアトップ4社のモデルハウスは可もなく不可もなくという感じで、人とちょっと変わったことが好きな私たち夫婦には訴えかけるものが何もなく、心に引っかかるものが残ったのはスウェーデンハウスだけでした。
もちろん契約をするときには十分納得した上で契約したわけで、実際に竣工した家を見て、そして引っ越してみても「良かった」と素直に思えるということは、スウェーデンハウスだけが気にかかったのはやはり何か漠然とした相性の良さを感じていたんだろうなと思う。

そして結露がないというふれ込みは正しかった。まぁ、最近の家はどこの家も結露なんてしないんだろうけど、前に住んでいたマンションは特にひどかったので、これはありがたいなぁ。

景気が低迷して収入も下がり気味というこの時期に、しかも東日本の震災のことを思うと浮かれてばかりもいられないけれど、人それぞれに事情があり前へ進んでいかなければならないということで自らを納得させつつ・・・。

とにかく、しばらくは積み上げられた段ボールの荷物を整理するのに忙殺されそうだ。

2011年3月1日火曜日

Cortex-M3 + FreeRTOS = 備忘録

最近はRTOSとして、FreeRTOSを使ってみることが多くなった。uITRON系よりも良いとか悪いとか比較する気はないけれど、FreeRTOSの特徴を挙げてみると・・・

  • シンプルで必要最低限の機能なのが○
  • タスク間通信機能はもうちょっとあっても良いのでは?
  • タスクのサスペンドとレジュームが「カウンタ」方式でないのが、たま~に困ることも・・・


こんな感じですが、安定性や移植性も十分合格点に達していると思う。

さて、このFreeRTOSですがCortex-M3と組み合わせて、割り込み関数内からいわゆる"FromISR"系APIを呼び出していると、まれにvListInsert()関数内で無限ループしていることが起こる。動かなくなったのでデバッガで強制breakするといつもこの関数内で足止めをくらっているという感じ。

無限ループしている行は、

for( pxIterator = ( xListItem * ) &( pxList->xListEnd );
pxIterator->pxNext->xItemValue <= xValueOfInsertion;
pxIterator = pxIterator->pxNext )
{
/* There is nothing to do here, we are just iterating to the
wanted insertion position. */
}

という部分なのだけれど、親切にもこの行の直前にコメントがあり、”この部分でクラッシュする可能性があるのは次の4つがある”と原因も列挙されている。
今回ハマったのはこのうちの2番目だったのだけれど、リンク先を見てもちょっと分かりにくい。

かいつまんで結論を書くと、
  • カーネルの割り込み優先レベルと、実機で使用している割り込み優先レベルとの関係が重要で、FreeRTOSの"FromISR"系APIを呼び出す可能性のある割り込みハンドラの割り込み優先度はFreeRTOSConfig.hに定義されている`configKERNEL_INTERRUPT_PRIORITY'~`configMAX_SYSCALL_INTERRUPT_PRIORITY'の間に設定しなければならない。


ということになる。
その上で勘違いしやすいのが、Cortex-M3の場合は優先度=0が最も優先度が高く、優先度=255がもっとも優先度が低い、ということ。先のガイドラインに従うと、

  • configKERNEL_INTERRUPT_PRIORITY'はもっとも優先度を低く設定しなければならないから255を設定
  • configMAX_SYSCALL_INTERRUPT_PRIORITYは適宜設定してよいがこの値よりも大きい(=優先度が低い)優先度の割り込みハンドラからは"FromISR"系APIが呼び出せて、逆にconfigMAX_SYSCALL_INTERRUPT_PRIORITYよりも値が小さい(=優先度が高い)優先度の割り込みハンドラからは"FromISR"系APIが呼び出せない代わりに、カーネルよりも高いリアルタイム性で割り込み処理ができる

ということになる。

余談だけれど更にややこしいことに、Cortex-M3のアーキテクチャとしては割り込み優先度は0~255までの256段階で設定できることになっているけれど、実際の実装(StellarisやSTM32、NXPなど)では8段階とか16段階になっているということがある。割り込み優先度レジスタは8bit幅で用意されていても書き込んだ値の下位nbitは常に0となって読み出されるという具合。

実はこの無限ループの一件でハマったのは今回が2回目だったような・・・。学習能力に問題アリだなぁ。

2011年2月25日金曜日

もしもUndoがなかったら・・・

いまはも当たり前のように使っているUndo/Redo機能だけれど、
もしもこの機能がなかったらどうだろう?などと思ってしまった。

テキストエディタで一文字ずつ打ち込んだりDELしたりする程度なら直ぐに打ち直せるけど
(っていうか、結構typoは多い方だと思うので、しょっちゅうやってる?)
範囲を選択してまとめて削除なんて怖くてできなくなるのでしょうかね。
他にもEXCELでもCAD系ソフトでも何でも、大きな範囲を扱うときは
「本当にいいのか~。やっちゃうと元に戻せないよ~。いや、ファイルを保存しなければいいんだ。でもファイル開いてからかなりいろいろ変更したあとだよ。ゲー、アレを全部やり直すのか~。覚えてるかな~。」
なんてことになるんだろうな。そうなると、自衛手段としてこまめに名前を変えながらファイルセーブとかやってたでしょうか?
そう思うと、今更ながらほとんどすべてのソフトで当たり前のように使えているUndo/Redo機能は非常にありがたいものだな。

でもちょっと思い返してみると、その昔8bitのBASICマシンが憧れの的だった頃、ベーマガとか買ってはソースコードひたすら打ち込んでいたけれど、あのときはどうやっていたのだろうか、もう思い出せない。
Undo/Redoなんて高度な機能はあるはずもなく、Cut&Pasteすらあったかどうか記憶にないな。間違えてもUndoはできないから、BSやカーソルキーをひたすら連打して間違い部分を直していたのだろう。それでも楽しくやっていたものだったな。
というか当時のマシンは記録媒体と言えばテープだったので、今のような気軽に「保存」なんてできない。マシン語の打ち込みしても保存し忘れて実行してしまったらあっけなく暴走、何時間もかけて打ち込んだコードが全部パァ、なんてことも日常茶飯事だったから、画面上でのちょっとした打ち間違えを直すくらいは屁とも思っていなかったのだろう。

そういう意味では良い時代になったものだな・・・(歳がバレるな・・・)