# WSL(Windows Subsystem for Linux)で CP/M 8266 をビルドする --- tags: ESP8266 ESP-WROOM-02 CP/M TurboPascal created_at: 2018-11-03 updated_at: 2020-06-19 --- # はじめに [CP/M 8266](https://github.com/SmallRoomLabs/cpm8266) という、ESP8266 コアの ESP モジュールで動作する **Z80 CP/M 2.2 エミュレータ** があり、それを WSL でビルドしてみようという趣旨の記事です。 - [CP/M (Wikipedia)](https://ja.wikipedia.org/wiki/CP/M) - [CP/M (en: Wikipedia)](https://en.wikipedia.org/wiki/CP/M) - [CP/M コマンド概要メモ (neko Java Home Page)](http://star.gmobb.jp/koji/cgi/wiki.cgi?page=CP%A1%BFM%A5%B3%A5%DE%A5%F3%A5%C9%B3%B5%CD%D7%A5%E1%A5%E2&fbclid=IwAR3ejRrBkvIu048heuRCI00UVY5G8Fg2-YRM1Rg1r_Ct2SVI0zhVU-a4LSk) # インストール、コンパイルそして実行 基本的には [CP/M 8266 の README](https://github.com/SmallRoomLabs/cpm8266/blob/master/README.md) をなぞるだけです。 ## 必要なもの ESP-WROOM-02 (EP8266) モジュールの載ったボードが必要です。 ボードには [スイッチサイエンスの ESPr Developer](https://www.switch-science.com/catalog/2500/) を推奨します。技適の通った ESP-WROOM-02 モジュールが使われており、自動プログラム機能もあるため楽ちんです。 CP/M 8266 を試す上で他に必要な部品はありません。 ![image.png](./images/8c685adf-1bb1-2155-0a93-2ce69876bb7c.png) ビルド環境として Window 10 の **WSL(Windows Subsystem for Linux)** を利用します。Linux は **Ubuntu の 16.04** を使います。 ![image.png](./images/54b4972e-7d4a-ac53-34ef-04adcebaf046.png) **See also:** - [ESP-WROOM-02 (ht-deko.com)](https://ht-deko.com/arduino/esp-wroom-02.html) - [Windows 10でLinuxプログラムを利用可能にするWSLをインストールする(バージョン1803以降対応版)(@IT)](http://www.atmarkit.co.jp/ait/articles/1608/08/news039.html) ## 1.git のインストール すでにインストールしてあればスキップしてください。インストールしていなければ 2. と合わせて一行で実行するといいでしょう。 ```text: $ sudo apt-get install git ``` ## 2.esp-open-sdk と cpm8266 のビルドに必要なものをインストール Qiita のコード表示の都合上、複数行にしてありますが、一行にまとめて実行しても構いません。 ```text: $ sudo apt-get install make unrar-free autoconf automake libtool gcc g++ $ sudo apt-get install gperf flex bison texinfo gawk ncurses-dev $ sudo apt-get install libexpat-dev python-dev python python-serial $ sudo apt-get install sed git unzip bash help2man wget bzip2 libtool-bin $ sudo apt-get install z80asm cpmtools zip vim-common ``` ## 3.esp-open-sdk のビルド このビルドには相当時間が掛かります。下手すれば 2 時間以上なので、のんびりやりましょう。 ```text: $ git clone --recursive https://github.com/pfalcon/esp-open-sdk.git $ cd esp-open-sdk $ make $ export PATH=~/esp-open-sdk/xtensa-lx106-elf/bin:$PATH $ cd .. ``` ## 4.COM ポートの確認 ESP-WROOM-2 (ESP8266) ボードを PC に接続し、ポートを調べます。デバイスマネージャからでも Arduino IDE からでも構いません。 ![image.png](./images/c8f4a895-878a-711f-eadd-cfb96ff51bb9.png) ## 4.CP/M 8266 のビルド前設定 CP/M 8266 のクローンを行います。 ```text: $ git clone https://github.com/SmallRoomLabs/cpm8266.git $ cd cpm8266/code $ export ESP8266SDK=~/esp-open-sdk $ export ESPTOOL=~/esp-open-sdk/esptool/esptool.py $ export ESPPORT=/dev/ttySnnn $ sudo chmod 666 /dev/ttySnnn ``` PC のシリアルポートは WSL で /dev/ttySnnn として透過的に見えます。例えば COM4 は /dev/ttyS4 のような具合です。なので `export ESPPORT` の行は適宜読み替えてください。また、そのままでは /dev/ttySnnn をアクセスする権限がないので `chmod` しておきます。 ## 5.オプションの設定 必要なら Makefile を開いてオプションを設定します。 ```text: : $ nano Makefile ``` エディタは vi でも emacs でもお好きなものをどうぞ (w ```text: FLASHPARAM = --flash_freq 80m --flash_mode dout FLASHBAUD = 921600 EMULATIONBAUD = 115200 PORT = 23 ``` `EMULATIONBAUD` を 115200 にするくらいですかね。ESP-WROOM-02 ボードの種類によっては `FLASHBAUD` を115200 とかに落とす必要があるかもしれません ## 6.CP/M 8266 のビルド CP/M 8266 をビルドします (すぐ終わります)。 ```text: $ make full ``` しかしながら... ### ■ ets_isr_attach でエラーが出る場合 ```text: [CC] main.c In file included from main.c:3:0: espincludes.h:39:6: error: conflicting types for 'ets_isr_attach' void ets_isr_attach(int intr, void *handler, void *arg); ^ In file included from /home/xxxxx/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/sysroot/usr/include/os_type.h:28:0, from main.c:2: /home/owner/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/sysroot/usr/include/ets_sys.h:67:6: note: previous declaration of 'ets_isr_attach' was here void ets_isr_attach(int i, ets_isr_t func, void *arg); ^ Makefile:109: ターゲット 'main.o' のレシピで失敗しました make: *** [main.o] エラー 1 ``` このようなエラーが出たら以下の手順でソースにパッチを当てる必要があります。 ```text: $ wget https://github.com/SmallRoomLabs/cpm8266/files/2088791/cpm8266-master-2-local.diff.gz $ gzip -d cpm8266-master-2-local.diff.gz $ patch -p2 < cpm8266-master-2-local.diff ``` ### ■ esptool.py で print エラーが出る場合 esptool.py で次のようなエラーが出る事があります。 ``` [LINK] text data bss dec hex filename 12900 10 70416 83326 1457e image.elf File "/home/xxxxx/esp-open-sdk/esptool/esptool.py", line 128 print 'Connecting...' ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print('Connecting...')? Makefile:101: recipe for target 'bins' failed make: *** [bins] Error 1 ``` `/home/xxxxx/esp-open-sdk/esptool` にある esptool.py をテキストエディタで開き、 ```python:esptool.py #!/usr/bin/env python # NB: Before sending a PR to change the above line to '#!/usr/bin/env python2', please read https://github.com/themadinventor/esptool/issues/21 ``` 先頭行の `python` を、 ```python:esptool.py #!/usr/bin/env python2 # NB: Before sending a PR to change the above line to '#!/usr/bin/env python2', please read https://github.com/themadinventor/esptool/issues/21 ``` python**2** に書き換えてください...2 行目に対処方法が書いてあるんですけどね。 **See also:** - [#!/usr/bin/env python vs python2 - aka PEP 394 The "python" Command on Unix-Like Systems #21 (espressif/esptool)](https://github.com/espressif/esptool/issues/21) ### ■termios.error エラーが出る場合 さらに、コンパイルは通っても以下のエラーで書き込めない事があります。 ```text: termios.error: (5, 'Input/output error') Makefile:173: ターゲット 'flash' のレシピで失敗しました make: *** [flash] エラー 1 ``` これは COM ポートにアクセスできない場合に発生します。COM ポートを別のアプリで開いていないか確認してください。Windows 再起動直後なら間違いなく大丈夫ですので、COM ポートを開いていないつもりなのにこのエラーが出る場合には PC を再起動した後、 ```text: $ cd cpm8266/code $ export PATH=~/esp-open-sdk/xtensa-lx106-elf/bin:$PATH $ export ESP8266SDK=~/esp-open-sdk $ export ESPTOOL=~/esp-open-sdk/esptool/esptool.py $ export ESPPORT=/dev/ttySnnn $ sudo chmod 666 /dev/ttySnnn $ make full ``` 上記手順をやり直してください。 ### ■ 正しくビルドできている場合 ![image.png](./images/82cb79cd-c333-e8f4-30c5-59f978d9f2c0.png) 正常ならばこのような感じで進行します。転送が終わったら PuTTY や Tera Term でつないで (デフォルトで 9600 bps) 〔Enter〕キーを叩けば CP/M 8266 が起動します。 ![image.png](./images/fcafc16f-4077-2edf-d80a-336fc2e4dc5e.png) ドライブは A: ~ O: まであります。 | ドライブ | 説明 | |:---:|:---| |A:|システム、アセンブラ| |B:|アセンブラ、リンカ、Microsoft Basic| |C:|Turbo Pascal 3.01A| |D:|Word Star 3.0| |E:|Word Star 3.3| |F:|(なし)| |G:|ゲーム| |H:|BASIC プログラム| |I:|BASIC プログラム| |J:|(なし)| |K:|(なし)| |L:|(なし)| |M:|XMODEM| |N:|Z80 アセンブラサンプル?| |O:|(なし)| Turbo Pascal を動かしてみました。 ![image.png](./images/93028a44-8fdd-4a2a-09c3-d80946bd68d5.png) ビルドオプションを変更して ESP-WROOM-02 (EP8266) に対して Wi-Fi 経由で Telnet 接続できるようにする事も可能なのですが、メモリが 36K になってしまい Turbo Pascal 等がマトモに動作しなくなってしまいます。 ## 7.CP/M 8266 イメージの退避 Windows の C ドライブは /mnt/c として透過的に見えるので CP/M 8266 のバイナリを退避させておきましょう。 ```text: $ mkdir /mnt/c/cpm8266 $ cp -v *.bin /mnt/c/cpm8266 $ cp -v disks/*.DSK /mnt/c/cpm8266 ``` こうしておけば、 ```batch:write_cpm8266.cmd @echo off SET COM_PORT=COM5 SET UP_SPD=921600 SET ESPTOOL=%LocalAppData%\Arduino15\packages\esp32\tools\esptool\2.3.1 %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x00000 image.elf-0x00000.bin %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x10000 image.elf-0x10000.bin %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x3c0000 DISK_A.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x381000 DISK_B.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x342000 DISK_C.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x303000 DISK_D.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x2c4000 DISK_E.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x285000 DISK_F.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x246000 DISK_G.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x207000 DISK_H.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x1c8000 DISK_I.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x189000 DISK_J.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x14a000 DISK_K.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x10b000 DISK_L.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x0cc000 DISK_M.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x08d000 DISK_N.DSK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% write_flash 0x04e000 DISK_O.DSK ``` **esptool** を使ってアップロードできます。バッチファイルは [arduino-esp32](https://github.com/espressif/arduino-esp32) 付属の esptool を使う設定になっていますので、適宜読み替えてください。GUI な [Flash Download Tools (Espressif)](https://www.espressif.com/en/support/download/other-tools) を使ってアップロードする事もできます。 ## 8.CP/M 8266 ディスクイメージの退避 (バックアップ) ESP-WROOM-02 (EP8266) のフラッシュメモリからディスクイメージを抜き出すには以下のバッチファイルを使います。 ```batch:read_cpm8266.cmd @echo off SET COM_PORT=COM5 SET UP_SPD=921600 SET ESPTOOL=%LocalAppData%\Arduino15\packages\esp32\tools\esptool\2.3.1 %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x3c0000 0x3E900 DISK_A.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x381000 0x3E900 DISK_B.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x342000 0x3E900 DISK_C.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x303000 0x3E900 DISK_D.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x2c4000 0x3E900 DISK_E.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x285000 0x3E900 DISK_F.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x246000 0x3E900 DISK_G.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x207000 0x3E900 DISK_H.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x1c8000 0x3E900 DISK_I.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x189000 0x3E900 DISK_J.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x14a000 0x3E900 DISK_K.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x10b000 0x3E900 DISK_L.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x0cc000 0x3E900 DISK_M.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x08d000 0x3E900 DISK_N.DSK.BAK %ESPTOOL%\esptool.exe --chip esp8266 --port %COM_PORT% --baud %UP_SPD% read_flash 0x04e000 0x3E900 DISK_O.DSK.BAK :EXIT PAUSE ``` 環境設定が済んだ CP/M 8266 のディスクイメージのバックアップを取っておく事ができます。 # おわりに [CP/M 8266](https://github.com/SmallRoomLabs/cpm8266) とは別に [RunCPM](https://github.com/MockbaTheBorg/RunCPM) という CP/M 2.2 エミュレータもあります。こちらは Arduino ベースでインストールも簡単なのですが、ESP-WROOM-02 (EP8266) だと最大でも 34K のメモリしか確保できません。 62K のメモリが使え、ディスク IO も早いので、ESP-WROOM-02 (EP8266) で CP/M エミュレータを動かすなら [CP/M 8266](https://github.com/SmallRoomLabs/cpm8266) の方がよさそうです。 **See also:** - [RunCPM (Z80 CP/M 2.2 エミュレータ) (ht-deko.com)](https://ht-deko.com/arduino/runcpm.html)