Annotation of nono/vm/power.cpp, revision 1.1.1.2

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2022 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // 電源周り
                      9: //
                     10: 
                     11: #include "power.h"
                     12: #include "mainapp.h"
1.1.1.2 ! root       13: #include "mfp.h"
1.1       root       14: #include "scheduler.h"
                     15: #include "sync.h"
                     16: #include "uimessage.h"
                     17: 
                     18: // グローバル参照用
                     19: PowerDevice *gPower;
                     20: 
                     21: // コンストラクタ
                     22: PowerDevice::PowerDevice()
                     23:        : inherited("Power")
                     24: {
1.1.1.2 ! root       25:        event.func = ToEventCallback(&PowerDevice::PowerCallback);
        !            26:        event.time = 1_msec;
        !            27:        event.Regist("Power Off");
        !            28: 
1.1       root       29:        gScheduler->ConnectMessage(MessageID::RESET, this,
                     30:                ToMessageCallback(&PowerDevice::ResetCallback));
                     31:        gScheduler->ConnectMessage(MessageID::POWEROFF_RESTART, this,
                     32:                ToMessageCallback(&PowerDevice::PowerOffCallback));
1.1.1.2 ! root       33:        gScheduler->ConnectMessage(MessageID::POWER_BUTTON, this,
        !            34:                ToMessageCallback(&PowerDevice::PowerButtonCallback));
1.1       root       35: }
                     36: 
                     37: // デストラクタ
                     38: PowerDevice::~PowerDevice()
                     39: {
                     40:        gPower = NULL;
                     41: }
                     42: 
                     43: // リセットをスケジューラに指示する。(外部から呼ばれる用)
                     44: void
                     45: PowerDevice::MakeResetHard()
                     46: {
                     47:        gScheduler->SendMessage(MessageID::RESET);
                     48: }
                     49: 
                     50: // リスタートをスケジューラに指示する。(外部から呼ばれる用)
                     51: void
                     52: PowerDevice::MakeRestart()
                     53: {
                     54:        gScheduler->SendMessage(MessageID::POWEROFF_RESTART);
                     55: }
                     56: 
1.1.1.2 ! root       57: // 電源ボタンを押す。 (外部から呼ばれる用)
1.1       root       58: void
1.1.1.2 ! root       59: PowerDevice::PowerButton()
1.1       root       60: {
1.1.1.2 ! root       61:        gScheduler->SendMessage(MessageID::POWER_BUTTON);
1.1       root       62: }
                     63: 
                     64: // リセットのメッセージコールバック
                     65: void
                     66: PowerDevice::ResetCallback(MessageID msgid, uint32 arg)
                     67: {
                     68:        DoResetHard();
                     69: }
                     70: 
                     71: // 電源オフのメッセージコールバック
                     72: void
                     73: PowerDevice::PowerOffCallback(MessageID msgid, uint32 arg)
                     74: {
                     75:        DoPowerOff(msgid);
                     76: }
                     77: 
1.1.1.2 ! root       78: // 電源ボタンのメッセージコールバック
        !            79: void
        !            80: PowerDevice::PowerButtonCallback(MessageID msgid, uint32 arg)
        !            81: {
        !            82:        DoPowerButton();
        !            83: }
        !            84: 
1.1       root       85: // 電源オン操作 (Device::ResetHard ではない)
                     86: void
                     87: PowerDevice::DoPowerOn()
                     88: {
                     89:        putlog(1, "PowerOn");
                     90: 
                     91:        if (ispower == false) {
                     92:                // 全デバイス電源オン
                     93:                ispower = true;
                     94:                for (auto obj : gMainApp.GetObjects()) {
                     95:                        auto dev = dynamic_cast<Device *>(obj);
                     96:                        if (dev) {
                     97:                                dev->ResetHard(true);
                     98:                        }
                     99:                }
                    100: 
                    101:                // 動作モード変更
                    102:                gSync->RequestPowerOffMode(false);
                    103:        }
                    104: }
                    105: 
                    106: // リセット操作 (Device::ResetHard ではない)
                    107: void
                    108: PowerDevice::DoResetHard()
                    109: {
                    110:        putlog(1, "Reset");
                    111: 
                    112:        if (ispower) {
                    113:                // 全デバイスをリセット
                    114:                for (auto obj : gMainApp.GetObjects()) {
                    115:                        auto dev = dynamic_cast<Device *>(obj);
                    116:                        if (dev) {
                    117:                                dev->ResetHard(false);
                    118:                        }
                    119:                }
                    120:        }
                    121: }
                    122: 
                    123: // 電源オフ操作 (Device::PowerOff ではない)
                    124: void
                    125: PowerDevice::DoPowerOff(MessageID msgid)
                    126: {
                    127:        putlog(1, "PowerOff");
                    128: 
                    129:        assertmsg(msgid == MessageID::POWEROFF_EXIT ||
                    130:                  msgid == MessageID::POWEROFF_RESTART,
                    131:                "msgid=%d", (int)msgid);
                    132: 
                    133:        if (ispower) {
                    134:                // 全デバイス電源オフ
                    135:                for (auto obj : gMainApp.GetObjects()) {
                    136:                        auto dev = dynamic_cast<Device *>(obj);
                    137:                        if (dev) {
                    138:                                dev->PowerOff();
                    139:                        }
                    140:                }
                    141:                ispower = false;
                    142: 
                    143:                // 動作モード変更
                    144:                gSync->RequestPowerOffMode(true);
                    145:        }
                    146: 
                    147:        // 電源オフ後の動作は引数によって異なる
                    148:        if (msgid == MessageID::POWEROFF_RESTART) {
                    149:                // 時間を始め直す
                    150:                gScheduler->StartTime();
                    151:                // 再び電源オンにする (リスタート)
                    152:                DoPowerOn();
                    153:        } else {
                    154:                // そうでなければ、GUI に終了を通知
                    155:                UIMessage::Post(UIMessage::APPEXIT);
                    156:        }
                    157: }
1.1.1.2 ! root      158: 
        !           159: // 電源ボタン操作
        !           160: void
        !           161: PowerDevice::DoPowerButton()
        !           162: {
        !           163:        putlog(1, "PowerButton");
        !           164: 
        !           165:        if (gMainApp.GetVMType() == VMType::X68030) {
        !           166:                // X68030 の電源ボタンはオルタネート動作
        !           167:                power_button = !power_button;
        !           168:                Change();
        !           169:                // MFP の POWSW 信号は負論理
        !           170:                gMFP->SetPowSW(!power_button);
        !           171:        } else {
        !           172:                // LUNA の電源ボタンはモーメンタリ動作
        !           173:                power_button = true;
        !           174:                Change();
        !           175:                power_button = false;
        !           176:        }
        !           177: }
        !           178: 
        !           179: // RP5C15 の ALARM_OUT を受け取る
        !           180: void
        !           181: PowerDevice::SetAlarmOut(bool alarm_out_)
        !           182: {
        !           183:        alarm_out = alarm_out_;
        !           184:        Change();
        !           185: }
        !           186: 
        !           187: // システム内の電源オン信号を受け取る。
        !           188: //                __
        !           189: // X68030 だと PW ON/OFF 信号(の反転)、
        !           190: // LUNA だと PIO1 の POWF* 信号で、どちらの場合も true がオン。
        !           191: void
        !           192: PowerDevice::SetSystemPowerOn(bool poweron)
        !           193: {
        !           194:        system_poweron = poweron;
        !           195:        Change();
        !           196: }
        !           197: 
        !           198: // 電源状態の変更。
        !           199: // power_button、alarm_out、system_poweron のいずれかの変更で呼ぶこと。
        !           200: void
        !           201: PowerDevice::Change()
        !           202: {
        !           203:        bool old_power = ispower;
        !           204:        bool new_power = power_button | alarm_out | system_poweron;
        !           205: 
        !           206:        if (old_power == false && new_power) {
        !           207:                DoPowerOn();
        !           208:        } else if (old_power && new_power == false) {
        !           209:                if (gMainApp.GetVMType() == VMType::X68030) {
        !           210:                        DoPowerOff(MessageID::POWEROFF_EXIT);
        !           211:                } else {
        !           212:                        gScheduler->RestartEvent(event);
        !           213:                }
        !           214:        }
        !           215: 
        !           216:        bool old_led = led;
        !           217:        if (gMainApp.GetVMType() == VMType::X68030) {
        !           218:                // X68030 の電源制御部の回路による。
        !           219:                led = power_button | alarm_out;
        !           220:        } else {
        !           221:                // LUNA の場合は電源の状態そのまま?
        !           222:                led = ispower;
        !           223:        }
        !           224:        if (old_led != led) {
        !           225:                // LED の状態が変わったことを UI に通知
        !           226:                UIMessage::Post(UIMessage::LED);
        !           227:        }
        !           228: }
        !           229: 
        !           230: // LUNA の電源オフが信号状態の変化に対し 1msec 遅れて応答することを
        !           231: // エミュレートするためのイベントコールバック
        !           232: void
        !           233: PowerDevice::PowerCallback(Event& ev)
        !           234: {
        !           235:        if (system_poweron == false) {
        !           236:                DoPowerOff(MessageID::POWEROFF_EXIT);
        !           237:        }
        !           238: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.