たまりば

パソコン・インターネット パソコン・インターネット三鷹市 三鷹市

漢点字一覧表
2015年04月26日 02:24

Windows7~11のペイントの劣化具合
2015年04月15日 23:11

Windows標準搭載の「ペイント」は素晴らしいソフトだったが、Windows7でリボンUIになった時に数々の改悪で使いものにならないソフトに成り下がってしまった。
Windows8(.1)でも変わらず使えないままなのを見るに、もうマイクロソフトにはまともなソフトを作る能力が無いのだろう。悲しいことだ。
ところで、電卓もそうだが、不思議なことにこんな酷い改悪をなされバグも多数あるというのにこれを褒める記事が目につく。使いもせずに見た目だけで判断して記事を書いているのだろう。

仕方ないので、XPのペイントを愛用していた自分が、Windows7からのペイントがどれほど酷いものかを説明しよう。
挙動はWindows8.1で確認しながら書いているが、Windows7でもだいたい確認した。

---
以上は2015年、Windows8.1を使っていた頃に書いた文章だ。
さてその後Windows10が登場、「ペイント3D」というペイントと全く性質の異なるソフトを後継と言い張ってペイントを廃止する計画も出たりしたが、幸か不幸か立ち消えになったようだ。
幸か不幸か。
幸じゃないのと思うかもしれないが、不幸なことに、廃止予定で放っておかれたペイントに下手に手が入るようになった結果、新たなバグ(または仕様)が生まれてきているのである。(下記new!)
その解説や新たに見つけた(たぶん7からの)バグ、書き忘れの追加や画像をつけるなど手直しも加えた。

使い物にならないと言っておきながらなんだかんだでCtrl+ホイールでの拡大縮小は便利で使い続けているのだが、そろそろ本当に代替ソフトを探すか作るかしなければなと思っている。
---


以上は2021年、Windows10の中期に書いた文章だ。
その後Windows11が登場、Windows10においてもいくつかのバグが加わったが、Windows11のペイントは初期はWindows10のものほぼそのままだったのが途中から新しく作り直されたようで、今までの比ではないペイントソフトの根幹に関わるバグの数々が搭載された。
一方で、今まであまりバグは直されることがなかったのが、ちょこちょこと直されるようになってきた。(新しい人が入ったのだろうか。個人的には尻拭いをさせていないで新たなまともなペイントを作る作業に当ててほしいところだが…)
それらの解説を、もう致命的なバグが多すぎて気持ち的にまいってしまっているので今までのように丁寧にはまとめていないが、一番下に適当に追加した。
基本的にTwitterでつぶやいていた内容をまとめたものである。もしかすると書き忘れがあるかもしれないし、新たなバグを発見するかもしれないのでTwitterで私のツイートを「ペイント」で検索するとよいかもしれない。

ただ、使い物にならないと言っておきながらなんだかんだで使い続けていたのだが、さすがにもう何にも使えなくなったので探して見つけた勝手に公開されているWindows10のものを使うつもりだ。なので新たなバグの発見はもう無いかもしれない。
でもなんだかんだで使うかもしれない。
---


・明確なバグ
選択領域を90度回転すると90度回転した領域とのAND部分のみしか残らない
 これは8(.1?)で修正済
 …かと思っていたが先日1回起こった。再現できていないので分からないが微妙な条件があるのだろう。
 これはWindows10ではむしろ確実に発動するようになった…と思っていたのだが今試すと出ない。治ったのだろうか。最近ではもう画像を回転するときは選択範囲を正方形にするようにしていたのでいつから変わったのか分からない…と思っていたらまた出た。相変わらず挙動が掴めない。
インデックスカラーの画像からコピーして新規画像にペーストすると色が変わる場合がある
コピー・ペーストすると同色でも塗りつぶし時に別扱いになる領域が出来る場合がある
 このとき透過判定も別になるので、「透明の選択」はまともに働かない。ワークアラウンドとしては一度背景色の部分を背景色で塗りつぶすとよい。(それでも囲まれた部分が塗りつぶされず完全ではないが)
インデックスカラーの画像は等倍表示で正常に表示されない
モノクロ画像の表示上のバグ
2倍拡大時にクリック位置がずれる
 等倍時のクリック位置と比較して1ドットずれている? 2倍拡大時に顕著に分かる。
Shift+鉛筆での90度移動が横のみしか効かない
 と思っていたが試したところごく稀に縦も出るようだ。数%の確率で。
 また、XPで試していたところ実は45度単位だったことが判明した。90度と違って狙って出せないのであまり意味が無い。
画像がモノクロの時、白で塗ろうとすると黒が塗られる。
ウィンドウに収まらない画像を用意し、端までスクロールし、右・下・右下の点をドラッグして縮めようとすると、ドラッグ終了地点よりも多くカットされる場合がある
小さい選択領域の移動が不可能になったnew!(1909で気づいた。1803では起こらなかったことを確認)
 図を示そう。
選択状態のカーソルの比較
 左が元のもの。選択領域の中にカーソルを置くと移動カーソルになり、掴んで移動ができる。常識的な挙動だ。
 右が新しいもの。4隅4辺の拡大縮小のドットの近くは「選択領域の中でも」拡大縮小機能となる。これにより、縦横ともドットの反応範囲の2倍より小さな選択領域は、移動することができない。(なお、縦横片方が狭くとも細長い選択範囲には移動できる領域が残る)
 また拡大縮小も、狭い選択領域の内側でドットを掴む場合、近い方のドットではなく右・上が優先なようで、思った辺を掴めない。
剪断変形に負の値が入れられなくなった。new!(1607ではできたことを確認)
 「サイズ変更と傾斜」ダイアログの「傾き (度)」の入力欄で、キーボードから「-」を入力しようとすると「許可されていない文字 ここには数字のみを入力できます。」のエラーとなる。
 剪断変形は正負両方の数値を使うものであり、これは明確にバグである。
 なおこのバグで入ったエラー判定にもバグが入っており、ペーストでは負の数も入力できる。
画像の色を白黒にしてからカラーに戻した際に妙な挙動をする
 画像の色を白黒にしてからカラーに戻し、その後鉛筆や直線ツールで線を引くと、場合によって斜めに接しているピクセルの隣に一見アンチエイリアスのような中間色のドットが付くようになる。
 正確な条件は分からないが、新たに引いた線を含む長方形が他の線に重なると出やすいように思う。
アンチエイリアスのような中間色のドット
選択ツールを使うと履歴の挙動がおかしい。
 選択して移動やカット・ペーストなどを何度か連続で行ったあとにCtrl+Zで履歴を戻ろうとすると、いくつもの動作がキャンセルされる。一連の操作がやり直しになり被害が大きい。
 …まあここまでは(正常に動作すれば)戻れる履歴数が増えたのとの引き換えでどちらが便利かは微妙なところだが、もう1つ、
 場合によって、正しく戻れない。
 これが最悪である。
 選択ツールを使った後のCtrl+Zは、しばしば選択領域全体が黒塗りや白塗りになることがある。これが起こるとCtrl+Yでも何らかの正しい履歴には戻せず、最悪の場合過去の作業全てが失われる。


・機能の低下
マウスチルトでの横スクロールができない
拡大率の最大が10倍から8倍に
 なおXPでの10倍は8倍の下の1pxをクリックするという隠しコマンド。
消しゴムやペンのサイズに上限がある
 XPにもあるかもしれないが、少なくとも半径1920pxくらいまで確認できたので、少なくとも「わざわざ付けている」制限は無いだろう。
 なぜ高解像度ディスプレイが流行りだした時にわざわざ制限するのか理解に苦しむ。
背景色を右クリックで選択できない
 背景色をクリック、目的の色をクリック、(そのままだと色々と面倒なので前景色をクリック) の2(or3)クリックに。
図形ツール(四角・楕円)を使うのが面倒
 ~Vista:
 線ツール、線の太さ、目的のツール、線と塗りの種類 の計4クリック。
 線幅が1pxでよい、または塗りつぶした図形を書く場合は線幅の選択が要らず、2クリックで済む。
 7~:
 全て選択する場合は
 図形の四角、[輪郭]、輪郭の種類、[塗りつぶし]、塗りつぶしの種類、[線の幅]、線の幅 の計7クリックが必要。
 なおデフォルトの線幅が5pxと使いづらい幅なので線幅選択は必須。
線ツールと他の図形ツールで色オプションが共有
 例えば四角ツールを線なし・塗りありで使った場合、線ツールで線なしという無意味な設定になっている。
 旧ペイントではこのような無意味な設定はできない。
手書きの線がマウスを離した時点で確定されるようになった
 マウスを離さずドット単位で塗っていた場合、確定された時点で形にずれが生じる。
Ctrl+クリックでの3色目の廃止
 まあこれはたぶんGIFの透明色用で3色目として使うことを想定していなかっただろうし別に使ってなかったのでまあ許す。
キャンバスサイズの変更が(メニューから)できない変な位置に移動した
 「ファイル→プロパティ」。画像の編集の一環であり、ソフト側の設定やファイルの扱いに関係する「ファイル」メニューの下というのは違和感がある。実際、消えたものと勘違いしてしまった。
 画像をきっかりのサイズに合わせたい時は、縁の点をドラッグでなく、数値でサイズを入力できるのが便利だろう。
 (自分はそれでもなんだかんだで縁の点のドラッグで1px単位まで合わせてしまうので今まで気づかなかった)
 なお、メニューからは辿りつけないがCtrl+Eのショートカットは変わらず使える。

(まともな)縦書きができない
 Vistaまで(たぶん; XPのものしか確認できていない)のペイントでは文字ツールに縦書きボタンがあり、縦書きをすることができたが、7でその機能は消えた。
 その代わりとしてしばしば紹介されるのが、フォント名の先頭に「@」を付けることで90度回転した縦書きで入力し、後で逆回転するという古えの機能だ。
 手間がかかるし、Windows2000の頃ならこれでよかったが、ClearTypeを使う現代では使い物にならない。
ツールを使って描いた図形を確定せずに色を変えると色が変わるのが不便
 なお付随してバグに遭遇したが再現しない。Shiftを押しながら赤い円を描いたところ、確定時に色が描画色でも背景色でもない謎のベージュに変わった。直後に同様に試すと普通に赤で確定。


・改良のつもりであろう改悪または無意味
図形が多数
 …っていうほど多くもないしレパートリーが微妙でいまいち使い勝手が良くない。
 だいたい6角形をShiftで縦横比固定したら正6角形になると思うじゃん。
 またサイズによって線の太さが変わったり1ドットのずれができるというバグがあり、見栄えを気にするなら使いものにならない。
ブラシが多数
 アンチエイリアスのないブラシは鉛筆のみに。
 四角のブラシが無くなった。四角を描くのに便利だったのに。
選択領域などのハンドルの判定が大きく
 細かい作業ができず不便。
各種図形ツールがドラッグ終了後にも位置をいじれるように
 このせいで線ツールで線を続けて引くことができなくなった。
 一番必要だったベジエ曲線はいじれない。
トリミング機能
 キャンバスサイズの変更の代わりに入ったのだろうか。
 改良点とちょっと迷ったがこっちで。選択範囲が作ってからサイズ調整できたらまだ使えたんだけどね。
 「全選択からドラッグして左上を合わせ、右下の点をつまんでサイズを合わせる」の方が便利。


・(数少ない)改良点
Ctrl+ホイールで表示倍率が変更でき、縮小もできる
アンドゥ回数増加
 上で述べたように選択ツールを使った際にバグはあるが。
文字入力機能の拡充
 とくに拡大表示中でも文字入力ができるのが便利。
保存形式のデフォルトがpngに
 とはいえjpgが好きな人にとっては改悪。選択式にすればよいものを。
アンドゥー履歴が増えた。
キーボード操作が追加された
 Ctrl+PgUp/Downで拡大縮小。(XPのときは指定倍率/1倍切り替え)
 選択領域を動かすのが1ドット単位でできるのは利用価値がある。
 Spaceで左クリック。右は?
ただし付随してバグが発生している。
 まれに、ペイントを起動している時、フォーカスがなくても、矢印キーを押すとカーソルがペイントのキャンバス内で動く現象が発生する。
 ペイントのキャンバス外で矢印キーを押すと、キャンバスの端まで瞬間移動する。
 調べて知るまでペイントのせいだとは気づけなかった。単体でバグを出すのみでなく他に影響するバグまで出すという酷い状況。

・余談: XPのペイントでバグを見つけた。
自由選択でドラッグして何らかの形に選択する。
自由選択で、クリックする。
選択範囲を移動すると、前回の選択の形に空白(背景色)になる。
しかしこの部分は表示上だけで、その後ブラシや選択範囲などが上を通ると元に戻る。
塗りつぶしをするとその形に塗りつぶされ、戻らない。


・未確認バグ
Twitterで2つのバグ情報を頂いた。残念ながらどちらも自分の環境では再現できなかったのだが、再現動画を頂いたので貼っておこう。
「キャンバスサイズの幅を変更しただけで勝手に高さまでズレる」
これ自体は再現できなかったものの、上で挙げた画面に収まらない画像をドラッグで縮める際にドラッグ終了地点よりも多くカットされる場合があるバグと似ているので、同じ現象かもしれない。
→その後自分の環境でも1度だけ再現した。このときは(いつものバグで)縦が指定以上に切れたのでアンドゥー後に数度に分けてカットした(この際も指定以上にカットされた)後だったので何か条件があるのかもしれない。

「矩形選択中に矢印キーを一瞬押しただけで数ドット動く」
こちらも再現はできなかったものの、この操作の際には矢印キーを押し続けると連続移動になるのだが、その際の長押し判定時間がキーリピート設定(キーボードのプロパティの「表示までの待ち時間」)とは無関係に、最短のキーリピート待ちより更に短い時間なので、PCが処理落ちなどした場合に長押し判定になってしまうこともありえそうに思う。


・Windows10後期~Windows11あたりで気付いた変化
Windows10で(XPのもので発生しないことを確認)、「傾き」の変形で選択範囲が広がるとき、キャンバスが狭いと傾きの値を無視してキャンバスの端で止まる。なおサイズ変更にはこのバグはなく端を超えて広がる。
ペイントは白黒モードではパレットが様々な濃さのタイリングパターンになるが、これが正常な頃(Vistaまでか、あるいは7や8も正常だったか)は極力均一なパターンになるよう選ばれたパレットであったものが、Windows10ではどれも微妙に均一でない半端な濃さのパターンになった。しかも、確定前と確定後でパターンが変わり、塗りと線でもパターンが変わる。
 タイリングパターンの均一性の例を示すとこんな感じ。左2つはXPのペイントのパレットの中で特に均一なもの。右2つは、Windows10で同程度の濃さのパターンはこんな感じだった再現。
均一なタイリングパターンとそうでないパターン
Windows11初期になって悪化し、白黒モードでパレットの表示が変わらなくなった。カラーのままの表示で、塗るとおそらく対応した濃さの(半端な)タイリングパターンになる。
Windows11のアップデートで、白黒モードは完全に無くなった。
Windows11でパレットが丸くなり、クリック範囲が分からなくなった。(なおクリック範囲は以前と変わらない四角の領域である)
Windows11で待望のキーボードショートカットがついた。ただし見えているツールにしか効かない(折りたたまれている中身には無効)。
また、(以前からのキーボードショートカットの)線の太さを変えるCtrl++/-が、メニューにフォーカスしている状態では効かなくなった。
Windows10までのペイントで画像ファイルを編集するときは開いてCtrl+ACNVで素早く新規ファイルとして扱えるので便利だったが、Windows11は選択してコピーしただけで変更が加わった扱いになるようになって不便になった。…と思っていたらまた戻って使いやすくなった。
Windows11のいつからか、拡大縮小が中途半端かつ段階が細かくなった。基本的にペイントのようなソフトで整数倍以外の拡大は使う場面が無いが、最大以外の整数倍の拡大がCtrl+ホイールで不可能になった。他のソフトでは半端な拡大率でも整数倍にスナップするような変化をするものもあるがそれもしない。Ctrl+PageUp/Downを使えば10%単位で拡大できるので整数倍の拡大は面倒だが可能。100%はCtrl+0。
Windows11のペイントはたとえ拡大率100%であってもドットバイドットでは表示されない。つまり、中間色が表示される。100%以外の(整数倍の)拡大率は言うに及ばず。
図は適当なビットマップフォントの文字列をスクリーンショットからペイントに貼り付けたものを、見やすいようにトーンカーブを掛けたもの。拡大して見れば右端の方で線の右に色がついているのが見えるだろう。
MSペイントのボケ
おそらく表示がドットバイドットでないのに関連して、数々のバグがある。
 選択範囲の枠線がピクセルに乗っておらずボケており、気持ちが悪い。
 Windows10では拡大時にクリック位置が1ドットずれるが、11では整数倍の拡大率でも等倍でもクリック位置のずれが一定せず1ドットずれたりずれなかったりする。すなわち等倍時に任意のドットを操作することはできない。ドラッグでも同様。
 条件がはっきりしないが(画像をクロップ? 非整数倍拡大時のクロップ?)、画像を保存した際にも中間色が表示されているその通りに保存される。
 拡大時に選択範囲やキャンバスサイズを動かすと画像のドット単位でなく表示上の1ドット単位で滑らかに動くため、どこで切れるのか分かりづらい。
古くからペイントでは左ドラッグ中に右クリックや右ドラッグ中に左クリックで描画中の操作をキャンセルできた。これが、挙動がコロコロ変わるのでいつのことだか記憶や記録が定かでないのだが、とにかくWindows10後期かWindows11で、一部のツールでしか効かなくなり、しばらくして使えるようになったかと思ったが、左ドラッグ中に右クリックのみで右ドラッグ中に左クリックは効かなかった。
また、消しゴムツールではドラッグ中逆クリックでキャンセルされないばかりか、履歴を破壊してCtrl+Zでも戻れない(消しゴムの前に行った操作が戻る)謎の消しが発生するようになった。
選択中にCtrl+Xで選択領域が消えるのでなく全体が消える。
直線ツールで線を引いた直後に両端周辺で端点を動かせるだけでなく直線周辺の遥かに広い範囲で直線全体を動かせて邪魔。
Windows11になって今更右クリックで背景色選択機能が戻った。あとだいぶ最近知ったがWindows10でもShfit+クリックで背景色を選択することができた。
小さい選択範囲をドラッグできなかったのが、Windows11でできるようになった。
上で述べたようにWindows7でツールのサイズに異様に小さい上限がついたが、(Windows10とWindows11で)消しゴムだけ最大サイズが50pxから248pxに拡大していた。
25%以下に縮小して右下の点をキャンバス左上隅(より左上)までドラッグすると、「ビットマップは、1 辺あたり 1 ピクセルより大きくなければなりません。」のエラーで失敗する。表示サイズ50%以上なら1×1pxにまでリサイズされる正常動作。
(ペイントだけではなくOSの標準機能かと思うが)Windows11のカラーピッカーはデフォルトの色に原色が無くなり不便。
Windows11になって終了時の保存確認ダイアログにアクセスキーが付かなくなりNで閉じられなくなって不便だったが、いつの間にか(表示上アクセスキーは無いが)Nで閉じられるようになった。便利だが書いていないと分かりづらい。必要なものを書かないのは最近のUIの流行りだが大嫌いだ。
Windows10では、メニュー項目の「Invert selection」(選択範囲の反転)が「選択の切り替え」に、そのツールチップの「Reverse the current selection.」(現在の玄琢範囲を反転します)が「現在の選択範囲を元に戻します」に誤訳されている。
 Windows11では、ツールチップが無くなった。
Windows11では、フォント名を手入力できない。

なおWindows11での改善のつもりであろうレイヤー機能についても多少触れておくと、選択ツールの「透明の選択」で(バグが無ければ)行えていたような操作が行えなくなり、不便である。
  

  • Atari2600詳細
    2015年04月13日 01:20

    アタリショックで有名なAtari2600。
    フェアチャイルドチャンネルFに続くカートリッジ交換式ゲーム機であり、ファミコンの前世代機としてアメリカで流行していたらしい。
    日本では流行らなかったため日本語での情報が少ないのが残念だ。とりあえず日本語で一番詳しくなるくらいに仕様をまとめてみる。
    性能が分かりやすいよう、日本人に馴染みの深いファミコンとの比較を各所に入れた。

    スペック

    ・CPU
    6507、1.19MHz
    この6507というCPUは6502の機能削減版で、割り込みが存在しないことと、メモリ領域が6502の64KBに対し8KBしかない点が違いである。
    ファミコンのCPUもBCD演算が無い他は機能は6502と同一なので単純に比較すると、ファミコンは1.79MHzなので、演算性能はファミコンの2/3と言えそうだ。
    が、Atari2600はファミコンと違い画面の描画にCPUを使うため、実質的に使用できるCPU時間は非表示期間中のみである。
    Atari2600の一般的な解像度は縦192pxなので、262-192=70と、1/4程度の時間しか演算に使えない。
    ファミコンは単純な(ラスタスクロールなどしない)静止画を表示する分にはCPUを使わないので、これと比較すると演算性能はファミコンの1/6程度とも言える。
    なおAtari2600も画面の描画を止めればCPU時間を演算に割くことができる。
    例えば「Vedeo Chess」ではAIの思考中は画面がチカチカする単色になる。
    https://www.youtube.com/watch?v=wdpRDYQgm84

    ・メモリ
    ワーキングRAM128バイト、VRAM数バイト
    ファミコンはワーキングRAMが2KB、VRAMが2KBである。
    ワーキングRAMが6502の高速なゼロページ領域に収まっているのでちょっと嬉しい。
    なおワーキングRAMは6502のスタック用の1ページにも重複してマッピングされているという面白い構造。
    128バイトでは少ないということでカートリッジ側に128バイトや256バイトのRAMを積むこともあったようだ。

    画面表示

    ・解像度
    横解像度は回路で決まっており、160ドットである。
    問題は縦で、(NTSCでは)192pxという値がよく見られるが、これはこの値が多くのゲームで使われているとか、この値が推奨されている程度の意味だろう。
    Atari2600の画面描画の特徴として、メモリには常に走査線1ライン分の情報しか持っていない。
    そこで、1ラインごとに、HBLANKの間にメモリ上の情報を書き換えて画面を作るのが基本の操作となる。描画中に何もしなければ縦線しか描けない。
    つまり、縦方向にどれだけの長さ描画するかはプログラムによって決まる。
    これより、NTSCの規格上許されている最大値をAtari2600の縦解像度の値とするのが妥当だろう。
    (規格外の走査線数を出力することすら可能だが、さすがにそれは考えないことにする)
    NTSCの規格上、映像信号を入れられるのは1フィールドあたり242.5ラインだが、NTSCの規格は2フィールドを半ラインずらすことになっているのをAtari2600などのゲーム機はずらしていないので、242pxとなる。

    なおこの192pxというのは242の約79%にあたる。
    横方向の160pxは44.7μ秒ほどで、描画期間約53.4μ秒の83.5%ほど。
    当時のTVで画面内に表示できる範囲はこの程度だったのであろう。

    さてではこの160×242ドットに自由に絵が描けるかというとそうではない。
    画面構成は後述するが、1ドット単位で絵を作れる構成要素は「オブジェクト」という、今で言うスプライトのみである。
    ファミコンのスプライトに横8枚制限があるのと同様、Atari2600もオブジェクトだけで画面全体を覆うことはまず不可能である。(たぶん本当に不可能だと思うが自信がない。後述)
    もう1つの構成要素としてPlayFieldという今で言う背景面のようなものがあるが、こちらは横解像度が40px、つまり160pxの画面に対し4pxごとにしか絵を描けない。
    これにより、Atari2600の画面はやけに解像度の低い背景の上にキャラクターがぽつぽつと置かれている独特な見た目になる。
    ただし、横は4ドット単位だが縦方向には1ドットごとに絵を書き換えられるため、上手いプログラムでは巧妙に横方向の解像度の低さを感じさせない絵柄を作っている。
    例えば「Pitfall!」の穴や木の表現が上手い。
    Atari2600 Pitfall!

    ・画面構成
    BackGround:
    以降の全てが無い部分の色

    PlayField:
    今で言う背景面
    単色。(Scoreモードでない場合)
    横解像度40px。
    拡大縮小やスクロールなどの機能は無い。
    「Scoreモード」では左右それぞれがPlayer0/1と同色で表示される。

    オブジェクト:
    今で言うスプライト。3種類5個のオブジェクトがある。
    Player0 / Player1
    横8px、それぞれ単色。
    一定間隔の2個または3個に増殖したり横幅2倍・4倍で表示する機能あり。
    具体的には、以下の8通り。2倍幅2個などといった自由な組み合わせはできない。
    Atari2600 Playerの表示パターン
    4倍幅モードでは横32pxと画面横幅の1/5。2つのPlayerで計2/5。ファミコンではスプライト上限横8個で画面の1/4なので、巨大キャラを動かすことについてはファミコンに優っていると言えなくもない。
    (まあファミコンなら背景面を使うところだが)

    Missile0 / Missile1
    横1px
    横幅2・4・8倍表示が可能
    対応するPlayerと同色
    個数・間隔もそれぞれのPlayerと同じ

    Ball
    横1px
    横幅2・4・8倍表示が可能
    色はPlayFieldと同色
    増殖はしない

    ・発色数
    扱える色は、オリジナルのNTSC版では
    (15色相+無彩色)×明度(?)8段階 = 128色
    PAL版では色信号の周波数が約15/12倍である関係か、
    (12+無)×8=104色
    と少々少ないが、どちらもファミコンの54色と比較すると多い。
    SECAMでは仕組みが全く違い明度に対応したデジタル8色のみ。

    なお「明度」と書いたが、彩度も連動して変わるかもしれない。(ファミコンがそうであるように)

    同時発色数は、1ライン中に同時に出せる色は基本的には以下の4色である。
    ・BackGround
    ・PlayField・Ball
    ・Player0・Missile0
    ・Player1・Missile1
    ただしライン中にレジスタを書き換えればこの限りではない。
    例えばAcidDropというゲームがあり、横1列に色違いの7区画+両端の色を表示している。
    https://www.youtube.com/watch?v=5Po47y0ALpU
    また、頑張れば下図のように横15色も可能である。
    Atari2600 1列に15色

    なお縦方向には制限はないので、ファミコンと違い画面中同時発色数は扱える全ての色128色が出力可能。縦方向のグラデーションはAtari2600の特徴である。

    ・オブジェクトの横位置の指定
    現代の感覚で考えれば、オブジェクトのX座標をレジスタに指定するとその位置に書いてくれる仕組みがあると思うだろう。
    否、そんな軟弱な仕組みではない。
    走査線を描画中にここぞというタイミングで各オブジェクトのリセットレジスタに書き込むことで、その地点のX座標に(次ラインから)オブジェクトが表示されるようになるのである。

    とはいえCPUの1クロックは画面上の3ドットに相当する。また時間調整のためのループは最短で1周に5クロックが必要であり、都合15ドットごとにしか書込みができない。
    そこで微調整機能が用意されている。
    5種のオブジェクト(Player0, Player1, Missile0, Missile1, Ball)それぞれについて横位置の差分を登録し、HMOVEレジスタに書き込むことで次ラインでの表示位置がその値だけずらせる。
    これが+7~-8まで設定できるので、任意の位置にオブジェクトを表示することが可能となる。
    またBallやMissileを表示したままラインごとにHMOVEをすることで斜めの線が表示できる。上のPitfall!の画像にもある。ファミコンにはできない芸当だ。
    なおこのHMOVEへの書込みを行うと、次ラインの左端8ドットが黒になるという妙な仕様があり、これによる櫛状の横線がAtari2600の画像の特徴となっている。

    高等技術

    プログラミング技術が成熟するにつれ、走査線の描画中にレジスタ内容を書き換えることで同時表示内容の限界を超えるテクニックが使われるようになる。

    ・PlayField内容の書き換え
    実は上で横40pxと言ったもののデータは20px分しか無く、1ライン中何もしなければ右半分が左半分と同じか、あるいは左半分を左右反転させたもので表示される。
    横40pxをフルに使うにはライン中の書き換えが必須である。
    なおこれは最初から想定されていた操作だろう。PlayFieldのScoreモードはライン中書き換えを前提としている。

    ・Player内容の書き換え
    Playerを複数表示モードにした状態で、1つ表示された後に内容を書き換えると、2つ目に別の内容を表示できる。
    これを最大限に駆使すると、Player0/1を3つづつ交互に並ぶようにして横48pxに自由に絵が描ける。
    ただし、このためにはメモリ(レジスタ)へ4回の書込みが必要になる。(CPUのレジスタとメモリにマップされたレジスタが紛らわしいな…)
    6502では(CPUの)レジスタからメモリへの書込みが最速で3クロック掛かる。画面のドット数で言うと9ドット分である。
    [--P0--][--P1--][--P0--][--P1--][--P0--][--P1--]
            ^P0      ^P1      ^P0      ^P1
    このように、猶予は4ドット分しか無く、書込み以外の操作を入れる余裕は無い。
    かつ、6502での最速の書込みはレジスタが3つしか無いため3連続が限度である。
    よって普通にはこの表示はできないことになる。

    この状況を打破するためには裏レジスタを使う必要がある。
    裏レジスタを理解するには、Vertical Delay(垂直遅延)機能の理解が必要である。
    この機能を有効にすると、Player0/1の書き込みはそれぞれの裏レジスタになされ、他方への書き込みを契機に表レジスタに移される。
    つまり、Player0/1の内容の書込みを他方への書込みまで遅延させるという動作をする。
    「Vertical」Delayの名は、1ラインごとにPlayer0と1へ交互に書き込む場合に1ライン分縦に遅延することになることによる。
    通常の使い道としては、Player0と1を両方1ラインごとに書き換えるのは処理が重いため、1ライン置きで交互に書き換えるようにしたとき、縦位置がずれないように使うものだろう。

    これを利用して、P0,P1両方の遅延を有効にし、非表示期間中にPlayer0,1に加えPlayer0の裏レジスタに表示内容を入れておく。
    すると、
    非表示期間:
    lda A
    sta P0 ;      P0裏=A
    lda B
    sta P1 ;P0=A, P1裏=B
    lda C
    sta P0 ;P1=B, P0裏=C
    lda D
    ldx E
    ldy F
    描画中:
    sta P1 ;P0=C, P1裏=D
    stx P0 ;P1=D, P0裏=E
    sty P1 ;P0=E, P1裏=F
    sta P0 ;P1=F, P0裏=D(表示されないのでstxでもstyでもよい)
    このように最速での4連続書込みが可能となる。

    ・オブジェクト増殖
    通常はリセットレジスタに書き込んだ次のラインからオブジェクトが表示されるのだが、Playerの2個・3個表示モードでは頭の1つを除いて同ラインに表示できる。またBallも同ラインから表示される。
    これを利用して、ライン中に複数回リセットをすることで1ライン中に複数個のPlayerを表示できる…らしい。
    これを使えばひょっとして画面を完全にオブジェクトで覆うこともできたりするのだろうか。恐らくは処理時間が足りず不可能だと思うが、この動作についてはいまいち仕様が理解できていないため自信がない。仮にできても意味のある絵を表示するのは困難だろう。
    この動作については下記「TIA Hardware Notes」が詳しいので気になる人はこれにあたってほしい。

    その他機能

    ・音源
    数種類のノイズと中途半端な音程の矩形波を出せるチャンネルが2チャンネル。
    あまり興味が無いので説明は割愛する。
    「Tone Toy」というHomebrewなソフトがあるので試してみると楽しいだろう。
    https://www.youtube.com/watch?v=Zco1hnyDiVI

    ・衝突検知
    ファミコンにも0番スプライトと背景面の衝突判定があるが、Atari2600ではPlayField, Ball, Player0/1, Missile0/1の6つの物体の全ての組合せ15通りについて衝突判定ができる。
    6502の「BIT」命令で読みやすいよう6,7bit目が立つ。

    ・タイマー
    ファミコンにもあれば良かったのに…。

    参考文献

    ネット上でいろいろと探した気がするが、結果的に以下の2つにだいたい全てまとまっていた。
    Atari 2600 Specifications http://problemkaputt.de/2k6specs.htm
    Atari 2600 TIA Hardware Notes http://www.atarihq.com/danb/files/TIA_HW_Notes.txt  

  • ベースラインPICの注意点
    2015年04月11日 23:36

    PICマイコンは時代を追ってベースライン→ミッドレンジ→ハイエンドと進化してきたが、日本で有名になったPIC16F84がミッドレンジのせいか、ベースラインPICに関する日本語の情報が少ない。
    そのためミッドレンジに慣れた者がベースラインを使おうとして戸惑うのをたまに見かける。
    そこで、ミッドレンジからベースラインへのマイグレーションを念頭に、この2つの違いを解説したい。
    今更ベースラインを使う意味があるかは微妙な所だが、安さで10F200や16F57を選ぶこともあるだろう。

    PIC10F200: 現在秋月で35円、aitendoで30円。自分の知る限り最安のマイコン。
    PIC16F57: 現在秋月で70円。I/Oピンが20本あり、3.5円/ピン。自分の知る限りI/Oピンあたり価格が最安のFlashマイコン。
    (ワンタイムを含めるとI/Oが43ピンで8個400円のこいつに負ける→ H8S16ビットワンタイムマイコンHD64P2128PS20V(8個入))

    見分け方

    比較の前に、まずベースラインとミッドレンジの見分け方について。
    型番で簡単に見分けられるのだが、これが知らないと分かりづらい。自分も最近まで知らなかった。
    まずPICの型番を見ると先頭に10F, 12F, 16F, 18Fとある。(さらには17F, 24F, dsPIC30, dsPIC33, PIC32MXとあるがこれらは単純なので割愛する。Fの部分がLFやCやHVのものもあるが割愛する)
    PICを分類するのにこの先頭の数字で分類されるのが一般的だが、実はこの数字はベースラインとミッドレンジの区別には役立たない。
    12Fがベースライン、16Fがミッドレンジであるとする誤った記述をたまに見かけるが注意が必要だ。
    (ただしハイエンドを見分けることはできる。18Fがハイエンドだ。)
    ではどこで見分けるかというと、英字の次の桁。
    これが(現在のところ、ごく一部の例外を除き)2か5ならばベースラインである。(また、ベースラインならば2か5である)
    例えば10F222、16F54、12F509はベースラインであり、10F322、16F84、12F609はミッドレンジである。
    (初期に命名法が確立していなかったと思しきPIC16C55Xというミッドレンジが存在する)
    また後半の数字が1始まりで4桁以上ある12F1*,16F1*はEnhancedミッドレンジである。
    また現在のところ数は少ないが、Enhancedベースラインというものも存在する。型番の規則はベースラインと同じだ。
    現在存在するEnhancedベースラインはおそらく、12F529T39A, 12F529T48A, 16F527, 16F570の4つのみである。

    なお先頭の数字10,12,16は、ピン数に対応している。6ピンが10、8ピンが12、14ピン以上が16だ。
    (ただし通常のI/Oピン以外に特殊機能のピンがある場合これに従わない。例:12F529T39A)
    (また今後8ピンも16Fになるようだ。例: 16F18313)
    (ハイエンドの8ピンはどうなるかというと、今のところ存在しないが、実は発表だけされて発売されなかった18F010/020がある)


    以下機能の違いを見ていく。

    割り込み

    ミッドレンジで追加された機能で最も重要と言える。
    割り込みを使ったコードは全てポーリングに書き直すしかない。
    割り込みがどうしても必要ならミッドレンジを使うしかないし、そうでなくとも割り込みの方が簡単に書けるならミッドレンジを使うのが身のためだ。
    ただもしかするとウォッチドッグタイマ(WDT)によるリセットで割り込みの代用ができるかもしれない。

    タイマーのオーバーフロー

    ベースラインもミッドレンジもTMR0の機能は基本的には同じである。
    ただし、ベースラインには割り込み機能が無いのに伴ってオーバーフローフラグも無い。
    割り込みを使っていなくてもオーバーフローフラグを使っていたプログラムは書き直しが必要だ。
    簡単な対処法として、TMR0を7bitのタイマーと考えて、最上位bitをオーバーフローフラグの代わりに使う方法が考えられる。
    タイマーが1周する前にチェックする必要がある点を除けば同様のプログラムが使える。
    またはクロック単位できっかり合わせたいなら例えばこんな感じ。
    synch:
        btfss TMR0,7
        goto $-1
        btfsc TMR0,7
        goto $-1
        decf TMR0,W
        addwf PCL,F
        nop
        nop
        nop
    when:

    スリープからの起床

    ベースラインもミッドレンジもSLEEP命令によるスリープ機能は持っているが、起床時の動作が異なる。
    ミッドレンジではスリープから起床するとSLEEP命令の直後から実行を再開する。(加えてその前に割り込みを掛けることもできる)
    それに対しベースラインではスリープからの起床はリセットと同等であり、SLEEP命令の直後から実行する機能は無い。
    先頭にパワーオンリセットとスリープからの起床を判別するコードを書いて分岐する必要がある。

    命令

    ベースラインからミッドレンジで追加された命令はわずか4つのみである。
    ADDLW, SUBLW, RETURN, RETFIE
    また、命令一覧から消えた命令が2つある(実はミッドレンジでも使える)。
    TRIS, OPTION
    その他の命令は、機能は同じだがアドレス指定のビット数が増えている。これによる違いはメモリ構造の項にて。

    これらの追加命令の対処法を示す。
    ・ADDLW
    比較的簡単。RAM1つ使用、2命令増で次のようにできる。
        addlw NN
        ↓
        movwf temp
        movlw NN
        addwf temp,W
    そもそも加算の順番を変えるだけで済むこともあるだろう。
    また、加算が必要かと思いきやIORLWが使える状況もたまにある。

    ・SUBLW
    単純に置き換えようとするとWの退避が面倒なことになる。
        sublw NN
        ↓
        movwf temp
        movlw NN
        movwf temp2
        movf temp,W
        subwf temp2,W
    順番を変えて事前に被減数を用意しておくのがよいだろう。つまり、
        movlw NN
        movwf minuend
    と準備しておくことにより
        subwf minuend,W
    とできる。定数からの減算なら準備は1回でよいためコア部分は同命令数にできる。

    ・RETURN
    ベースラインには値を返さないRETURN命令が無く、RETLWしか無かった。
    Wの値を使いたければ、適当な場所に保存しておく必要がある。
        movwf w_buf
        retlw 0
    ;---
    ;(呼び出し元)
        call where
        movf w_buf,W
    Wを保存しておく必要が無ければ適当な値を返すRETLWをそのまま使えばよい。というより、ベースラインでは「RETURN」が「RETLW 0」のマクロとして登録されているので、何も考えず「RETURN」と書くだけでよい。
    なのでむしろ、RETURN命令を使ったミッドレンジ向けコードが書き換えずそのまま動いてしまうことに注意が必要である。

    ・RETFIE
    割り込み機能が無いので当然ながらどうしようもない。

    メモリ構造の違い

    ・RAM(ファイルレジスタ)のマッピング
    RAMのバンク分けがミッドレンジ128バイトごとに対しベースライン32バイトごとと、バンクごとの容量が1/4しかなかった。
    (対応してファイルレジスタを指定する命令すべてでアドレス指定のbitが7→5と少ない。)
    また連続で使えるメモリ量はミッドレンジの80バイトや96バイトに対しベースライン16バイト(bank0は+数バイト)。
    ミッドレンジからベースラインへ移行する場合はメモリ量が足りたとしてもバンク切り替えが増えるのに注意が必要である。
    ただ、間接アドレッシングで16バイトを超えるメモリを連続的に扱いたいときは、FSRの4bit目を常にセットするように扱えばよいので、ミッドレンジの80バイトと96バイトの領域が混在する複雑な構造よりだいぶ楽である。
    またバンク共通のメモリの位置も異なり、ミッドレンジでは各バンクの最後16バイトであるが、ベースラインは前半16バイトのうちSFRでないあまり部分がバンク共通となっている。
    図にまとめると以下のようになる。
    ベースラインとミッドレンジのRAM構成比較
    注:
    大抵の機種はこの構成に従っているが、そうでないものもある。おそらく古いものが異なるのだろう。例えば16F84Aはベースラインに似た割り付けである。
    図は可能な最大量を示した。実際に実装されているメモリ量がこれより少ない場合、データシートの図はこれと異なる。
    ベースラインのバンク共通メモリの量はSFRの量に依存するため、機種により異なる。例えば12F509では9バイト、16F526では3バイトである。

    ・特殊なレジスタマッピング
    特殊なレジスタにTRISxとOPTIONがある。
    この2つは、ベースラインでは通常のレジスタとしてマッピングされていない。
    その代わりに、「TRIS」命令と「OPTION」命令でWの内容を書き込む仕組みになっている。
    書込みのみで読み出しはできないため、あとで値が必要になるなら適当なRAMに保存しておく必要がある。

    命令の使い方は、OPTIONはオペランドをとらず、1つしかないOPTIONレジスタにWを書き込む。
        option
    ミッドレンジで同等の動作は、(適切なバンクになっている前提で)こうである。
        movwf OPTION_REG

    TRISは、オペランドにI/Oポートレジスタ(のアドレス)をとり、対応するTRISxレジスタにWを書き込む。
        tris PORTA
    ミッドレンジではこう。
        movwf TRISA

    ・FlashROM
    Flashのページ分けは注意が必要である。
    まず、ミッドレンジの2048(0x800)ワード毎に対し、ベースラインでは512(0x200)ワード毎にページが分けられている。
    つまり、ミッドレンジでは「0x800の壁」と呼ばれているものはベースラインでは0x200の壁となる。
    これに対応してGOTO命令では飛び先のアドレスが9bit指定できるのだが、CALL命令では飛び先のアドレスは8bitしか指定できない。
    その分のアドレス1bitを別の場所で指定できるわけでもないため、CALLの飛び先のアドレスは各ページの前半256命令のみで、後半256命令にはCALLで飛ぶことはできない。
    ミッドレンジではGOTO・CALLとも同じく11bitになりこの状況は解消されているので、ベースライン特有の制限である。

    CALLで飛べるのがページ前半のみということは、後半はサブルーチンに使えないのかというと、そうでもない。
    このようにすれば、1命令・2サイクル余計に掛かるものの、サブルーチンの実体を後半に置くことができる。
    ;(前半)
    func1entry:
        goto func1core
    ;(後半)
    func1core:
        ...
        retlw 0
    前半に置かなければならないのは、定数テーブル参照などPCL操作をするようなコードのみである。
    というわけで、実は印象の割には大した制限ではない。

    ・バンク・ページ選択
    バンクおよびページの選択方法はベースラインからミッドレンジで様変わりしており、注意が必要である。
    ROMページ:
    ミッド… PCLATHレジスタで指定。
    ベース… STATUSレジスタの上位3bitにPA2:0があり、これがミッドレンジのPCLATHと同様の働きをもつ。
    RAMバンク:
    ミッド… STATUSレジスタの上位3bitにIRP,RP1:0があり、それぞれ間接アドレッシングと直接アドレッシングのバンクを指定する。
    ベース… 間接アドレッシングはFSRのみでアドレスを指定できる。直接アドレッシングの場合、FSRの上位3bitと命令からの5bitでアドレスを指定する。

    というように、STATUSレジスタの上位3bitの扱いが変わっているので注意が必要である。
    またベースラインは間接アドレッシングと直接アドレッシングで別のページを指すことができないことに注意が必要である。

    コールスタック

    ミッドレンジのコールスタックは8段あり、複雑な事をしなければ足りなくなることはあまり無い。
    それに対しベースラインのコールスタックはわずか2段であり、よく考えて使わないとすぐに足りなくなる。

    どうしても3段のネストが必要になったら、自力で戻りアドレスを保存してCALL・RETURNを模擬する必要がある。
    単純な例を挙げればこんな感じ。
    mycall macro where
        movlw $+3
        movwf retAddr
        goto where
        endm
    ;---
    myreturn macro
        movf retAddr
        movwf PCL
        endm
    PC上位を保存しておく必要があったり再入可能にするならもっと面倒になるが、そこまで必要になったことが無いので考えていない。

    主要レジスタの機能比較

    周辺機能の制御用を除いた、コア機能のためのレジスタを比較する。

    ベースラインに無いレジスタは、説明済みのPCLATHと、割り込みが無いためINTCONが存在しないのみである。
    なお、上で述べたとおり、INTCONが無いということはTMR0のオーバーフローフラグも無いことに注意が必要である。

    機能の違うレジスタは3つ。
    STATUS, FSR, OPTION(_REG)
    FSRについては説明済み。
    STATUSとOPTIONを詳しく見る。
    なおビット名については、I/OポートがPORTBかGPIOかにより異なる場合がある(例: GPWUF/RBWUF)。ここではGPIOの方を示した。

    STATUS
    ミッド: IRPRP1RP0/TO/PDZDCC
    ベース①: PA2PA1PA0/TO/PDZDCC
    ベース②: GPWUFCWUFPA0/TO/PDZDCC
    下位5bitは共通。上位3bitが問題となる。
    ミッドレンジではおそらくすべての機種で間接・直接のバンク選択に割り当てられている。
    ベースラインでは、
    ①機能の無いもの(例: 16F5x)では3bitすべてページ選択(=PCLATH相当)に割り当てられている。
    もっとも、ベースラインのFlash量は最大でも2kワードなのでPA2が使われている機種は無さそうである。
    ②機能のあるものでは、上位2bitが2種のウェイクアップフラグ(GPIOピン変化・コンパレータ変化)に割り当てられている。
    このため両機能のあるものではFlashを2ページ(1024ワード)までしか積めないことになる。

    OPTION (レジスタ名はミッドレンジではOPTION_REG)
    ミッド: /GPPUINTEDGT0CST0CEPSAPS2PS1PS0
    ベース: /GPWU/GPPUT0CST0CEPSAPS2PS1PS0
    下位6bitは共通。上位2bitが、
    ミッドレンジではポートのプルアップと割り込みエッジ。
    ベースラインではピン変化ウェイクアップとポートのプルアップ。
    …なんでわざわざポートのプルアップのビットの位置を変えたんだろう。

    【余談】

    ・OPTION_REG
    ミッドレンジの「OPTION_REG」レジスタだが、古い機種のデータシートでは「OPTION」レジスタであった。
    おそらくOPTION命令との衝突を避けて名前を変えたのだろう。
    データシートのリビジョンで記述が変わっていることもあるようだ。
    PIC16F87/88 データシート
    上: Revision B (August 2003)
    下: Revision D (October 2011)
    OPTION_REGデータシート比較

    ・TRIS命令
    TRIS命令は命令表にはビットパターンが
    0000 0000 0fff
    と書かれているがこれは不適切で、PORTA~PORTEまである石では、
    0000 0000 0101
    0000 0000 0110
    0000 0000 0111
    0000 0000 1000
    0000 0000 1001
    がTRISに相当する。

    ・OPTION2
    OPTIONレジスタに加えてOPTION2レジスタをもつ石が存在し(例: PIC16HV504PIC16HV540)、これに書き込むにはTRIS命令を使う
        tris OPTION2
        tris 7
    どちらも表に見えていないレジスタに書き込むという実質的に同じ動作なのだろう。
    なお、てっきり「tris OPTION2」と書けるものだと勘違いしていたが、OPTION2はincファイルに定義が無く、マジックナンバー「7」で書き込まなければならない。「OPTION2」を「7」と定義しておいてくれれば楽なのにと思いもするが、勘違いで「movwf OPTION2」などと書かせないためだろうか。

    ・ミッドレンジで隠し命令
    TRIS命令とOPTION命令は命令一覧には載っていないもののミッドレンジでも使用可能である。
    バンクを切り替えなくともOPTION_REG・TRISレジスタに書き込めるのは便利である。
    ただしいくつか制限があり、
    ・PORTA,B,Cの3つ限定
    ・Enhancedミッドレンジでは指定する値はPORTA,B,Cとは関係なく5,6,7
    ・MPLAB8で試した所シミュレータでは不正な命令扱いになってしまった。



    編集履歴
    2015-08-29