Multics on docker

## はじめに
以前「Multics on docker」「Multics on docker part2」という記事を書きました。
Alpine Linuxもバージョンアップしてたりするし、最新の Dps8/M エミュレータを使ってみようと思った。
色々やったんですが、libuvがgitからのダウンロードで失敗するし、Multics の QuickStart もダウンロードが遅いしということで、Dockerfile の見直しを行いました。
Dps8/MはR3.1.0としました。
「Multics on docker」「Multics on docker part2」は内容が重複するので削除しました。
参考になるサイトは[Multics Wiki](https://multics-wiki.swenson.org/index.php/Main_Page)です。
## Dockerfile
「apk del build-dependencies」は後々のことを考えれば、削除した方が良いかも。gccとか無くなってしまいます。
```Dockerfile:Dockerfile
FROM alpine:3.21.3
RUN apk update \
    && apk --no-cache --virtual .build-deps add tzdata \
    && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && echo "Asia/Tokyo" >  /etc/timezone \
    && apk del --purge .build-deps

ENV BUILDPKGS "git libtool automake make m4 autoconf gcc libc-dev libpcap-dev pcre-dev"

RUN apk --no-cache add --virtual build-dependencies $BUILDPKGS && \
    mkdir -p /opt/multics_install  && \
    cd /opt/multics_install  && \
    wget https://github.com/libuv/libuv/archive/refs/heads/v1.x.zip && \
    unzip v1.x.zip && \
    cd libuv-1.x && \
    sh autogen.sh && \
    ./configure && \
    make -j $(nproc) && \
    make install
RUN cd /opt/multics_install && \
    wget https://dps8m.gitlab.io/dps8m-r3.1.0-archive/R3.1.0/dps8m-r3.1.0-src.tar.lz && \
    lzip -dc dps8m-r3.1.0-src.tar.lz | tar xvf - && \

    cd dps8 && \
    make -j $(nproc)  && \
    cp /opt/multics_install/dps8m/src/prt2pdf/prt2pdf /usr/local/bin && \
    cp /opt/multics_install/dps8m/src/punutil/punutil /usr/local/bin && \
    make install && \
    rm -R /opt/multics_install
RUN mkdir -p /opt/multics
COPY QuickStart_MR12.8.zip /opt/multics/
RUN unzip /opt/multics/QuickStart_MR12.8.zip -d /opt/multics/ && \
    rm /opt/multics/QuickStart_MR12.8.zip && \
    mv /opt/multics/QuickStart_MR12.8 /opt/multics/qs
RUN apk add busybox-extras && \
    apk del build-dependencies && \
    rm -rf /var/cache/apk/*

EXPOSE 6180

WORKDIR /opt/multics/qs

#ENTRYPOINT ["dps8", "MR12.8_boot.ini"]
```
環境ができたら色々試したいので ENTRYPOINT は取り合えずコメントとしました。
## サイトの設定
タイムゾーンの設定やらユーザの追加を行います。 /opt/multics/qs/site_setup.shというファイルがあります。 これを更新し、「./site_setup.sh > kazu.ini」と設定ファイルを作成、「dps8 kazu.ini」とやって設定を反映させます。 元の site_setup.sh との差分は以下です。追加するユーザ名等変更しています。
予め用意して置いて、Dockerイメージ作る際に実行しても良いかな。
```
--- site_setup.sh
+++ site_setup.sh_orig
@@ -4,31 +4,31 @@
 # -----------------

 # Your System name
-SYSTEM_NAME="Kazu Corp. Systems"
+SYSTEM_NAME="Yoyodyne Propulsion Systems"
 SYSTEM_NAME_DOUBLE_SPACED=`echo ${SYSTEM_NAME} | sed "s/\(.\)/\1 /g" | sed "s/ $//"`

 # Project Administrator name
-PROJECT_ADMINISTRATOR="Kazuhisa, Shimizu"
+PROJECT_ADMINISTRATOR="Chiclitz, Clayton"

 # Project Administratot Organization
-ORGANIZATION_ADMINISTRATOR="Kazu"
+ORGANIZATION_ADMINISTRATOR="Yoyodyne"

 # Your Account name
 ### TODO : has to start with an upper case letter
-ACCOUNT_NAME="Kazuhisa"
+ACCOUNT_NAME="Clayton"

 # Your Account password
 ### TODO: Check length and valid characters (8, [a-zA-Z0-9] ? )
 ACCOUNT_PASSWORD="password"

 # Your name and organization
-NAME="Kazuhisa, Shimizu"
-ORGANIZATION="Kazu"
+NAME="Chiclitz, Clayton"
+ORGANIZATION="Yoyodyne"

-TIME_ZONE="jst"
+TIME_ZONE="pst"

 cat <<EOF
-attach -r tape0 12.8MULTICS.tap
+attach -r tape0 12.7MULTICS.tap
 attach disk0 root.dsk

 set debug stdout
```
その後「dps8 MR12.8_boot.ini」で起動します。
```
$ docker run -it -p 6180:6180 --name multics multics
/opt/multics/qs # dps8 MR12.8_boot.ini
DPS8/M simulator R3.1.0 (64-bit)
  Commit: a834c552e9046ed485fabbefa3139dc5ea08e64d


Please register your system at https://dps8m.gitlab.io/register/
or create the file 'serial.txt' containing the line 'sn: 0'.


TAPE: unit is read only (12.8MULTICS.tap)

Note:
If, during boot, you see the message "bce: Unrecognizable request.  Type lr for a list of requests.", you can safely ignore it.

[FNP emulation: TELNET server listening on 0.0.0.0:6180]
CPU A: Thread created (TID 39)
CONSOLE: ALERT
bootload_0: Booting system MR12.8 generated 08/02/23 1032.0 pdt Wed.
0200.8  announce_chwm: 431. pages used of 512. in wired environment.
0200.8  announce_chwm: 708. words used of 1024. in int_unpaged_page_tables.
find_rpv_subsystem: Enter RPV data: M-> [auto-input] rpv a11 ipc 3381 0a

0200.8  load_mst: 954. out of 1048. pages used in disk mst area.
bce (early) 0200.8: M-> [auto-input] bce

System was last shutdown at:
Saturday, May 17, 2025 10:47:31 jst
Current system time is: Saturday, May 17, 2025 11:00:52 jst.
Is this correct? M-> [auto-input] yes

bce (boot) 1100.8: M-> [auto-input] yes

bce: Unrecognizable request.  Type lr for a list of requests.
bce (boot) 1100.8: M-> [auto-input] boot star

1100.9  CPU A: Model #: DPS 8/SIM M; Serial #: 0; Ship date: 250514; PROM Layout Version: 2;
          Simulator Release: R3.1.0 (2025-05-14); Build Number: <None>;
          Build Arch: x86_64; Build OS: Linux;
          Target Arch: Intel x86_64 (AMD64); Target OS: Linux.
Multics MR12.8 - 05/17/25  1100.9 jst Sat
1101.0  Loading FNP d, >user_dir_dir>SysAdmin>a>mcs.7.6c>site_mcs 7.6c
[FNP emulation: FNP d received BOOTLOAD command]
[FNP emulation: FNP already initialized]
1101.0  FNP d loaded successfully

scavenge_vol: No volumes found
Ready
 1101  as   as_init_: Multics MR12.8; Answering Service 17.0
 1101  as   LOGIN              IO.SysDaemon dmn cord (create)
 1101  as   LOGIN              Backup.SysDaemon dmn bk (create)
 1101  as   LOGIN              IO.SysDaemon dmn prta (create)
 1101  as   LOGIN              Utility.SysDaemon dmn ut (create)
 1101  as   LOGIN              Volume_Dumper.Daemon dmn vinc (create)
 1101  as   as_mcs_mpx_: Load signalled for FNP d.
 1101  bk
 1101  cord Enter command:  coordinator, driver, or logout:
-->  cord
 1101  prta Enter command:  coordinator, driver, or logout:
-->  prta
 1101  bk   r 11:01 0.125 34
 1101  bk
-->  bk
 1101  ut   copy_dump: Attempt to re-copy an invalid dump.
 1101  vinc
 1101  vinc r 11:01 0.123 25
 1101  vinc
-->  vinc
 1101  as   sc_admin_command_: Utility.SysDaemon.z: delete_old_pdds
 1101  ut   send_admin_command: Execution started ...
 1101  ut   completed.
 1101  ut
 1101  ut   Records   Left  %    VTOCEs   Left  %   PB/PD  LV Name
 1101  ut
 1101  ut   166388   91371  55   42326   33807  80  pb     root
 1101  ut
 1101  ut   r 11:01 0.803 498
 1101  ut
-->  ut
1101.0  RCP: Attached tapa_00 for Utility.SysDaemon.z
1101.0  RCP: Detached tapa_00 from Utility.SysDaemon.z
1101.0  RCP: Attached rdra for Utility.SysDaemon.z
1101.0  RCP: Detached rdra from Utility.SysDaemon.z
1101.0  RCP: Attached puna for Utility.SysDaemon.z
1101.0  RCP: Detached puna from Utility.SysDaemon.z
1101.0  RCP: Attached prta for Utility.SysDaemon.z
1101.0  RCP: Detached prta from Utility.SysDaemon.z
```
## Multicsへの接続
立ち上げた後の接続は[Multics on docker](https://qiita.com/suzanHud/items/eb234f91f5833b3d0f7d)で書いたユーザRepairでできます。Teraterm等でローカルホストのポート6180にアクセスします。ユーザRepairの初期パスワードはrepairです。ここでは site_setuup.sh で作成したユーザでログインしてみます。
```
HSLA Port (d.h000,d.h001,d.h002,d.h003,d.h004,d.h005,d.h006,d.h007,d.h008,d.h009,d.h010,d.h011,d.h012,d.h013,d.h014,d.h015,d.h016,d.h017,d.h018,d.h019,d.h020,d.h021,d.h022,d.h023,d.h024,d.h025,d.h026,d.h027,d.h028,d.h029,d.h030,d.h031)?
Attached to line d.h000

Multics MR12.8: Kazu Corp. Systems (Channel d.h000)
Load = 5.0 out of 90.0 units: users = 5, 05/17/25  1102.8 jst Sat
login Kazuhisa
Password:
You are protected from preemption until 11:04.
Kazuhisa.SysEng logged in 05/17/25  1104.1 jst Sat from ASCII terminal "none".

New messages in message_of_the_day:

Welcome to the Multics System.

print_motd:  Created >user_dir_dir>SysEng>Kazuhisa>Kazuhisa.value.
r 11:04 0.139 33

ls

Segments = 2, Lengths = 1.

r w    1  Kazuhisa.value
r w    0  card_input.acs

r 11:04 0.014 6

date
05/17/25
r 11:05 0.000 3

who -a -lg

Multics MR12.8; Kazu Corp. Systems
Load = 6.0 out of 90.0 units; users = 6, 1 interactive, 5 daemons.
Absentee users = 0 background; Max background absentee users = 3
System up since 05/17/25  1101.0 jst Sat
Last shutdown was at 05/17/25  1047.4 jst Sat

    Login at      TTY  Load   User ID

05/17/25  11:01  cord  1.0   IO.SysDaemon
          11:01  bk    1.0   Backup.SysDaemon
          11:01  prta  1.0   IO.SysDaemon
          11:01  ut    1.0   Utility.SysDaemon
          11:01  vinc  1.0   Volume_Dumper.Daemon
          11:04  none  1.0   Kazuhisa.SysEng

r 11:05 0.024 2
```
site_setup.shで設定した「Multics MR12.8: Kazu Corp. Systems」となり、ユーザ「Kazuhisa」でログインでき、タイムゾーンもJSTとなりました。
注意点として31行目の「attach -r tape0 12.7MULTICS.tap」は「attach -r tape0 12.8MULTICS.tap」に修正しましょう。
## Multicsのshutdown
ついでに shutdown の方法も再掲します。ESC、「logout * * *」、ESC、「shut」、ESC、「die」「yes」と必要に応じてESCを叩きます。
```
M-> logout * * *

Ready
M->
CONSOLE: RELEASED

 1107  as   LOGOUT             IO.SysDaemon.z dmn cord   0: 0 $0.01 (looc)
 1107  as   LOGOUT             Backup.SysDaemon.z dmn bk   0: 0 $0.01 (looc)
 1107  as   LOGOUT             IO.SysDaemon.z dmn prta   0: 0 $0.01 (looc)
 1107  as   LOGOUT             Utility.SysDaemon.z dmn ut   0: 1 $1.72 (looc)
 1107  as   LOGOUT             Volume_Dumper.Daemon.z dmn vinc   0: 0 $0.01 (looc)
M-> shut

 1107  as   act_ctl_: shutdown, 6 0.03 0.03 0.00 0.42 0:0:1 $1.83
1107.4  shutdown complete
bce (boot) 1107.4: M-> die

Do you really wish bce to die? M-> yes

BCE DIS causes CPU halt

+---------------------------------+
|         CPU A Statistics        |
+---------------------------------+
|  CPU Time Used    00:00:28.019  |
+---------------------------------+
|  cycles              529694208  |
|  instructions        265936494  |
+---------------------------------+
|  lockCnt             366112301  |
|  lockImmediate       366112301  |
+---------------------------------+
|  lockWait                    0  |
|  lockWaitMax                 0  |
|  lockYield                   0  |
+---------------------------------+
|   CPU A Micro-cache Statistics  |
+---------------------------------+
|  Instruction Fetch:             |
|    Hits               30815384  |
|    Misses              1784460  |
|    Skipped            83282218  |
|    Effectiveness        26.59%  |
+---------------------------------+
|  Operand Read:                  |
|    Hits               41408152  |
|    Misses              7177816  |
|    Skipped                   0  |
|    Effectiveness        85.23%  |
+---------------------------------+
|  Cache Bypasses:                |
|    RALR                     74  |
|    CALL6               1062316  |
|    Segno                     0  |
+---------------------------------+

Simulation stop, IC: 000000 (000000000000)
sim>
```
## アーカイブからのファイル取り出し
archiveコマンドでアーカイブファイルから取り出せます。
```
ls >ldd>unbundled>source>tss_basic_.s.archive

Segments = 1, Lengths = 20.

re    20  tss_basic_.s.archive
          4sqrs.basic
          annuit.basic
          bayes.basic
          biconf.basic
          blkjak.basic
          condif.basic
          conlim.basic
          curfit.basic
          linpro.basic
          linreg.basic
          pert.basic
          plotto.basic
          polfit.basic
          return.basic
          saving.basic
          stat12.basic
          triang.basic
          truint.basic
          twoplo.basic
          unista.basic
          xyplot.basic

r 13:37 0.053 48

archive x >ldd>unbundled>source>tss_basic_.s.archive 4sqrs.basic
r 13:38 0.021 30

ls

Segments = 3, Lengths = 2.

r w    1  4sqrs.basic
r w    1  Kazuhisa.value
r w    0  card_input.acs

r 13:38 0.009 0

print 4sqrs.basic

                    4sqrs.basic         07/23/24  1340.6 jst Tue

10 PRINT "4SQRS"
20 PRINT "N = A^2 + B^2 + C^2 + D^2"
30 PRINT
40 PRINT "N    A     B     C     D"
50 PRINT"------------------------"
60 PRINT
70 INPUT M
80 LET N=ABS(M)
90 LET R=SQR(N)
100 FOR A = 0 TO R
110 LET A2=A*A
120 LET N1=N-A2
130 FOR B = 0 TO N1
140 LET B2=B*B
150 LET N2=N1-B2
160 FOR C = 0 TO N2
170 LET C2 = C*C
180 IF A2+B2+C2 > N THEN 270
190 LET D = SQR(N-A2-B2-C2)
200 IF D > INT(D) THEN 260
210 IF M>=0 THEN 240
220 PRINT " ";-A;-B;-C;-D
230 GO TO 60
240 PRINT " ";A;B;C;D
250 GO TO 60
260 NEXT C
270 NEXT B
280 NEXT A
290 GO TO 60
300 END

r 13:40 0.048 13
```
## 印刷
[Printing_Files](http://multics-wiki.swenson.org/index.php/Using_Multics)に方法が書いてありました。コンソールで「x io」を入力し、印刷デーモンを動かします。
```
M-> CONSOLE: RELEASED

M-> x io

sc_command r cord coordinator
pause 10
 1347  cord I/O Coordinator Version: 3.2
 1347  cord I/O Coordinator initialized
-->  cord
sc_command r prta driver
sc_command r prta prta
sc_command r prta go
Ready
M->
CONSOLE: RELEASED

1347.3  RCP: Attached prta for IO.SysDaemon.z
 1347  prta
 1347  prta IO Daemon Driver Version: 5.7
 1347  prta
 1347  prta Enter command or device/request_type:
 1347  cord New driver for device prta, request type printer (series = 10000)
 1347  prta
 1347  prta prta driver ready at 07/23/24  1347.4 jst Tue
 1347  prta
```
端末で「enter_output_request」(「eor」)コマンドで印刷します。
```
eor 4sqrs.basic
1 request submitted; 0 already in printer queue 3.
r 13:49 0.116 25
```
そうすると印刷デーモンが動きます。
```
 1349  prta Request 10001 printer q3:  >user_dir_dir>SysEng>Kazuhisa>4sqrs.basic
 1349  prta   from Kazuhisa.SysEng.a
 1349  prta   Charge for request 10001: $0.05  (30 lines,  1 pages)
 1349  prta prta driver: No requests, driver is idle.
 ```
動かしたカレントディレクトリにprtファイルが作成されます。
```
/opt/multics/qs # ls -l prta.spool.*.Kazuhisa.SysEng*
-rw-------    1 root     root          9637 Jul 23 13:49 prta.spool.10001.Kazuhisa.SysEng.a.BuX9us.prt
/opt/multics/qs #
```
*.prtはdps8mのソースに含まれるprt2pdfでPDFに変換できます。
```
/opt/multics/qs # prt2pdf < prta.spool.10001.Kazuhisa.SysEng.a.BuX9us.prt > 4sqrs.pdf
/opt/multics/qs #
```
以下、PDFのイメージです。表表紙、ファイルの内容、裏表紙が出力されます。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68593/e32fa05a-cbb2-cbda-74d5-0deced6c5053.png)

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68593/68bca649-f925-ef2b-5e73-2b32631bd8af.png)

![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68593/35a545fd-56da-8a86-8c34-55b47b6d3b47.png)
## カードデッキから読み込み
[Reading a Card Deck](https://multics-wiki.swenson.org/index.php/Using_Multics#Reading_a_Card_Deck)にある通り、カードデッキイメージを作成し、カードリーダのデーモンを起動します。
まず、カードデッキイメージを作成します。以下では「/tmp/rdra/sdeck.test.txt」です。
```
++data test.txt \Kazuhisa \Sys\Eng
++password XXXXXXXX
++format mcc noaddnl notrim
++control overwrite
++input
This is a test of card reading.
This is a test of card reading.
This is a test of card reading.
```
コンソールでデーモンを用いてカードを読み込みます。
```
M-> x rc

clean_card_pool -age 7
All entries older than 7 days have been removed.
sc_command login IO SysDaemon rdra
pause 10
 1655  as   LOGIN              IO.SysDaemon dmn rdra (create)
 1656  rdra Enter command:  coordinator, driver, or logout:
-->  rdra
sc_command r rdra driver
sc_command r rdra rdra
sc_command r rdra read_cards
Ready
M->
CONSOLE: RELEASED

1656.1  RCP: Attached rdra for IO.SysDaemon.z
 1656  rdra
 1656  rdra IO Daemon Driver Version: 5.7
 1656  rdra
 1656  rdra Enter command or device/request_type:
 1656  cord New driver for device rdra, request type dummy (series = 20000)
 1656  rdra
 1656  rdra rdra driver ready for station reader at 07/23/24  1656.2 jst Tue
 1656  rdra
 1656  rdra Card input started.
 1656  rdra *Begin deck*
 1656  rdra Reading test.txt.0 (mcc) for Kazuhisa.SysEng.
 1656  rdra *Successful read*
 1656  rdra rdra:   ***** Device Attention.
 1656  rdra         ***** Hopper empty or Stacker full.
 1656  rdra
 ```
 読み込まれたデータはシステムが保持しているので、ログインし、自分のファイルとします。
```
copy_cards test.txt
1 card decks copied.
r 16:58 0.027 1

ls test.txt

Segments = 1, Lengths = 1.

rew    1  test.txt

r 16:58 0.008 0

pr test.txt

                    test.txt  07/23/24  1658.3 jst Tue

This is a test of card reading.
This is a test of card reading.
This is a test of card reading.

r 16:58 0.012 0
```
## Multics 12.8インストールテープイメージ
テープイメージは[MR12.8_artifacts.zip](https://s3.amazonaws.com/eswenson-multics/public/releases/MR12.8/MR12.8_artifacts.zip)を入手すると楽です。中身は以下です。
```
% unzip -l MR12.8_artifacts.zip
Archive:  MR12.8_artifacts.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2023-08-11 06:40   MR12.8_artifacts/
    68191  2023-08-09 05:13   MR12.8_artifacts/MR12.8_SRB.txt
107501264  2023-08-06 03:12   MR12.8_artifacts/12.8UNBUNDLED.tap
     7317  2023-08-06 09:56   MR12.8_artifacts/MR12.8_coldboot.ini
  2686260  2023-08-09 04:56   MR12.8_artifacts/12.8MISC.tap
     9486  2023-08-06 10:01   MR12.8_artifacts/Tickets_fixed_in_MR12.8
 59364556  2023-08-06 03:10   MR12.8_artifacts/12.8EXEC.tap
   327810  2023-08-06 10:01   MR12.8_artifacts/system_book_
     1797  2023-08-08 11:34   MR12.8_artifacts/MR12.7_to_MR12.8_upgrade.ini
195008052  2023-08-11 06:39   MR12.8_artifacts/12.8LDD_STANDARD.tap
  5349060  2023-08-06 03:10   MR12.8_artifacts/12.8MULTICS.tap
 34175764  2023-08-10 00:21   MR12.8_artifacts/12.8AML.tap
      801  2023-08-06 09:56   MR12.8_artifacts/MR12.8_boot.ini
    79778  2023-08-09 05:13   MR12.8_artifacts/MR12.8_SIB.txt
---------                     -------
404580136                     14 file
```

[tapeUtils](https://github.com/charlesUnixPro/dps8m/tree/PR_rework)を入手しましょう。12.8UNBUNDLED.tapを見てみます。
```
% restore_tape 12.8UNBUNDLED_restore 12.8UNBUNDLED.tap
Reading tape file: 12.8UNBUNDLED.tap
Tape label information:
  Gold Hill Multics
  12.8UNBUNDLED

    3 DIR                    0 >library_dir_dir>mcs
    4 DIR                    0 >library_dir_dir>mcs>info
    5 DIR                    0 >library_dir_dir>mcs>source
    6 SEG               962712 >library_dir_dir>mcs>info>355_macros
      Creating BINARY file 12.8UNBUNDLED_restore\library_dir_dir\mcs\info\355_macros ()
   34 SEG               736803 >library_dir_dir>mcs>info>macros.map355
      Creating BINARY file 12.8UNBUNDLED_restore\library_dir_dir\mcs\info\macros.map355 (.map355)
   55 SEG                 7785 >library_dir_dir>mcs>info>macros_asm
      Creating BINARY file 12.8UNBUNDLED_restore\library_dir_dir\mcs\info\macros_asm ()
   57 SEG                12897 >library_dir_dir>mcs>info>site_mcs.bind_fnp
      Creating BINARY file 12.8UNBUNDLED_restore\library_dir_dir\mcs\info\site_mcs.bind_fnp (.bind_fnp)
   59 SEG                66060 >library_dir_dir>mcs>info>site_mcs.list
      Creating BINARY file 12.8UNBUNDLED_restore\library_dir_dir\mcs\info\site_mcs.list (.list)
(snip)
```
ソース関連のリストは以下の通りです(一部です）。
```
% ls */library_dir_dir/*/source
12.8UNBUNDLED_restore/library_dir_dir/mcs/source:
mcs.s.archive           mcs_bisync.s.archive  mcs_hasp.s.archive     mcs_x25.s.archive
mcs_autocall.s.archive  mcs_g115.s.archive    mcs_ibm3270.s.archive

12.8UNBUNDLED_restore/library_dir_dir/system_library_unbundled/source:
bound_ascii_dsm_.s.archive        bound_imft_.s.archive
bound_basic_.s.archive            bound_l6_ftf_.s.archive
bound_basic_runtime_.s.archive    bound_linus_.1.s.archive
bound_bft_.s.archive              bound_linus_.2.s.archive
bound_cobol_back_.1.s.archive     bound_lisp_compiler_.s.archive
bound_cobol_back_.2.s.archive     bound_lisp_intrprtr_.1.s.archive
bound_cobol_back_.3.s.archive     bound_lisp_intrprtr_.2.s.archive
(snip)
bound_ibm_io_.s.archive
```
## 端末設定
何も設定せずにログインした場合、端末設定は以下となります。
```
stty -a
Type: ASCII
Modes: ll79,^pl,can_type=overstrike,^edited,^tabs,can,esc,erkl,^rawi,^rawo,^red
\c,^vertsp,crecho,lfecho,tabecho,hndlquit,fulldpx,echoplex,^capo,^replay,^polit
\ce,^ctl_char,^blk_xfer,^breakall,^scroll,^prefixnl,^wake_tbl,^iflow,^oflow,^no
\c_outp,^8bit,^oddp.
Erase: #,  Kill: @
Frame_begin: \000, Frame_end: \000
Delays: vert_nl 127, horz_nl  0.960, const_tab 94, var_tab  1.000, backspace 16
\c, vt_ff 511
r 14:34 0.020 0
```
これだと不便なので、.bashrcと同じようなものとして「start_up.ec」と作成し、sttyコマンドを実行するようにします。
```
edm
Input.
stty -ttp vt100
.
Edit.
w start_up.ec
q
r 14:35 0.031 7
```
これでemacsを立ち上げたときに端末は聞かれません。
## コマンドの紹介
pwd(print_wdir)
cd(create_dir)
dd(delete_dir)
cwd(change_wdir)
ls(list)
dl(delete)
pr(print)

後、最初に以下を読みましょう。
・[New User's Intro to Multics Part 1](http://bitsavers.trailing-edge.com/pdf/honeywell/large_systems/multics/CH24-0_multicsIntrPt1_Nov79.pdf)
・[New User's Intro to Multics Part 2](http://bitsavers.trailing-edge.com/pdf/honeywell/large_systems/multics/CH25-0_multicsIntrPt2_Nov79.pdf)
Multicsの基本が書かれています。

引数が分からない場合、helpコマンドを使いましょう。
```
help cd

>doc>info>cd.info   (11 lines follow; 90 lines in info)

1985-02-08  create_dir, cd

Syntax as a command:  cd paths {-control_args}

Function: creates a specified directory branch in a specified
directory or in your working directory; that is, it creates a storage
system entry for an empty subdirectory.

Arguments:
paths
   are pathnames of directories to be created.

Control arguments (16).
  More help?
```
lsでACLが出力されますが[Multics Glossary -A-](https://multicians.org/mga.html)によると
r	read
e	execute
w	write
null	no access
でls -aとやってディレクトリが出力される場合
s	status
m	modify
a	append
null	no access
とのこと。
```
ls -a

Segments = 4, Lengths = 3.

r w    1  start_up.ec
rew    1  test.txt
r w    0  card_input.acs
r w    1  Kazuhisa.value

Directories = 1.

sma  test

r 17:32 0.014 0
```
## テープにバックアップ
テープにバックアップを取ります。
まず、ダンプ制御ファイルを作成します(以下ではfoo.dump)としました。
backup_dumpコマンドを実行します(リストアはretrieveコマンドです)。
このとき、ボリュームラベルを聞かれるのでラベル名を入力します。
以下は後述する認証まで行ってバックアップまでできた例です。
```
edm
Input.
>user_dir_dir>SysEng>Kazuhisa
.
Edit.
w foo.dump
q
r 20:53 0.085 7

backup_dump -control foo -debug

Type primary dump tape label:   kazuBackup
Mounting tape kazuBackup for writing
Mounted blank volume "kazuBackup" on device tapa_01
Begin at 07/24/24  2053.5 jst Wed
Map attached to file "!BBBKXnPnlHMPMb.backup.map".
Normal termination 07/24/24  2055.3 jst Wed.
r 20:55 1.794 43
```
コンソールにテープの認証を聞いてくるので、(テープを掛けてから(^^;)
認証(x auth)を入力します。
```
2053.8  RCP: Attached tapa_01 for Kazuhisa.SysEng.a
CONSOLE: ALERT
2053.8  RCP: Mount Reel kazuBackup with ring on tapa_01 for Kazuhisa.SysEng.a
attachTape selected unit 1
loadTape Attaching drive 1 to file kazuBackup.tap
TAPE: creating new file (kazuBackup.tap)
CONSOLE: ALERT
2053.8  RCP: Authenticate tapa_01.  It has blank label .
M-> x auth tapa_01 ***

Ready
M->
CONSOLE: RELEASED

2055.2  RCP: Detached tapa_01 from Kazuhisa.SysEng.a
```
backupコマンドを実行した結果、dsp8 を実行したディレクトリに「kazuBackup.tap」のようにラベル名.tapでテープイメージができます。
```
/opt/multics/qs # ls -l *.tap
-rw-r--r--    1 root     root       5349060 Jul 23 10:52 12.8MULTICS.tap
-rw-r--r--    1 root     root         65652 Jul 24 20:55 kazuBackup.tap
/opt/multics/qs #
```
バックアップテープイメージからファイルを取り出すこともできます。
tapeUtilsを使用します。が、なんか変です。止まらない。
```
/opt/multics/qs # restore_tape x kazuBackup.tap | head -20
Reading tape file: kazuBackup.tap
Tape label information:
  Kazu Corp. Systems
  kazuBackup

    3 DIR                    0 >user_dir_dir>SysEng>Kazuhisa
    4 SEG                36864 >user_dir_dir>SysEng>Kazuhisa>!BBBKXnPnlHMPMb.backup.map
      Creating BINARY file x\user_dir_dir\SysEng\Kazuhisa\!BBBKXnPnlHMPMb.backup.map (.map)
    6 SEG                10008 >user_dir_dir>SysEng>Kazuhisa>Kazuhisa.value
      Creating BINARY file x\user_dir_dir\SysEng\Kazuhisa\Kazuhisa.value (.value)
    8 SEG                    0 >user_dir_dir>SysEng>Kazuhisa>card_input.acs
create empty file () x/user_dir_dir/SysEng/Kazuhisa/card_input.acs
      Creating BINARY file x\user_dir_dir\SysEng\Kazuhisa\card_input.acs (.acs)
   10 SEG                  144 >user_dir_dir>SysEng>Kazuhisa>start_up.ec
      Creating BINARY file x\user_dir_dir\SysEng\Kazuhisa\start_up.ec (.ec)
   12 DIR                    0 >user_dir_dir>SysEng>Kazuhisa>test
   14 NDC dirlst             0 >user_dir_dir>SysEng>Kazuhisa>test>
```
再度バックアップを取り直し、restore_tapeを再ビルドし、実行してみた。今度は大丈夫そう。
```
/opt/multics/qs # restore_tape backup kazuBackup.tap
Reading tape file: kazuBackup.tap
Tape label information:
  Kazu Corp. Systems
  kazuBackup

    3 DIR                    0 >user_dir_dir>SysEng>Kazuhisa
    4 SEG                36864 >user_dir_dir>SysEng>Kazuhisa>!BBBKXnQCpDZHXN.backup.map
      Creating BINARY file backup\user_dir_dir\SysEng\Kazuhisa\!BBBKXnQCpDZHXN.backup.map (.map)
    6 SEG                 3420 >user_dir_dir>SysEng>Kazuhisa>Kazuhisa.value
      Creating BINARY file backup\user_dir_dir\SysEng\Kazuhisa\Kazuhisa.value (.value)
    8 SEG                    0 >user_dir_dir>SysEng>Kazuhisa>card_input.acs
create empty file () backup/user_dir_dir/SysEng/Kazuhisa/card_input.acs
      Creating BINARY file backup\user_dir_dir\SysEng\Kazuhisa\card_input.acs (.acs)
   10 SEG                  144 >user_dir_dir>SysEng>Kazuhisa>start_up.ec
      Creating BINARY file backup\user_dir_dir\SysEng\Kazuhisa\start_up.ec (.ec)
4 files restored
/opt/multics/qs #
```
また、取り出したファイルをASCIIに変換することもできます。
```
/opt/multics/qs # cd /opt/multics/qs/backup/user_dir_dir/SysEng/Kazuhisa
/opt/multics/qs/backup/user_dir_dir/SysEng/Kazuhisa # ls
!BBBKXnQCpDZHXN.backup.map  card_input.acs
Kazuhisa.value              start_up.ec
/opt/multics/qs/backup/user_dir_dir/SysEng/Kazuhisa # p72_to_acsii start_up.ec start_up.ec_ascii
/opt/multics/qs/backup/user_dir_dir/SysEng/Kazuhisa # cat start_up.ec_ascii
stty -ttp vt100
/opt/multics/qs/backup/user_dir_dir/SysEng/Kazuhisa #
```
## maclispで遊ぶ
```
lisp
*
(+ 5 6)
13
(defun factorial (x)
        (cond ((equal x 0) 1)
              (t (times x (factorial (1- x))))))
factorial
(factorial 3)
6
(factorial 4)
30
(quit)
r 15:58 0.055 72
```
ん、[改訂版Maclispマニュアル](https://www.maclisp.info/pitmanual/intro.html)
によると「デフォルト基数は8である」とある。lisp立ち上げ時に読み込むファイル(start_up.lisp)を作成する。
```
edm
Input.
;;; A very typical init file    -*- Mode:LISP; -*-
(comment) ;magic
(progn ; real init file stuff
  (setq base 10. ibase 10. *nopoint nil) ;change radix
  (setq nouuo t *rset t) ;these make debugging easier
  '*) ;return an asterisk for lisp to print out
.
Edit.
w start_up.lisp
q
r 16:02 0.041 1
```
再度、動かしてみる。
```
lisp
*
(+ 5 6)
11.
(quit)
r 16:02 0.025 13
```
基数が10進になっているね。
もう少し、遊んでみる。
後藤英一, 戸島凞, 石畑清著 "記号処理の基礎と応用"にMINI-LISPの実行サンプルとして微分実行結果が載っています。これをMaclispで動かしてみます。evaluatorなMINI-LISPの記述を修正します。
```
r 10:24 0.079 14

edm
Input.
(defun diff (e x)
  (cond ((atom e) (cond ((eq e x) 1) (t 0)))
        ((eq (car e) 'plus)
         (list 'plus (diff (cadr e) x) (diff (caddr e) x)))
        ((eq (car e) 'times)
         (list 'plus
               (list 'times (cadr e) (diff (caddr e) x))
               (list 'times (caddr e) (diff (cadr e) x))))))
(defun simp (e)
  (cond ((atom e) e)
        ((eq (car e) 'plus)
         (simpa (simp (cadr e)) (simp (caddr e))))
        ((eq (car e) 'times)
         (simpm (simp (cadr e)) (simp (caddr e))))))
(defun simpa (p q)
  (cond ((eq p 0) q)
        ((eq q 0) p)
        (t (list 'plus p q))))
(defun simpm (p q)
  (cond ((eq p 0) 0)
        ((eq q 0) 0)
        ((eq p 1) q)
        ((eq q 1) p)
        (t (list 'times p q))))
(defun sdiff (e x) (simp (diff e x)))
.
Edit.
w diff.lisp
q
r 10:25 0.041 1
```
後はロードしてsdiffを実行します。
```
r 10:25 0.041 1

lisp
*
(load "diff.lisp")
t
(diff '(plus (times a x) b) 'x)
(plus (plus (times a 1) (times x 0)) 0)
(sdiff '(plus (times a x) b) 'x)
a
(quit)
r 10:25 0.052 14
```
## system control requests
system controlのリクエストは以下があります。
```
M-> lr

Summary of system_control requests:

Type "list_help" for a list of topics available to the help request.
Type "help TOPIC" for more information on a given topic.

abs                      Control the absentee facility.
accept                   Accept a channel as a message coordinator
                            terminal.
accept_vchn              Accept a message coordinator virtual
                            channel.
add_lv, alv              Mount a logical volume for use.
add_vol, av              Inform the system of the location of a
                            physical volume.
admin                    Enter admin mode.
attach                   Attach a communications channel for use.
bce                      Return to BCE.
bump                     Bump an interactive user from the system.
del_lv, dlv              Demount a logical volume.
del_vol, dv              Demount a physical volume.
define                   Define a new virtual console, or add a
                            disposition to an existing one.
deroute                  Remove a routine of a source stream.
detach                   Forcibly detach a communications channel
                            from a user.
down                     Sets, cancels, or prints the scheduled
                            shutdown time.
drop                     Drop a channel from use as a message
                            coordinator terminal.
exec, x                  Executes an extended command.
force_reset              Force reset Answering Service locks and
                            masks.
go                       Start answering lines.
hmu                      Prints the number of users logged in.
init_vol                 Initialize a new physical volume.
intercom, ic             Send a message to another message
                            coordinator terminal.
list_disks, ld           Status of all disk drives.
list_lv_attachments,     Status of logical volume attachments.
   llva
list_vols, lsv           Status of storage system volumes.
login, logi              Logs in a daemon process.
logout, logo             Logs out a daemon process.
maxunits, maxu           Set the maximum number of users who may
                            login.
mc_list                  Lists message coordinator information.
message, motd            Edit the message of the day.
multics, mult            Initialize the Answering Service for a
                            special session.
no_start_up, ns          Disables execution of the system_start_up
                            exec_com.
quit                     Send a quit signal to a daemon process.
rcp                      Control RCP.
reply, r                 Send input to a daemon process.
reroute                  Change the routing of a source stream.
route                    Route a source stream to a virtual console.
sign_off                 Sign out as operator.
sign_on                  Sign in as operator.
redefine                 Replace the disposition of a virtual
                            console.
remove                   Remove a channel from use.
reset                    Reset some Answering Service locks and
                            masks.
salvage_vol              Physical volume salvage a volume.
set_time_zone, stz       Set the system time zone.
shutdown, shut           Shut down the system.
startup, star            Start the Answering Service and begin
                            answering lines.
stop                     Bump users in preparation for system
                            shutdown.
substty                  Substitute one message coordinator terminal
                            for another.
sysid                    Changes the system ID.
terminate                Forcibly terminate a process.
unbump                   Cancel a bump of an interactive user.
undefine                 Remove a disposition from a virtual
                            console.
set_drive_usage, sdu     Change a disk between user I/O and Storage
                            System use.
preload                  Preload a disk or tape volume.
unload                   Unload a disk or tape volume.
load_mpx                 Loads a multiplexer.
dump_mpx                 Dumps a multiplexer.
start_mpx                Starts a multiplexer.
stop_mpx                 Stops a multiplexer from accepting new
                            calls.
add_pdir_volume          Adds a logical volume to the set of pdir
                            volumes.
del_pdir_volume          Deletes a logical volume from the set of
                            pdir volumes.
set_pdir_volumes         Specifies the set of pdir logical volumes.
log                      Adds a message to the system log.
shift                    Changes the shift.
disconnect               Forcibly disconnects a user from their
                            terminal.
vacate_pdir_volume       Moves all user process directories off of a
                            logical volume.
shutdown_mpx             Shuts down a multiplexer without dumping
                            it.
reconfigure, rcf         Reconfigures system hardware.
lock_mca                 Disable input to the MCAs.
unlock_mca               Enable input to a selected MCA.
warn, w                  Sends a warning blast to a user.
who                      Lists logged in user.
word                     Changes the login word and banner message.
.                        Identify the signed-on operator.
help                     Obtain information on the operator
                            commands.
?                        Produce a list of the most commonly used
                            requests.
answer                   Provide preset answers to another request
                            line.
do                       Perform substitution into a control string
                            and execute or return the expansion.
execute_string, exs      Perform substitution into a control string
                            and execute the expansion.
list_help, lh            List topics for which help is available.
list_requests, lr        List brief information on subsystem
                            requests.
q                        Leave the subsystem.
substitute_arguments,    Perform substitution into a control string
   substitute_args,         and print or return the expansion.
   sbag
Ready
```
プリンタに出力する際に使用した「x io」は「Executes an extended command」ですね。
それで、extended commandは「&gt;sc1&gt;admin.ec」に定義されています。
sc1はsystem_coltrol_dirね。
ヘッダーは以下の通りです。
```
******************************************************
*                                                    *
* Copyright, (C) Honeywell Bull Inc., 1987           *
*                                                    *
* Copyright (c) 1972 by Massachusetts Institute of   *
* Technology and Honeywell Information Systems, Inc. *
*                                                    *
******************************************************
```
HISTORY COMMENTSを見ると [MIT versionのadmin.ec](https://web.mit.edu/multics-history/source/Multics/tools/admin.ec) から更新されているようです。以下は追加分です。
```
2) change(2018-01-12,Swenson), approve(2018-01-12,MCR10040),
   audit(2018-01-13,GDixon), install(2018-01-16,MR12.6g-0003):
   Fix "x repair" entry to not cause an answering service dump if no
   arguments are supplied.
3) change(2018-01-17,Swenson), approve(2018-01-17,MCR10045),
   audit(2018-01-23,Anthony), install(2018-01-23,MR12.6g-0011):
   Fix "x vcons" to not use obsolete control argument -skip_incr_count N
   to consolidated_volume_dump command.
4) change(2023-06-14,Swenson), approve(2023-06-14,MCR10134),
   audit(2023-06-30,GDixon), install(2023-06-30,MR12.8-1059):
   Update "x io1" to login the "puna" IO.SysDaemon before sending commands
   to it.
```
ちょっとADMIN.ECを覗いてみる。「x io」と「x io1」との違いは動かすデーモンがプリンタのみかプリンタ＋カードパンチャーかが異なります。
```
&  x io   starts coordinator, prta
&  x io1  starts coordinator, prta, puna
&
&label io
&label io1
sc_command r cord coordinator
pause 10
&label prta
sc_command r prta driver
sc_command r prta prta
sc_command r prta go
&if [equal &r1 io1] &then &goto punch
&quit
&
&label punch
&label puna
sc_command login IO SysDaemon puna
pause 10
sc_command r puna driver
sc_command r puna puna
sc_command r puna go
&quit
```
## カードパンチに出力する
「x io」とか上で書いたけど。カードパンチの出力方法が書いてなかった。デーモンをコンソールで動かす。
```
M-> x io1

sc_command r cord coordinator
pause 10
 1113  cord I/O Coordinator Version: 3.2
CONSOLE: ALERT
 1113  cord iodc_init: Warning -- Cannot get old saved list.  Some deletions may not be performed.
 1113  cord I/O Coordinator initialized
-->  cord
Host clock went backwards 2133984 uS!
sc_command r prta driver
sc_command r prta prta
sc_command r prta go
sc_command login IO SysDaemon puna
pause 10
 1113  as   LOGIN              IO.SysDaemon dmn puna (create)
 1113  puna Created >system_control_1>puna.message
 1113  puna Enter command:  coordinator, driver, or logout:
-->  puna
 1113  prta
 1113  prta IO Daemon Driver Version: 5.7
 1113  prta
 1113  prta Enter command or device/request_type:
 1113  cord New driver for device prta, request type printer (series = 10000)
1113.9  RCP: Attached prta for IO.SysDaemon.z
 1113  prta
 1113  prta prta driver ready at 07/29/24  1113.9 jst Mon
 1113  prta
 1113  prta Request 10001 printer q3:  >user_dir_dir>SysDaemon>Salvager>salv_output.08/17/23.15:35
 1113  prta   from Salvager.SysDaemon.z (for "SALV OUTPUT")
 1113  prta   Charge for request 10001: $0.91  (507 lines,  13 pages)
 1113  prta Request 10002 printer q3:  >user_dir_dir>SysDaemon>Salvager>online_salvout.08/17/23.15:35
 1113  prta   from Salvager.SysDaemon.z (for "SALV ONLINE")
 1113  prta   Charge for request 10002: $0.01  (8 lines,  1 pages)
sc_command r puna driver
sc_command r puna puna
sc_command r puna go
Ready
M->
CONSOLE: RELEASED

1114.1  RCP: Attached puna for IO.SysDaemon.z
 1114  puna
 1114  puna IO Daemon Driver Version: 5.7
 1114  puna
 1114  puna Enter command or device/request_type:
 1114  cord New driver for device puna, request type punch (series = 20000)
 1114  puna
 1114  puna puna driver ready at 07/29/24  1114.2 jst Mon
 1114  puna
 1114  prta prta driver: No requests, driver is idle.
 ```
 eorコマンドでファイルを出力する。
 ```
edm
Input.
aaaaaa
bbbbbb
.
Edit.
w ab.txt
q
r 11:33 0.040 7

print ab.txt

          ab.txt    07/29/24  1133.5 jst Mon

aaaaaa
bbbbbb

r 11:33 0.019 14

eor ab.txt -punch
1 request submitted; 0 already in punch queue 3.
r 11:33 -0.005 25
```
印刷の時と同様にファイルに出力されます。
```
/opt/multics/qs # ls -l puna.*
-rw-------    1 root     root          1560 Jul 29 11:34 puna.spool.20001.KAZUHISA.SYSENG.A.V5RqOq.pun
/opt/multics/qs #
```
これをpunutilを使って変換します。
```
/opt/multics/qs # punutil -h
****
Punch File Utility
****

Multics Punch Utility Program

Invoking:
    punutil [options]
Where options are:
  -h, --help      = Output this message
  -a, --auto      = Attempt to automatically determine the type of card deck
                      (Default; disables any previously enabled output options)
  -n, --no-auto   = Disable auto selection of the card format
                      (You must specify output control options)
  -v, --version   = Add version information to stderr output

Output control options:
    By default 'auto' mode is active, where a scan attempts to determine the
    type of deck.  The scan order is: 'MCC', '7punch', and 'raw' (if neither
    of  the  first  two seem  to apply).  Note  that  the options  below are
    mutually exclusive.
  -7, --7punch    = Interpret the cards as 7punch data and output the data
                      (currently not supported!)
  -c, --cards     = Output an ASCII art form of the punched cards with an '*'
                      representing the punches
  -f, --flip      = If --cards is specified, the banner cards will be 'flipped'
                      so they can be read normally
  -g, --glyphs    = Output the glyphs parsed from the banner cards as ASCII
  -m, --mcc       = Interpret the cards as MCC Punch Codes
                      (Invalid punch codes will be converted to spaces)
  -r, --raw       = Dump the raw card data as 12-bit words in column order

This program will  read a  card  spool file produced  by the DPS8M Simulator,
parse it, and produce the requested output on standard output. Note that only
one output mode may be selected.


 This software is made available under the terms of the ICU License,
 version 1.8.1 or later.  For complete details, see the "LICENSE.md"
 included or https://gitlab.com/dps8m/dps8m/-/blob/master/LICENSE.md
/opt/multics/qs # punutil < puna.spool.20001.KAZUHISA.SYSENG.A.V5RqOq.pun
****
Punch File Utility
****
>> Auto-detected MCC Punch Codes <<

*****
Writing MCC output
*****
aaaaaa
bbbbbb
/opt/multics/qs #
```
# おまけ
gcc/automake/make/m4/autoconfなどがinstallしているlinux環境があるならgccでビルドできます。こんな感じでコマンド打てば/usr/local/bin/dps8が生成されます。

```
apk add git libtool sudo
mkdir -p /opt/multics_install
cd /opt/multics_install
git clone https://github.com/libuv/libuv.git
cd libuv
git checkout v1.42.0 && \
sh autogen.sh && \
CC=gcc ./configure --disable-shared --enable-static
make V=1 && make V=1 install
cd /opt/multics_install
git clone https://gitlab.com/dps8m/dps8m
cd dps8m 
make -j $(nproc)  CC=gcc
make install
```

せっかくなのでBASICで遊んでみた。
```
edm
Input.
10 PRINT "HELLO,WORLD!"
20 END
.
Edit.
w hw.basic
q
r 00:24 0.030 2

basic hw
HELLO,WORLD!
r 00:24 0.014 2

ls

Segments = 2, Lengths = 2.

r w    1  hw.basic
r w    1  Repair.value

r 00:25 0.015 0
```
[Student Handbook Cource Code F01 MLTICS CONCEPT AND ITILIZATION](http://www.bitsavers.org/pdf/honeywell/large_systems/multics/F01_multicsIntroCourseOct78.pdf)に qedx コマンドの使用例が載っている。Unix系のedコマンドを知っていれば、内容はわかる、っというか逆か(^^;
```
qedx
a
"Now is hte time
for al good
their county
\f

1,$p
"Now is hte time
for al good
their county
2p
for al good
s/al/all/
```