PC-G850(ポケコン)をレビュー！プログラミング機能も紹介！

## はじめに
こんにちは、ついにポケコンデビューしてしまったbockringです。

　**ポケコン、ゲットだぜ！**

ということで勢いに任せてポケコンを買ってしまいました。(なんてこった…) いつものレビュースタイルだと「エンジニアなお話か？」って運営に怒られそうなので、全体のレビューをした後でプログラミング機能に重点を置いてレビューしていきます。

## PC-G850とは
SHARPから発売されていた、学校教育用のポケットコンピューターです。PC-E200シリーズの学校向け版(派生型)であるPC-G800シリーズの中の1番目の機種になります。同じ`850`ナンバーではPC-G850、PC-G850S、PC-G850V、PC-G850VSの4機種があります。

また、後期のE200シリーズの特徴として100文字以上表示できるフルドットマトリクス液晶、C言語によるプログラミングなどが挙げられます。

また、他のポケコン同様、Basicでのプログラミングにも対応します。

この機種で扱える言語は**Basic/C/Assembly**ですが、今回はBasicとCをメインに扱っていきます。(←アセンブリが使えないだけ、というかリファレンスを探すのが面倒)

## 購入
今回、ポケコンの購入にあたって以下の機種で比較を行いました。
- SHARP PC-G850
- CASIO スーパーカレッジVX-4

そしてさまざまなサイトで比較した結果以下の情報が手に入りました。
|  | SHARP<br>PC-G850 | CASIO<br>ｽｰﾊﾟｰｶﾚｯｼﾞVX-4 |
|-:|:-|:-|
| **CPU** | Z80相当CMOS<br>(8MHz?) | HD91700A<br>(910KHz) |
| **RAM** | 32KB | 8KB |
| **画面画素数** | 144×48 | 192×32 |
| **表示文字数** | 24×6 (144) | 32×4 (128) |
| **言語** | Basic<br>C<br>CASLアセンブラ<br>Z80アセンブラ | Basic<br>C<br>CASLアセンブラ<br>　 |
| **電源** | 単4×4<br>EA-23E(8.5V)アダプター | 単3×4 + CR1220<br>　 |
| **消費電力** | 0.4Wh | 0.08Wh |
| **使用可能時間** | 70h | 200h |

まぁ、性能で前者に決めました。

後者は性能を落として電池持ちを良くする魂胆なのかもしれませんが、それでも前者の性能の良さが目立ちます。

また、ネット上の画像を比較しても前者の方がキーの配置が使いやすそうです。前者は割と純粋なQWERTYキーボードの配置ですが、後者はまだ電卓キーボードのようなものを感じます。どう足掻いても**電卓キーボードは使いにくい**ので、前者に分があります。

そしてプログラミング言語。どちらもほとんど同じですが、後者のC言語機能は貧弱というか、少し古いようです。とはいえ前者も行番号が必要な特殊なC言語ですが…

またエディターに関しては後者の方が優秀という情報が多いです。また実際にそうだと思いますが、前者は行数が多いので… ここは引き分けですかね。

## レビュー
まず、Amazonで中古を購入しました。

最初に7000円弱の出品を買いましたが、あまりに届かないのでカスタマーサポートに連絡したら、注文キャンセルと再購入をしろと言われました。しかし、再購入すると8200円くらいで1200円くらいの差額があります。この件も伝えると差額も補填してくれるということでしたので、即決です。

まぁ、7000円で少し値段が高い(ことから状態が良いと予想できる)8200円のものを購入できてしまいました。

商品は、ブザーの裏蓋がありませんでしたが、説明にはありませんでしたが、それが正常です。なぜなら**その裏蓋は、記名シールであり、剥がさないとプライバシー上の問題があります**。適当なシールでも貼って隠しておけばOKです。

しかし、おそらく少なくとも1回は分解されているでしょう(公式オプションで発送時からあるのかもしれないが)。PC-G850は学校用のもので、ブザーは標準装備ではなかったはずです。

とはいえブザーがあるのは面白いですね。遊ぶ幅が増えます。

キーボードは**めちゃくちゃ小さい**ですが、意外と苦にはなりません。繊細に押す必要があるものの素直なQWERTY配列ですから、いつもの感覚で打てます。

あと、Shiftと併せて操作するキーに関しては、同時押しでした。つまり、Shiftキーと他のキーの組み合わせについては全て同時に反応する様です。

キーはどちらかというとプチプチとした触感で、好みが分かれそうです。個人的には好きですね。フニャフニャのキーは嫌いです。クセがあるキーの方が好きなんですよね。

## プログラミング機能
### Basic
ポケコンの特徴といえば**Basicが動く**ことですが、ポケコンBasicはまともなことが多いです。

https://qiita.com/bockring/items/0b0cb24771019c6ec232

どこかのグラフ電卓と違ってちゃんとBasicなので、文を読めば何をやりたいかが分かる言語です。**これこそがBasicの姿だと思う**のですが…

#### 合成抵抗の算出
まずは、並列の合成抵抗を算出するプログラムを作ります。このプログラム、簡単なのに変数の入出力や任意値の入力もできて、意外と便利です。

```BASIC:ParaRes
10:INPUT "R1=",A
20:INPUT "R2=",B
30:IF A<0 OR B<0 THEN PRINT "INPUT ERROR":GOTO 60
40:IF A=0 AND B=0 THEN PRINT "INPUT ERROR":GOTO 60
50:PRINT "R=", A*B/(A+B)
60:END
```

もちろん、このままでも動作はします。というか理想の動作をするので基本的に問題はありません。

[こちらの環境](https://synapse.kyoto/tool/SynBasic/page001.html)で動かした結果です。

![IMG_0284.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/c6357708-ca1d-4045-b4eb-c3e5f320225c.jpeg)

とはいえ、これをポケコンで動かすには容量を食い過ぎですね。ということでこちらの記事を参考にしつつ容量を減らしていきます。

https://qiita.com/plageoj/items/242015118f65ea177859

```BASIC:ParaRes(Light?)
10:INPUT "R1=?",A:INPUT "R2=?",B
20:IF A<0 OR B<0 THEN PRINT "INPUT ERROR!":END
30:IF A=0 AND B=0 THEN PRINT "INPUT ERROR!":END
40:PRINT "R=", A*B/(A+B)
```

これは元のコードの`10`行目と`20`行目をまとめた、あと最終行の`END`を使わないようにしただけで、2行分しか減っていません。

また簡単な処理に`IF`を2回も使っているのは不恰好ですよね。この`IF`でどんな篩にかけたいか、という話ですが、以下の様になります。
- A,Bの2数がともに0より大きい  **OK**
- A,Bのどちらか一方が0より大きく、もう一方が0  **OK**
- A,Bの2数がともに0  **NG**
- A,Bの2数がともに0より小さい  **NG**

ですから2番目の条件を上手に変更しすると字数を削れそうです。ここで制約を与えつつ条件式を変更します。

元のコードでは、`R1`と`R2`のどちらにも0を代入することが許されていました。しかし、実際にはその後の条件分岐で`R1=R2=0`の入力は弾くようにされています。

それなら入力プロンプトの時点で`R1(Zero OK)=`や`R2(Zero NG)=`というように`0`の代入が許されているかを明記し、`IF`の条件式を変更することで行数を減らせます。

```BASIC:ParaRes(Light)
10:INPUT "R1(Zero OK)=",A:INPUT "R2(Zero NG)=",B
20:IF A>=0 AND B>0 THEN PRINT "R=",A*B/(A+B):END
30:PRINT "INPUT ERROR!"
```

---

<details><summary>通常のBASIC環境で走らせたい方はこちら</summary>

```BASIC:ParaRes(Light/Normal)
10 INPUT "R1(Zero OK)=",A:INPUT "R2(Zero NG)=",B
20 IF A>=0 AND B>0 THEN PRINT "R=",A*B/(A+B):END
30 PRINT "INPUT ERROR!"
```

実行結果です。
![IMG_0288.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/b0fa4f49-67ad-4080-87c2-ef05d39a3329.jpeg)

</details>

---

この軽量版では`IF`の条件式を真逆にしました。これは
- 値が条件を満たさないならば、実行しない
- 値が条件を満たすならば、実行する

という2つの意味が同じであることを利用しています。`IF`文内で`END`を使っていますが、これを使った方が行数を減らせます。

#### 数当てゲーム
もはやこれも定番です。それなりにUIを意識して作成します。
```BASIC:RandNum.TXT
10 CLS :PRINT "[ｶｽﾞｱﾃｹﾞｰﾑ]"
20 PRINT "ﾌﾟﾚｲｦｶｲｼｼﾀｲﾊﾞｱｲﾊ1ｦ､ﾙｰﾙｦﾐﾀｲﾊﾞｱｲﾊ2ｦ､ﾆｭｳﾘｮｸｼﾃｸﾀﾞｻｲ｡":INPUT "(1 or 2)",Z
30 IF Z=1 THEN GOTO 50
40 IF Z=2 THEN PRINT "~ﾙｰﾙ~":PRINT "ｱﾅﾀﾊ､1ｶﾗ10ﾏﾃﾞﾉｽｳｼﾞｦﾖｿｳｼ､ﾆｭｳﾘｮｸｼﾏｽ｡":PRINT "":GOTO 20 ELSE GOTO 20
50 CLS :A= RND 10:PRINT "1ｶﾗ10ﾏﾃﾞﾉｽｳｼﾞｲｦ､ﾆｭｳﾘｮｸｼﾃｸﾀﾞｻｲ｡":INPUT "(1~10)",B:PRINT "ﾗﾝｽｳ:",A,"ｱﾅﾀﾉﾖｿｳ:",B
60 IF A=B THEN PRINT "ｾｲｶｲ!":BEEP 2,10 ELSE PRINT "ｻﾞﾝﾈﾝ...":BEEP 1,63
70 PRINT "":PRINT "ﾂﾂﾞｹﾏｽｶ?(ﾊｲ:1 ｲｲｴ:0)":INPUT "(1 or 0)",Z
80 IF Z=1 THEN GOTO 50 ELSE GOTO 90
90 CLS :PRINT "ｱｿﾝﾃﾞｸﾚﾃｱﾘｶﾞﾄｳ!":PRINT "  Thank you for playing!"
```

思ったよりも正解できなくて驚きましたが、正解の時の動作も大丈夫そうです。

---

<details><summary>通常版BASIC</summary>

```BASIC:
10 CLS :PRINT "[数当てゲーム]"
20 PRINT "プレイを開始したい場合は1を、ルールを見たい場合は2を、入力してください。":INPUT "(1 or 2)",Z
30 IF Z=1 THEN GOTO 50
40 IF Z=2 THEN CLS:PRINT "〜ルール〜":PRINT "あなたは、1から10までの数字を予想し、入力します。":PRINT "":GOTO 20 ELSE GOTO 20
50 CLS :A=INT(RND * 10)+1:PRINT "1から10までの数字を入力してください。":INPUT "(1~10)",B:PRINT "乱数:",A,"あなたの予想:",B
60 IF A=B THEN PRINT "正解!" ELSE PRINT "残念..."
70 PRINT "":PRINT "続けますか?(はい:1 いいえ:0)":INPUT "(1 or 0)",Z
80 IF Z=1 THEN GOTO 50 ELSE GOTO 90
90 CLS :PRINT "遊んでくれてありがとう!":PRINT "  Thank you for playing!"
```
せっかく現代には全角日本語を認識できるBASICが存在しますので、完全な日本語に焼き直しました。こちらの方が遊びやすいと思います。

あとポケコンでは`RND`命令が特殊だったり、`BEEP`が存在したりするので、そこだけは直しています。

9行でそれなりには遊べるのですから、BASICはすごいですよね…
</details>

---

### C言語
ここでは、C言語を試していきます。まぁ、**C言語を6行の画面で実行するのは絶望的**な訳ですが。Arduinoと16文字2行の液晶で簡易OSを作って遊んでいたくらいで、小さな画面には多少慣れています。

#### C言語の実行方法
まず、`TEXT`キーを押してテキストエディタを開きます。次に`E`キーを押し、`Edit`モードにします。ここで行番号を含めてコードを書きます。


その後、`2nd F`キーを押して`TEXT`キーを押します。そうするとセカンドファンクションのC言語モードが開くので、`C`キーを押してコンパイル、問題がなければメニューに戻り`G`キーで実行(Go)します。

ファイルの保存は`.TXT`で保存されます。こちらはテキストエディタのメニューからFile、Saveの順に押して保存です。

#### 手始めに`Hello, world!`
まさかここで驚かされるとは。びっくりです。(小泉構文もどき？)

通常、C言語での`Hello, world!`は以下のコードで行います。
```c:hello_world.c
#include <stdio.h>

int main () {
  printf("Hello, world!");
  return 0;
}
```

普通、こうじゃないですか。しかしこのポケコンだと以下の様になります。
```c:Hello_W.TXT
10 int main (void) {
20   printf("Hello, world");
30   return 0;
40 }
```

意味不明ですね。ちなみに最初に`#include <stdio.h>`を入れると、コンパイラが`10:ilegal include`とエラーを突き出してくるので、「なんでやねん」というツッコミは程々にして削除します。

#### 合成抵抗の算出
とりあえず、BASICの時と同じ様に合成抵抗を求めていきます。

通常のC言語では以下の様になるはずです。

```c:ParaResC.c
#include <stdio.h>

int main (void) {
  float R1, R2;
  
  printf("R1(Zero OK)=");
  scanf("%f", &R1);
  printf("%lf\n", R1);
  printf("R2(Zero NG)=");
  scanf("%f", &R2);
  printf("%lf\n", R2);

  printf("R = %lf\n", R1 * R2 / (R1 + R2));

  return 0;
}
```

このコードを適当な開発環境に入力して実行したら入力を求められ、2値を入力すれば合成抵抗値が出力されます。

https://www.mycompiler.io/view/6riSnjk0Zej

![IMG_0337.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/7cb146a3-ebfb-4673-854d-d2fd5a53db1a.jpeg)

なんか見た目が終わっていますが、動けばOKです。

これをポケコン用に焼き直します。
```c:ParaResC.TXT
int main (void) {
  float A, B;
  printf("Input R1(Zero OK)");
  scanf("%f", &A);
  printf("Input R2(Zero NG)");
  scanf("%f", &B);
  printf("R=%lf", A * B / (A + B));
  return 0;
}
```

ポケコンの改行規則や、特別な事情に合わせて書き直しました。このコードの冒頭に`#include <stdio.h>`を追加して実行すると、以下の様になります。
![IMG_0338.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/56ff8852-e2ce-4d9f-b08f-0ce4f709c4d7.jpeg)

見た目は異なりますが、同じ値が出ていますのでOKです。

それではこれをポケコンに入れていきます。

まぁ、流石に動作しました。が、少し問題が露呈しましたので「比較」章をご覧ください。

**ちなみに、コンパイラは結構速いので快適です。Arduino IDEよりかは遥かに速いです。** しかしエラー詳細が表示されないので…そこは困りますね()

### 比較
プログラム機能を使っていて分かったのが、**演算の精度が異なる**ことです。試しに次の2つの画像を比べてください。1つ目がBASIC、2つ目がC言語です。

![IMG_0355.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/d59bbfb1-1bf4-4027-9e59-b8bceb38f629.png)
↑BASIC

![IMG_0354.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/3d304b6b-1c0b-4197-81f5-57a8baece577.png)
↑C言語

見比べると、BASICでは`R=49.99750012`、そしてC言語では`R=50.000000`と表示されています。

どちらもユーザー引数にはどちらにも`R1=50`, `R2=1E6`(`R2=1000000`)を代入しています(オシロスコープの1MΩの入力に対して並列に50Ωの抵抗(ターミナル)を接続した場合の抵抗値)。[Web上で高精度に計算できるke!san](https://keisan.casio.jp/calculator)にて30桁設定で計算したところ、`49.9975001249937503124843757812`でしたから、四捨五入を考慮すると、BASICで`R=49.99750012`、C言語で`R=49.997500`です。

この結果より、前者は正確に出ています。後者は`0.002500`の差が出ています。これは今回の様な雑プログラミングならそこまで問題にはなりませんが、この値を繰り返し、特に計算したものを段階を重ねて扱う場合は最終的な誤差の影響が大きくなります。

また、ソフトの中での閉じた世界では問題がない場合もありますが、このプログラムの目的は**並列接続の抵抗の合成抵抗値Rを求める**ことですから、回路によってはこの誤差が後で大問題につながることもあります。

何か計算をしたい場合やその計算にある程度の精度が求められる場合はBASICで実行するのが良いかと思います。

## おわりに
まず、この記事で何回も参考にした記事を@plageoj様にこの場をお借りして感謝を申し上げます。本当にありがとうございます。もの凄く参考になりました。なにせ取説が付属していないもんで、何度も読みました。

ということで、ポケコンデビューをしてしまい、色々遊んできましたが、結構楽しかったです。昨今の大画面化で画面の小ささを少々辛く感じますが、これでもポケコン界では大画面な様です。

とはいえ、大昔のPCは、Basicが動くCUI環境だったわけで、多少であるものの「これが昔のに近しきものなのか…」感はありました。

しばらくはこいつで遊んでいこうと思います。

そしてそのうちCASIOのFX-890P/Z-1/Z-1GRを買っている未来が見えます。

それではまた〜