--- nono/vm/pio.cpp 2026/04/29 17:04:55 1.1.1.8 +++ nono/vm/pio.cpp 2026/04/29 17:04:59 1.1.1.9 @@ -5,6 +5,7 @@ // #include "pio.h" +#include "bitops.h" #include "config.h" #include "lcd.h" #include "mainapp.h" @@ -166,11 +167,49 @@ PPIDevice::Peek(uint32 offset) // 0x48000000 から 0x4c000000 の手前まで 4バイト単位でミラーが見える。 // // LUNA の DIP-SW は #1, #2 にそれぞれ8個、計16個ある。 -// DIP-SW #1, #2 が設定ファイルの luna_dipsw_{1,2} に対応する。 -// luna_dipsw_{1,2} はいずれも "0"/"1" を8つ並べた文字列であり、 +// DIP-SW #1, #2 が設定ファイルの luna-dipsw{1,2} に対応する。 +// luna-dipsw{1,2} はいずれも "0"/"1" を8つ並べた文字列であり、 // 先頭が本体表記でいう 1番、末尾側が本体表記でいう 8番に対応する。 -// 変数は dipsw{1,2}[0..7] に対応。 -// 設定ファイルと変数の値は %0 が down を表し、%1 が up を表す。 +// 値は "0" が down、"1" が up を表す。 +// +// PIO0Device 内ではこの設定を読み込んで bool dipsw1[8], dipsw2[8] の配列で +// 値を保持している。dipsw1[0] が本体表記1番、dipsw1[7] が本体表記 8番に対応 +// する。値は false が down("0")、true が up("1") に対応する。 +// +// PIO から読み出せる値のビットの並び順が機種によって異なる。 +// LUNA-1 では 1番が LSB、8番が MSB の並び順、 +// LUNA88K では 1番が MSB、8番が LSB の並び順。 +// 値は、並び順に関わらずどちらも +// %0 が false = down = "0"、%1 が true = up = "1" である。 +// +// #1 #2 #3 #4 #5 #6 #7 #8 +// +-------------------------+ +// | [] [] [] [] [] [] [] | 本体外観 +// | [] | +// +-------------------------+ +// +// luna-dipsw1 = "01111111" ← 設定ファイル +// |||||||| ↓ このクラスのメンバ変数 +// |||||||+- dipsw1[7] = true; +// ||||||+-- dipsw1[6] = true; +// |||||+--- dipsw1[5] = true; +// ||||+---- dipsw1[4] = true; +// |||+----- dipsw1[3] = true; +// ||+------ dipsw1[2] = true; +// |+------- dipsw1[1] = true; +// +-------- dipsw1[0] = false; +// +// b7 b6 b5 b4 b3 b2 b1 b0 +// +----+----+----+----+----+----+----+----+ +// LUNA-1 | #8 | #7 | #6 | #5 | #4 | #3 | #2 | #1 | +// PortA | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | %1=UP, %0=DOWN +// +----+----+----+----+----+----+----+----+ +// +// b7 b6 b5 b4 b3 b2 b1 b0 +// +----+----+----+----+----+----+----+----+ +// LUNA88K | #1 | #2 | #3 | #4 | #5 | #6 | #7 | #8 | +// PortA | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | %1=UP, %0=DOWN +// +----+----+----+----+----+----+----+----+ // // LUNA-1: // #1-1 up なら UNIX をロードして移行。down なら ROM モニタで起動。 @@ -194,7 +233,8 @@ PPIDevice::Peek(uint32 offset) // #1-1 up なら ROM モニタで停止、down ならマルチユーザブート。 // OpenBSD カーネルも up なら UserKernelConfig で止まる模様?。 // #1-2 up なら外付けシリアルコンソール、down なら内蔵ビットマップ。 -// #1-3..#1-8 は予約。 +// #1-3..#1-7 は不明? +// #1-8 down なら自己診断後電源オフするようだ。 // #2-x はユーザ(?) // コンストラクタ @@ -210,9 +250,11 @@ PIO0Device::PIO0Device() switch (gMainApp.GetVMType()) { case VMTYPE_LUNA1: gConfig->SetDefault("luna-dipsw1", "11110111"); + msb_first = false; break; case VMTYPE_LUNA88K: gConfig->SetDefault("luna-dipsw1", "11111111"); + msb_first = true; break; default: __unreachable(); @@ -363,11 +405,11 @@ PIO0Device::MonitorUpdate(Monitor *, Tex screen.Puts(0, y++, "PortC"); screen.Puts(1, y++, TA::OnOff(xp_reset), "b7: XP Reset"); screen.Puts(1, y++, TA::OnOff(parity), "b6: Parity"); - screen.Puts(1, y++, "b5: ---"); + screen.Puts(1, y++, TA::Disable, "b5: ---"); screen.Puts(1, y++, TA::OnOff(int5en), "b4: Int5 Enable"); screen.Puts(1, y++, TA::OnOff(int5rq), "b3: Int5 Request"); screen.Puts(1, y++, TA::OnOff(int1en), "b2: Int1 Enable"); - screen.Puts(1, y++, "b1: ---"); + screen.Puts(1, y++, TA::Disable, "b1: ---"); screen.Puts(1, y++, TA::OnOff(int1rq), "b0: Intq Request"); } @@ -379,6 +421,9 @@ PIO0Device::GetPA() const for (int i = 0; i < 8; i++) { data |= ((int)dipsw1[i]) << i; } + if (msb_first) { + data = bitrev(data); + } return data & 0xff; } @@ -390,6 +435,9 @@ PIO0Device::GetPB() const for (int i = 0; i < 8; i++) { data |= ((int)dipsw2[i]) << i; } + if (msb_first) { + data = bitrev(data); + } return data & 0xff; }