|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.10 root 7: //
8: // PIO/PPI (i8255)
9: //
10:
11: // IODevice
12: // |
13: // | +-------------+
14: // +--| i8255Device | (8255 としての共通部分)
15: // +-------------+
16: // |
17: // | +-----------+
18: // +--| PPIDevice | (X68030)
19: // | +-----------+
20: // |
21: // | +------------+
22: // +--| PIO0Device | (LUNA)
23: // | +------------+
24: // |
25: // | +------------+
26: // +--| PIO1Device | (LUNA)
27: // +------------+
28:
1.1 root 29: #include "pio.h"
1.1.1.9 root 30: #include "bitops.h"
1.1.1.2 root 31: #include "config.h"
1.1 root 32: #include "lcd.h"
1.1.1.3 root 33: #include "mainapp.h"
1.1.1.10 root 34: #include "mpu.h"
35: #include "power.h"
1.1 root 36: #include "scheduler.h"
37:
1.1.1.10 root 38: // グローバル参照用
39: PPIDevice *gPPI;
40: PIO0Device *gPIO0;
41: PIO1Device *gPIO1;
1.1 root 42:
43: //
44: // i8255
45: //
46:
47: // コンストラクタ
1.1.1.8 root 48: i8255Device::i8255Device(const std::string& objname_)
49: : inherited(objname_)
1.1 root 50: {
51: }
52:
53: // デストラクタ
54: i8255Device::~i8255Device()
55: {
56: }
57:
1.1.1.4 root 58: // リセット
59: void
1.1.1.10 root 60: i8255Device::ResetHard(bool poweron)
1.1.1.4 root 61: {
62: // clears the control register
63: // and place ports A, B, and C in input mode.
64: // The input latches in ports A, B, and C are not cleared.
65:
66: ctrl = 0b10011011;
67: }
68:
1.1 root 69: // コントロールポートへの書き込み。
70: void
71: i8255Device::WriteCtrl(uint32 data)
72: {
73: if ((data & 0x80)) {
74: // 最上位が立っていればモード設定
75: ctrl = data;
76: putlog(1,
1.1.1.11! root 77: "Set mode: groupA=%d groupB=%d portA=%s portB=%s portC=%s/%s",
1.1 root 78: GetGroupAMode(), GetGroupBMode(),
79: PortADir() == DIR_IN ? "IN" : "OUT",
80: PortBDir() == DIR_IN ? "IN" : "OUT",
81: PortCHDir() == DIR_IN ? "IN" : "OUT",
82: PortCLDir() == DIR_IN ? "IN" : "OUT");
83:
84: // モード設定すると PC はゼロクリアされる
85: for (int pc = 0; pc < 8; pc++) {
86: SetPC(pc, 0);
87: }
88: } else {
89: // portC 出力
90: //
91: // 0 x x x P P P V
92: // | | | +-- 書き込むビットデータ
93: // +--+--+----- 書き込むビット位置
94:
95: int pc = (data >> 1) & 7;
96: int val = data & 1;
97: SetPC(pc, val);
98: }
99: }
100:
101: //
102: // X68k PPI
103: //
104:
105: // コンストラクタ
106: PPIDevice::PPIDevice()
1.1.1.8 root 107: : inherited("PPI")
1.1 root 108: {
109: devaddr = baseaddr;
110: devlen = 0x2000;
111: }
112:
113: // デストラクタ
114: PPIDevice::~PPIDevice()
115: {
1.1.1.10 root 116: gPPI = NULL;
1.1 root 117: }
118:
119: uint64
1.1.1.6 root 120: PPIDevice::Read(uint32 offset)
1.1 root 121: {
1.1.1.4 root 122: gMPU->AddCycle(19); // InsideOut p.135
123:
1.1.1.6 root 124: switch (offset) {
1.1 root 125: case 0:
126: case 1:
127: return 0xff;
128: case 2:
1.1.1.11! root 129: putlog(0, "Read $e9a005 PortC (NOT IMPLEMENTED)");
1.1.1.5 root 130: return 0xff;
1.1 root 131: case 3:
1.1.1.11! root 132: putlog(0, "Read $e9a007 Ctrl (NOT IMPLEMENTED)");
! 133: return 0xff;
1.1 root 134: default:
135: __unreachable();
136: }
137: }
138:
139: uint64
1.1.1.6 root 140: PPIDevice::Write(uint32 offset, uint32 data)
1.1 root 141: {
1.1.1.4 root 142: gMPU->AddCycle(19); // InsideOut p.135
143:
1.1.1.6 root 144: switch (offset) {
1.1 root 145: case 0:
146: case 1:
147: break;
1.1.1.11! root 148: case 2: // PPI PortC
! 149: for (int i = 0; i < 8; i++) {
! 150: SetPC(i, data & 1);
! 151: data >>= 1;
! 152: }
1.1 root 153: break;
154: case 3:
1.1.1.11! root 155: WriteCtrl(data);
1.1 root 156: break;
157: default:
158: __unreachable();
159: }
160: return 0;
161: }
162:
163: uint64
1.1.1.6 root 164: PPIDevice::Peek(uint32 offset)
1.1 root 165: {
166: // XXX
167: return 0xff;
168: }
169:
1.1.1.10 root 170: // PortC 書き込み
171: void
1.1.1.11! root 172: PPIDevice::SetPC(int pc, int val)
1.1.1.10 root 173: {
1.1.1.11! root 174: switch (pc) {
! 175: case 0: // ADPCM PAN Left Off
! 176: pan_left = !val;
! 177: break;
! 178: case 1: // ADPCM PAN Right Off
! 179: pan_right = !val;
! 180: break;
! 181: case 2: // ADPCM サンプリングレート
! 182: adpcm_rate = (adpcm_rate & 2) | val;
! 183: break;
! 184: case 3: // ADPCM サンプリングレート
! 185: adpcm_rate = (val << 1) | (adpcm_rate & 1);
! 186: break;
! 187:
! 188: case 4: // ジョイスティック #1 コントロール
! 189: case 5: // ジョイスティック #2 コントロール
! 190: case 6: // ジョイスティック #1 ボタン A
! 191: case 7: // ジョイスティック #1 ボタン B
! 192: putlog(1, "SetPC(%d) <- %d (NOT IMPLEMENTED)", pc, val);
! 193: break;
! 194: default:
! 195: __unreachable();
! 196: }
1.1.1.10 root 197: }
198:
1.1 root 199: //
200: // LUNA PIO0
201: //
202: // 仕様は 0x49000000 から 4バイトだが、
203: // 0x48000000 から 0x4c000000 の手前まで 4バイト単位でミラーが見える。
204: //
205: // LUNA の DIP-SW は #1, #2 にそれぞれ8個、計16個ある。
1.1.1.9 root 206: // DIP-SW #1, #2 が設定ファイルの luna-dipsw{1,2} に対応する。
207: // luna-dipsw{1,2} はいずれも "0"/"1" を8つ並べた文字列であり、
1.1 root 208: // 先頭が本体表記でいう 1番、末尾側が本体表記でいう 8番に対応する。
1.1.1.9 root 209: // 値は "0" が down、"1" が up を表す。
210: //
211: // PIO0Device 内ではこの設定を読み込んで bool dipsw1[8], dipsw2[8] の配列で
212: // 値を保持している。dipsw1[0] が本体表記1番、dipsw1[7] が本体表記 8番に対応
213: // する。値は false が down("0")、true が up("1") に対応する。
214: //
215: // PIO から読み出せる値のビットの並び順が機種によって異なる。
216: // LUNA-1 では 1番が LSB、8番が MSB の並び順、
217: // LUNA88K では 1番が MSB、8番が LSB の並び順。
218: // 値は、並び順に関わらずどちらも
219: // %0 が false = down = "0"、%1 が true = up = "1" である。
220: //
221: // #1 #2 #3 #4 #5 #6 #7 #8
222: // +-------------------------+
223: // | [] [] [] [] [] [] [] | 本体外観
224: // | [] |
225: // +-------------------------+
226: //
227: // luna-dipsw1 = "01111111" ← 設定ファイル
228: // |||||||| ↓ このクラスのメンバ変数
229: // |||||||+- dipsw1[7] = true;
230: // ||||||+-- dipsw1[6] = true;
231: // |||||+--- dipsw1[5] = true;
232: // ||||+---- dipsw1[4] = true;
233: // |||+----- dipsw1[3] = true;
234: // ||+------ dipsw1[2] = true;
235: // |+------- dipsw1[1] = true;
236: // +-------- dipsw1[0] = false;
237: //
238: // b7 b6 b5 b4 b3 b2 b1 b0
239: // +----+----+----+----+----+----+----+----+
240: // LUNA-1 | #8 | #7 | #6 | #5 | #4 | #3 | #2 | #1 |
241: // PortA | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | %1=UP, %0=DOWN
242: // +----+----+----+----+----+----+----+----+
243: //
244: // b7 b6 b5 b4 b3 b2 b1 b0
245: // +----+----+----+----+----+----+----+----+
246: // LUNA88K | #1 | #2 | #3 | #4 | #5 | #6 | #7 | #8 |
247: // PortA | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | %1=UP, %0=DOWN
248: // +----+----+----+----+----+----+----+----+
1.1 root 249: //
1.1.1.3 root 250: // LUNA-1:
1.1 root 251: // #1-1 up なら UNIX をロードして移行。down なら ROM モニタで起動。
252: // #1-2 up ならディスプレイコンソール。down ならシリアルコンソール。
253: // #1-3 up - color display, down - force to have monochrome display
254: // #1-4 up - no write verification,
255: // down - verification on every harddisk write operation
256: // #1-5 up - OS is UniOS-U (SystemV/COFF),
257: // down - OS is UniOS (4.3BSD/a.out OMAGIC)
258: // #1-6 down - force monochrome display?
259: // #1-7 up - boot from local device, down - boot from network
260: // #1-8 up - normal boot, down - start diagnostics と書いてあるが
261: // down にすると画面真っ暗で詳細不明。
262: //
263: // #2-x すべて up にすると /boot が自動的にカーネルを起動。一つでも down が
264: // あれば /boot がプロンプトで停止。これは ROM ではなく NetBSD のブート
265: // ローダの話。
266: // どこか由来のソースコードらしいがたぶんビット演算を間違えている。
1.1.1.3 root 267: //
268: // LUNA88K:
269: // #1-1 up なら ROM モニタで停止、down ならマルチユーザブート。
270: // OpenBSD カーネルも up なら UserKernelConfig で止まる模様?。
271: // #1-2 up なら外付けシリアルコンソール、down なら内蔵ビットマップ。
1.1.1.9 root 272: // #1-3..#1-7 は不明?
273: // #1-8 down なら自己診断後電源オフするようだ。
1.1.1.3 root 274: // #2-x はユーザ(?)
1.1 root 275:
276: // コンストラクタ
277: PIO0Device::PIO0Device()
1.1.1.8 root 278: : inherited("PIO0")
1.1 root 279: {
280: devaddr = 0x49000000;
281: devlen = 4;
1.1.1.2 root 282:
1.1.1.3 root 283: // 機種固有パラメータ
284:
285: // LUNA-1 と LUNA88K で使いやすいように初期値を変えておく。
286: switch (gMainApp.GetVMType()) {
1.1.1.11! root 287: case VMType::LUNA1:
1.1.1.3 root 288: gConfig->SetDefault("luna-dipsw1", "11110111");
1.1.1.9 root 289: msb_first = false;
1.1.1.3 root 290: break;
1.1.1.11! root 291: case VMType::LUNA88K:
1.1.1.4 root 292: gConfig->SetDefault("luna-dipsw1", "11111111");
1.1.1.9 root 293: msb_first = true;
1.1.1.3 root 294: break;
295: default:
296: __unreachable();
297: }
298: // DIP-SW#2 はユーザ定義(?)なので(今の所?)どちらも共通。
299: gConfig->SetDefault("luna-dipsw2", "11111111");
300:
1.1.1.10 root 301: monitor.func = ToMonitorCallback(&PIO0Device::MonitorUpdate);
1.1.1.8 root 302: monitor.SetSize(22, 11);
303: monitor.Regist(ID_MONITOR_PIO0);
1.1 root 304: }
305:
306: // デストラクタ
307: PIO0Device::~PIO0Device()
308: {
1.1.1.10 root 309: gPIO0 = NULL;
1.1 root 310: }
311:
312: bool
313: PIO0Device::Init()
314: {
315: // XXX 本当はラッチのタイミングが違う気もするけど、とりあえずね
316:
1.1.1.2 root 317: const ConfigItem& item1 = gConfig->Find("luna-dipsw1");
1.1 root 318: const std::string& str1 = item1.AsString();
319: if (str1.size() != 8) {
320: item1.Err("must be 8 digits");
321: return false;
322: }
323:
1.1.1.2 root 324: const ConfigItem& item2 = gConfig->Find("luna-dipsw2");
1.1 root 325: const std::string& str2 = item2.AsString();
326: if (str2.size() != 8) {
327: item2.Err("must be 8 digits");
328: return false;
329: }
330: for (int i = 0; i < 8; i++) {
331: dipsw1[i] = (str1[i] != '0');
332: dipsw2[i] = (str2[i] != '0');
333: }
334: return true;
335: }
336:
1.1.1.10 root 337: // XXX ResetHard 未調査
1.1.1.7 root 338:
1.1 root 339: uint64
1.1.1.6 root 340: PIO0Device::Read(uint32 offset)
1.1 root 341: {
342: uint32 data;
343:
1.1.1.6 root 344: switch (offset) {
1.1 root 345: case 0:
346: // PortA
1.1.1.11! root 347: data = GetPA();
! 348: putlog(1, "DIP-SW1 -> $%02x", data);
! 349: return data;
1.1 root 350:
351: case 1:
352: // PortB
1.1.1.11! root 353: data = GetPB();
! 354: putlog(1, "DIP-SW2 -> $%02x", data);
! 355: return data;
1.1 root 356:
357: case 2:
358: // PortC
359: data = GetPC();
1.1.1.11! root 360: putlog(1, "PortC -> $%02x", data);
1.1 root 361: return data;
362:
363: case 3:
364: data = ReadCtrl();
1.1.1.11! root 365: putlog(1, "Ctrl -> $%02x", data);
1.1 root 366: return data;
367:
368: default:
369: __unreachable();
370: }
371: }
372:
373: uint64
1.1.1.6 root 374: PIO0Device::Write(uint32 offset, uint32 data)
1.1 root 375: {
1.1.1.6 root 376: switch (offset) {
1.1 root 377: case 0: // PIO0 PortA: DIPSW1 (入力のみ)
378: case 1: // PIO0 PortB: DIPSW2 (入力のみ)
379: return 0;
380:
381: case 2: // PIO0 PortC: ホスト割り込み制御
382: for (int i = 0; i < 8; i++) {
383: SetPC(i, data & 1);
384: data >>= 1;
385: }
386: return 0;
387:
388: case 3: // コントロール
389: WriteCtrl(data);
390: return 0;
391:
392: default:
393: __unreachable();
394: }
395: }
396:
397: uint64
1.1.1.6 root 398: PIO0Device::Peek(uint32 offset)
1.1 root 399: {
1.1.1.6 root 400: switch (offset) {
1.1 root 401: case 0:
402: return GetPA();
403:
404: case 1:
405: return GetPB();
406:
407: case 2:
408: return GetPC();
409:
410: case 3:
411: return ReadCtrl();
412:
413: default:
414: __unreachable();
415: }
416: }
417:
1.1.1.3 root 418: void
1.1.1.8 root 419: PIO0Device::MonitorUpdate(Monitor *, TextScreen& screen)
1.1.1.2 root 420: {
421: int y;
422:
1.1.1.8 root 423: screen.Clear();
1.1.1.2 root 424:
425: y = 0;
1.1.1.8 root 426: screen.Print(0, y++, "PortA(DIPSW1):%c%c%c%c%c%c%c%c",
1.1.1.2 root 427: (dipsw1[0] ? '1' : '0'),
428: (dipsw1[1] ? '1' : '0'),
429: (dipsw1[2] ? '1' : '0'),
430: (dipsw1[3] ? '1' : '0'),
431: (dipsw1[4] ? '1' : '0'),
432: (dipsw1[5] ? '1' : '0'),
433: (dipsw1[6] ? '1' : '0'),
434: (dipsw1[7] ? '1' : '0'));
1.1.1.8 root 435: screen.Print(0, y++, "PortB(DIPSW2):%c%c%c%c%c%c%c%c",
1.1.1.2 root 436: (dipsw2[0] ? '1' : '0'),
437: (dipsw2[1] ? '1' : '0'),
438: (dipsw2[2] ? '1' : '0'),
439: (dipsw2[3] ? '1' : '0'),
440: (dipsw2[4] ? '1' : '0'),
441: (dipsw2[5] ? '1' : '0'),
442: (dipsw2[6] ? '1' : '0'),
443: (dipsw2[7] ? '1' : '0'));
1.1.1.8 root 444: screen.Puts(0, y++, "PortC");
445: screen.Puts(1, y++, TA::OnOff(xp_reset), "b7: XP Reset");
446: screen.Puts(1, y++, TA::OnOff(parity), "b6: Parity");
1.1.1.9 root 447: screen.Puts(1, y++, TA::Disable, "b5: ---");
1.1.1.8 root 448: screen.Puts(1, y++, TA::OnOff(int5en), "b4: Int5 Enable");
449: screen.Puts(1, y++, TA::OnOff(int5rq), "b3: Int5 Request");
450: screen.Puts(1, y++, TA::OnOff(int1en), "b2: Int1 Enable");
1.1.1.9 root 451: screen.Puts(1, y++, TA::Disable, "b1: ---");
1.1.1.8 root 452: screen.Puts(1, y++, TA::OnOff(int1rq), "b0: Intq Request");
1.1.1.2 root 453: }
454:
1.1 root 455: // PortA (DIP-SW 1) 読み込み
456: uint32
457: PIO0Device::GetPA() const
458: {
459: uint32 data = 0;
460: for (int i = 0; i < 8; i++) {
461: data |= ((int)dipsw1[i]) << i;
462: }
1.1.1.9 root 463: if (msb_first) {
464: data = bitrev(data);
465: }
1.1 root 466: return data & 0xff;
467: }
468:
469: // PortB (DIP-SW 2) 読み込み
470: uint32
471: PIO0Device::GetPB() const
472: {
473: uint32 data = 0;
474: for (int i = 0; i < 8; i++) {
475: data |= ((int)dipsw2[i]) << i;
476: }
1.1.1.9 root 477: if (msb_first) {
478: data = bitrev(data);
479: }
1.1 root 480: return data & 0xff;
481: }
482:
483: // PortC 読み込み
484: uint32
485: PIO0Device::GetPC() const
486: {
487: uint32 data;
488:
489: data = 0x00 // XXX 空きビットは何が読めるか?
490: | (int1rq ? 0x01 : 0)
491: | (int1en ? 0x04 : 0)
492: | (int5rq ? 0x08 : 0)
493: | (int5en ? 0x10 : 0)
494: | (parity ? 0x40 : 0)
495: | (xp_reset?0x80 : 0);
496: return data;
497: }
498:
499: // PortC 書き込み
500: void
501: PIO0Device::SetPC(int pc, int val)
502: {
503: switch (pc) {
504: case 0:
505: if ((val ^ int1rq)) {
506: int1rq = val;
1.1.1.11! root 507: putlog(0, "INT1 Interrupt Request %d (NOT IMPLEMENTED)", int1rq);
1.1 root 508: }
509: return;
510: case 1:
511: // Not Connected.
512: return;
513: case 2:
514: if ((val ^ int1en)) {
515: int1en = val;
1.1.1.11! root 516: putlog(0, "INT1 Interrupt Enable %d (NOT IMPLEMENTED)", int1en);
1.1 root 517: }
518: return;
519: case 3:
520: if ((val ^ int5rq)) {
521: int5rq = val;
1.1.1.11! root 522: putlog(0, "INT5 Interrupt Request %d (NOT IMPLEMENTED)", int5rq);
1.1 root 523: }
524: return;
525: case 4:
526: if ((val ^ int5en)) {
527: int5en = val;
1.1.1.11! root 528: putlog(0, "INT5 Interrupt Enable %d (NOT IMPLEMENTED)", int5en);
1.1 root 529: }
530: return;
531: case 5:
532: // Not Connected.
533: return;
534: case 6:
535: // パリティ有効/無効
536: // 使わないので無視するが読み返しのために覚えておく
537: parity = val;
538: return;
539: case 7:
540: // XP リセット
541: if ((val ^ xp_reset)) {
542: xp_reset = val;
1.1.1.11! root 543: putlog(0, "XP Reset %d (NOT IMPLEMENTED)", xp_reset);
1.1 root 544: }
545: return;
546: }
1.1.1.10 root 547: VMPANIC("invalid pc=%d", pc);
1.1 root 548: }
549:
550:
551: //
552: // LUNA PIO1
553: //
554: // 仕様は 0x4d000000 から 4バイトだが、
555: // 0x4c000000 から 0x50000000 の手前まで 4バイト単位でミラーが見える。
556:
557: // コンストラクタ
558: PIO1Device::PIO1Device()
1.1.1.8 root 559: : inherited("PIO1")
1.1 root 560: {
561: devaddr = 0x4d000000;
562: devlen = 4;
563:
564: }
565:
566: // デストラクタ
567: PIO1Device::~PIO1Device()
568: {
1.1.1.10 root 569: gPIO1 = NULL;
1.1 root 570: }
571:
1.1.1.4 root 572: // リセット
573: void
1.1.1.10 root 574: PIO1Device::ResetHard(bool poweron)
1.1.1.4 root 575: {
1.1.1.10 root 576: inherited::ResetHard(poweron);
1.1.1.4 root 577:
1.1.1.11! root 578: // デフォルトで PIO 出力は「1msec 後に電源オフ」という状態なので、
! 579: // 電源オンから 1msec 以内にソフトウェアがこれをキャンセルしないと
! 580: // いけないらしい。どうしてこうなった…。
! 581: gPower->SetSystemPowerOn(false);
1.1.1.4 root 582: }
583:
1.1 root 584: uint64
1.1.1.6 root 585: PIO1Device::Read(uint32 offset)
1.1 root 586: {
587: uint32 data;
588:
1.1.1.6 root 589: switch (offset) {
1.1 root 590: case 0:
591: // PIO1 PortA: LCD データ
592: return gLCD->Read();
593:
594: case 1:
595: // PIO1 PortB: 無効
596: return 0xff;
597:
598: case 2:
599: // PortC
600: data = gLCD->Get();
601: data |= xp_intreq ? 0 : 0x02;
602: // 残りのビットは %1 だろうか?
603: data |= 0x0d;
1.1.1.11! root 604: putlog(1, "PortC -> $%02x", data);
1.1 root 605: return data;
606:
607: case 3:
608: data = ReadCtrl();
1.1.1.11! root 609: putlog(1, "Ctrl -> $%02x", data);
1.1 root 610: return data;
611:
612: default:
613: __unreachable();
614: }
615: }
616:
617: uint64
1.1.1.6 root 618: PIO1Device::Write(uint32 offset, uint32 data)
1.1 root 619: {
1.1.1.6 root 620: switch (offset) {
1.1 root 621: case 0: // PIO1 PortA: LCD データ
622: gLCD->Write(data);
623: return 0;
624:
625: case 1: // PIO1 PortB: ローカル割り込み
626: break;
627:
628: case 2: // PIO1 PortC: LCD/パワーオフ制御
629: for (int i = 0; i < 8; i++) {
630: SetPC(i, data & 1);
631: data >>= 1;
632: }
633: return 0;
634:
635: case 3: // コントロール
636: WriteCtrl(data);
637: return 0;
638:
639: default:
640: __unreachable();
641: }
1.1.1.10 root 642: VMPANIC("$%08X <- $%02X 未サポート書き込み", gMPU->GetPaddr(), data);
1.1 root 643: return 0;
644: }
645:
646: uint64
1.1.1.6 root 647: PIO1Device::Peek(uint32 offset)
1.1 root 648: {
649: uint32 data;
650:
1.1.1.6 root 651: switch (offset) {
1.1 root 652: case 0: // PIO1 PortA LCD データ
653: return gLCD->Peek();
654:
655: case 1: // PIO1 PortB 無効
656: return 0xff;
657:
658: case 2: // PIO1 PortC
659: data = gLCD->Get();
660: data |= xp_intreq ? 0 : 0x02;
661: // 残りのビットは %1 だろうか?
662: data |= 0x0d;
663: return data;
664:
665: case 3:
666: return ReadCtrl();
667:
668: default:
669: __unreachable();
670: }
671: }
672:
673: void
674: PIO1Device::SetPC(int pc, int val)
675: {
676: switch (pc) {
677: case 0:
678: case 1:
679: case 2:
680: case 3:
681: // PortC の下半分は入力ポートとして使われることを想定して
682: // いるので、ここへの書き込みは起きないだろうし、無視する。
683: return;
684:
685: case 4:
686: power = val;
687: if (power) {
688: // 電源オフ取り消し
1.1.1.11! root 689: putlog(1, "Power-off canceled");
! 690: gPower->SetSystemPowerOn(true);
1.1 root 691: } else {
692: // 1msec 後に電源オフ
1.1.1.11! root 693: putlog(1, "Power-off scheduled");
! 694: gPower->SetSystemPowerOn(false);
1.1 root 695: }
696: return;
697: case 5:
698: gLCD->SetRW(val);
699: return;
700: case 6:
701: gLCD->SetRS(val);
702: return;
703: case 7:
704: gLCD->SetE(val);
705: return;
706:
707: default:
708: break;
709: }
1.1.1.10 root 710: VMPANIC("PC%d 未実装", pc);
1.1 root 711: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.