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

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

unix.superglobalmegacorp.com

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