シャープポケットコンピュータ PC-1262内部解析

# PC-1262 内部解析

## はじめに

本稿はシャープ ポケットコンピュータ PC-1262のアーキテクチャに関して書籍およびWEBから収集した情報を整理したものに、筆者の独自解析結果を一部加えたものである。
2019年現在において失われつつあるこれらの情報を再度集積し、保管することを目的として作成した。


### ROMバージョンについて

参考文献[1]によればPC-1260/PC-1261/PC-1262には3種類のROMバージョンがあり，アドレス\$F200の値によって判別することができる。

|\$F200の値|備考                  |
|---------|---------------------|
|\$C3      |                     |
|\$22      |                     |
|\$54      |最後期型？PC-1262が該当|

筆者の手元にある実機が(\$F200)==\$54のPC-1262のみであるため，他のバージョンについての検証を行っていない。ただしPC-1262がPC-1261よりも後に出た価格改定版という経緯から考え，PC-1262であればROMバージョン\$54であることがほぼ確実と思われる。

参考文献[2]によればHELP機能のNEXTの使用例がFOTとなっているバージョンが存在するようである。\$C3が該当バージョンではないかと想像するものの確認できていない。参考までに\$54のNEXTのオンラインHELPを示す。

```BASIC:NEXTのHELP
FOR N=1 TO 5
NEXT N
```

## メモリマップ

### アドレス空間

よく知られたことだがPC-1262のCPU ESR-H(SC61860)にはプログラムカウンタがアクセスできる通常のRAM・ROMのアドレス空間64KBと内部RAM 96バイトの二つのアドレス空間がある。周辺デバイスのうちLCDのVRAMのみが通常アドレス空間にマップされ，その他が内部RAMにマップされている。


### RAM・ROMメモリマップ

バージョン(\$F200)==\$54

|アドレス  |内容                                  |
|----------|-------------------------------------|
|0000～1FFF|内部ROM (8KB)                         |
|2000～20BF|VRAM (DISP1)                          |
|2800～28BF|VRAM (DISP2)                          |
|3000～20BF|VRAM (DISP1 image)                    |
|3800～38BF|VRAM (DISP2 image)                    |
|4000      |(RAM先頭)                             |
|4080～64FF|フリーエリア                          |
|6500～65CF|固定変数エリア                        |
|65D0～65FF|リザーブ・エリア                      |
|6650～667F|プリント・バッファ                    |
|66DB～66DD|CALL文用ジャンプポインタ              |
|66E1～66E2|BASICプログラム先頭アドレス・ポインタ |
|66E3～66E4|BASICプログラム終了アドレス・ポインタ |
|66F7      |ストリングバッファ・ポインタ          |
|66FC～66FD|変数ポインタ                          |
|6760～67AF|ストリングバッファ・エリア            |
|67FF      |(RAM末尾)                             |
|6800～7FFF|(未実装)                              |
|8000～8044|ジャンプテーブル(IOCS?)               |
|8045～8391|フォント                              |
|A43B～A6B1|中間コードテーブル？                  |
|～FFFF    |(ROM)                                 |

###  内部RAM

機種違いだが，参考文献[3]がわかりやすい。アドレス\$4～\$7の外部RAMポインタを参考文献[1]などでX，Yとしているが，システム・サブルーチンの使用する演算レジスタX，Yとの混同を避けるため本稿ではIX，IYと呼称する。

|アドレス|内容        |
|-------|------------|
|0      |I カウンタ   |
|1      |J カウンタ   |
|2      |A アキュムレータ               |
|3      |B アキュムレータ               |
|4～5   |IX 読み込み用 外部RAMポインタ   |
|6～7   |IY 書き込み用 外部RAMポインタ   |
|8      |K 汎用レジスタ   |
|9      |L 汎用レジスタ   |
|A      |M 汎用レジスタ   |
|B      |N 汎用レジスタ   |
|C～F   |汎用RAM   |
|10～17 |演算レジスタX|
|18～1F |演算レジスタY|
|20～27 |演算レジスタZ|
|28～2F |演算レジスタW|
|3A～3D |行番号サーチの結果|
|～5B   |スタック   |
|5C     |IA I/Oポートレジスタ   |
|5D     |IB I/Oポートレジスタ   |
|5E     |FO I/Oポートレジスタ   |
|5F     |OUTC コントロールポートレジスタ   |


## システム・サブルーチン

### システム・サブルーチン一覧

参考文献[1]より

|機能                  |(\$F200)<br>==\$C3|\$22|\$54 |
|---|:-:|:-:|:-:|
|印字ルーチンへ入る    |0975|0975|0975|
|印字ルーチンを抜ける  |097F|097F|097F|
|(印字)データセット    |9E3A|A09C|A282|
|(2変数)加算           |860F|87CA|88AE|
|(2変数)減算           |8626|87E1|88C5|
|(2変数)乗算           |8630|87EB|88CF|
|(2変数)除算           |863A|87F5|88D9|
|(2変数)べき乗算       |8643|87FE|88E2|
|(1変数)EXP            |8659|8814|88F8|
|(1変数)SIN            |8667|8822|8906|
|(1変数)COS            |866E|8829|890D|
|(1変数)TAN            |8675|8830|8914|
|(1変数)ASN            |867C|8837|891B|
|(1変数)ACS            |8683|883E|8922|
|(1変数)ATN            |868A|8845|8929|
|(1変数)DEG            |8698|8853|8937|
|(1変数)DMS            |869F|885A|893E|
|(1変数)ABS            |8C52|8E26|8F0D|
|(1変数)INT            |8C2E|8E02|8EE9|
|(1変数)SGN            |86AD|8868|894C|
|(1変数)RND            |86A6|8861|8945|
|(1変数)SQR            |8660|881B|88FF|
|(1変数)LOG            |8652|880D|88F1|
|(1変数)LN             |864A|8805|88E9|
|ASC                   |87B0|8984|8A68|
|CHR\$                  |87CF|89A3|8A87|
|STR\$                  |882C|8A00|8AE4|
|VAL                   |888A|8A5E|8B42|
|(比較・数値)＜＞      |87A1|8975|8A59|
|(比較・数値)＜        |872E|88EE|89D2|
|(比較・数値)＞        |8749|891D|8A01|
|(比較・数値)＝        |878D|8961|8A45|
|(比較・数値)≦        |86CC|8887|896B|
|(比較・数値)≧        |86D9|8894|8978|
|(比較・文字)＜＞      |879C|8970|8A54|
|(比較・文字)＜        |86E1|889C|8980|
|(比較・文字)＞        |86E3|889E|8982|
|(比較・文字)＝        |8751|8925|8A09|
|(比較・文字)≦        |8770|897E|8A62|
|(比較・文字)≧        |86C7|8882|8966|
|表示ON                |043B|043B|043B|
|表示OFF               |0437|0437|0437|
|全画面表示            |CB0B|CE2E|D0F3|
|プリントバッファクリア|1B2F|1B2F|1B2F|
|キースキャン          |03C1|03C1|03C1|
|10進→2進変換 負号あり|13D2|13D2|13D2|
|10進→2進変換 負号なし|13DD|13DD|13DD|
|2進→10進変換 負号あり|10E7|10E7|10E7|
|2進→10進変換 負号なし|10E0|10E0|10E0|
|行番号 サーチ 2進表現 |B411|B6DB|B8ED|
|変数のアドレスサーチ<br>単純変数|1865|1865|1865|
|変数のアドレスサーチ<br>配列変数|157A|157A|157A|

参考文献[1]にないもの

|仮称|機能                  |(\$F200)==\$54 |
|---|---|:-:|
|\_MOVE\_IY\_BA|レジスタBAをIYにコピー|0222|
|\_MOVE\_IX\_BA|レジスタBAをIXにコピー|0225|
|\_LOAD\_IX\_FONT|フォントアドレスをIXにセット|135F|
|\_PRINT|全画面表示|800F|

全般的にJ=1を前提とした処理があるので注意。

### システム・サブルーチン詳細

#### \_PRINT

##### アドレス
\$800F
##### 機能
全画面表示
##### 入力
\$6650～\$667F (プリント・バッファ)
##### 出力
\$2000～\$203B,\$2040～\$207B,\$2800～\$283B,\$2840～\$287B (VRAM)
##### 破壊
少なくともA,B,P,Q,I,IX,IY,K,L,DP
##### 前提
J=1,M=?
##### 解説
プリント・バッファに書き込まれた文字列を画面表示する。参考文献[1]に記載の\$D0F3ではうまくいかない。(以下のサンプルコードの20行目を`CALL &D0F3`とすることで確認できる)

\$D225からのルーチンで内部RAM \$0A(レジスタM)と表示文字が一致した場合に何らかの処理を行っているが，内容を追い切れていない。M=0としておくのが無難と思われる。

##### サンプルコード
```plaintext:_PRINT.BAS
10:FOR I=0 to 47: POKE (&D6650+I),(&41+I): NEXT I
20:CALL &800F: CALL &043B
30:FOR I=0 TO 500: NEXT I
```

##### 備考
解析の便のため，調査した呼び出し順序を以下に示す。

\$800F → \$D1D4 (BA=\$2000,\$2080,\$2040,\$2840を順次セット) → \$D205 (VRAMへの書き込み，DXL/IYSを5回繰り返す) → \$D225 → \$135F ( \_LOAD\_IX\_FONT )


#### \_LOAD\_IX\_FONT

##### アドレス
\$135F
##### 機能
フォントアドレスをIXにセット
##### 入力
A
##### 出力
IX
##### 破壊
P,Q,I
##### 前提
J=1
##### 解説
アキュムレータAの内容を文字コードとしてフォントアドレスを計算し，IXに格納する。文字コード\$20～に対応するフォントが\$8045～にある。


#### \_MOVE\_IY\_BA

##### アドレス
\$0222
##### 機能
アキュムレータBAをIYにコピー
##### 入力
BA
##### 出力
IY
##### 破壊
P,Q,I
##### 前提
J=1

##### 実装
```plaintext
LP	$06
LIQ	$02
MVB
```
##### 解説
アキュムレータBAの値を書き込み用外部RAMポインタIYに代入するマクロ。J=1でなければ正常動作しないはずなので注意。本ルーチンを引数固定で呼び出すルーチンがいくつかあるので，下表に示す。

|アドレス|機能|
|---|---|
|\$0242|IY=BA-1|
|\$023E|BA=\$67B0，IY=\$67B0-1|
|\$0246|BA=\$2080，IY=\$2080-1|


#### \_MOVE\_IX\_BA

##### アドレス
\$0225
##### 機能
アキュムレータBAをIXにコピー
##### 入力
BA
##### 出力
IX
##### 破壊
P,Q,I
##### 前提
J=1

##### 実装
```plaintext
LP	$04
LIQ	$02
MVB
```
##### 解説
アキュムレータBAの値を読み込み用外部RAMポインタIXに代入するマクロ。J=1でなければ正常動作しないはずなので注意。本ルーチンを引数固定で呼び出すルーチンがいくつかあるので，下表に示す。

|アドレス|機能|
|---|---|
|\$022E|IY=BA-1|
|\$022A|BA=\$67B0，IY=\$67B0-1|
|\$0232|BA=\$6650，IY=\$6650-1|
|\$0238|BA=\$2080，IY=\$2080-1|


## 各種テーブル

### ジャンプテーブル

IOCSと呼ぶ人もいるようだが？

|アドレス|飛び先|機能|
|:-:|:-:|:-:|
|8000    |8930  | |
|8003    |8D2F  | |
|8006    |AC85  | |
|8009    |879D  | |
|800C    |D690  | |
|800F    |D1D4  |全画面表示|
|8012    |A92C  | |
|8015    |AADC  | |
|8018    |D702  | |
|801B    |9062  | |
|801E    |8FBD  | |
|8021    |A305  | |
|8024    |04B4  | |
|8027    |04B6  | |
|802A    |0516  | |
|802D    |0518  | |
|8030    |054E  | |
|8033    |0550  | |
|8036    |9AF2  | |
|8039    |8BFF  | |
|803C    |8C83  | |
|803F    |8C32  | |
|8042    |CF55  | |


### 中間コードテーブル

マーク(下位ニブルが文字数),予約語,中間コード,アドレス となっている

|予約語  |中間コード|アドレス|マーク|
|---|:-:|:-:|:-:|
|AREAD   |E1|C41F|B5|
|AND     |A1|8781|A3|
|ABS     |99|8781|A3|
|ATN     |9F|8781|A3|
|ASN     |9D|8781|A3|
|ACS     |9E|8781|A3|
|ASC     |A4|8781|A3|
|BEEP    |C4|C147|B4|
|CONT    |B2|C4C4|F4|
|CLEAR   |C9|C17B|C5|
|CLOAD   |B7|9695|E5|
|CSAVE   |B6|9513|C5|
|COS     |96|8781|E3|
|CHR\$    |A8|8781|A4|
|CALL    |CC|C191|A4|
|CLS     |CE|C0FA|E3|
|CHAIN   |E5|963C|A5|
|CURSOR  |CF|C10C|A6|
|DIM     |CB|BD7B|B3|
|DEGREE  |C1|C3A8|E6|
|DEG     |9B|8937|E3|
|DMS     |9C|893E|A3|
|DATA    |DC|C41F|A4|
|END     |D8|C324|B3|
|EXP     |93|8781|A3|
|EQU#    |B9|C624|84|
|FOR     |D5|BE0F|D3|
|GOTO    |C6|BFC4|B4|
|GOSUB   |E0|BFFA|E5|
|GRAD    |C3|C3B8|A4|
|INPUT   |DF|C4E5|F5|
|IF      |D4|C29D|E2|
|INT     |98|8781|A3|
|INKEY\$  |AD|8781|A6|
|LIST    |B4|C596|D4|
|LLIST   |B5|C7D6|C5|
|LPRINT  |E2|C786|C6|
|LOG     |92|8781|A3|
|LN      |91|8781|A2|
|LET     |D6|C066|A3|
|LEN     |A6|8781|A3|
|LEFT\$   |AB|8781|85|
|MEM     |AF|8781|D3|
|MEM#    |BA|8781|C4|
|MID\$    |AA|8781|C4|
|MERGE   |B8|96BD|C5|
|NEXT    |D9|BEB2|D4|
|NOT     |A3|8781|A3|
|NEW     |B1|BC72|A3|
|ON      |D3|C3C0|F2|
|OR      |A2|8781|A2|
|PRINT   |DE|C6E1|B5|
|PASS    |B3|C437|E4|
|PI      |AE|8781|C2|
|PEEK    |A7|8781|C4|
|POKE    |CD|C1AE|A4|
|PAUSE   |DD|C348|E5|
|RUN     |B0|BD07|B3|
|RETURN  |E3|C2D6|C6|
|READ    |DB|C1EF|A4|
|RESTORE |E4|C26D|A7|
|RND     |A0|8781|A3|
|RANDOM  |C0|C0F7|A6|
|RIGHT\$  |AC|8781|E6|
|RADIAN  |C2|C3B0|C6|
|REM     |D7|C2CF|E3|
|STOP    |DA|C33C|B4|
|SQR     |94|8781|A3|
|SIN     |95|8781|A3|
|SGN     |9A|8781|A3|
|STR\$    |A9|8781|A4|
|STEP    |D1|0FC1|A4|
|THEN    |D2|0FC1|F4|
|TAN     |97|8781|E3|
|TRON    |C7|C340|A4|
|TROFF   |C8|C344|E5|
|TO      |D0|0FC1|E2|
|USING   |CA|C5F8|F5|
|VAL     |A5|8781|F3|
|WAIT    |C5|C384|94|

### フォントROM

\$8045～
抜けは詰められている


## その他

### CALL文用ジャンプポインタ

\$66DBに\$79(JP命令)，\$66DC～\$66DDにCALL文の引数(飛び先)が入る。
CALL文の内部でCALL \$66DBとして間接コールを実現している。
リロケータブルプログラムの間接ジャンプに活用可能。


## 参考文献

1. [シャープポケットコンピュータ機械語マニュアル，シャープ株式会社 工学社企画・編集，工学社，1986](http://iss.ndl.go.jp/books?any=%E3%82%B7%E3%83%A3%E3%83%BC%E3%83%97%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E6%A9%9F%E6%A2%B0%E8%AA%9E%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB&display=&op_id=1)
1. PC-1261の小技：マイブーム，Jimmy， http://cyndi.cocolog-nifty.com/blog/2007/07/pc1261_4ea9.html ，2019/01 閲覧
1. ポケコン SHARP PC-1401 SC61860 機械語資料，VisualBasist， http://gojigen.myhome.cx/SC61860.html ，2019/01 閲覧
1. [ポケコンマシン語入門，I/O編集部 編著，工学社，1984](http://iss.ndl.go.jp/books?any=%E3%83%9D%E3%82%B1%E3%82%B3%E3%83%B3%E3%83%9E%E3%82%B7%E3%83%B3%E8%AA%9E%E5%85%A5%E9%96%80&op_id=1)