Annotation of nono/vm/pedec.cpp, revision 1.1.1.9

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
1.1.1.5   root        7: //
                      8: // PEDEC
                      9: //
                     10: 
                     11: // IODevice
                     12: //    |
                     13: //    +-- InterruptDevice (割り込みコントローラの共通部)
                     14: //          |
                     15: //          +-- M680x0Interrupt (m68k 割り込みコントローラの共通部)
                     16: //          |     |
                     17: //          |     +-- X68030Interrupt  (X68030 の割り込みコントローラ)
                     18: //          |     +-- LunaInterrupt    (LUNA-I の割り込みコントローラ)
                     19: //          |
                     20: //          |  +-------------+
                     21: //          +--| PEDECDevice | (X68030 の Lv1 担当コントローラ)
                     22: //          |  +-------------+
                     23: //          |
1.1.1.7   root       24: //          +-- SysCtlrDevice  (LUNA-88K の割り込みコントローラ)
1.1.1.5   root       25: 
1.1       root       26: #include "pedec.h"
                     27: #include "fdc.h"
1.1.1.6   root       28: #include "fdd.h"
1.1       root       29: #include "spc.h"
                     30: 
1.1.1.5   root       31: // コンストラクタ
1.1       root       32: PEDECDevice::PEDECDevice()
1.1.1.7   root       33:        : inherited(OBJ_PEDEC)
1.1       root       34: {
                     35: }
                     36: 
1.1.1.5   root       37: // デストラクタ
1.1       root       38: PEDECDevice::~PEDECDevice()
                     39: {
1.1.1.7   root       40: }
                     41: 
                     42: // 初期化
                     43: bool
                     44: PEDECDevice::Init()
                     45: {
                     46:        if (inherited::Init() == false) {
                     47:                return false;
                     48:        }
                     49: 
                     50:        interrupt = GetInterruptDevice();
1.1.1.9 ! root       51: 
        !            52:        // 検索順
        !            53:        RegistINT(IntmapSPC,  "SPC",  GetSPCDevice());
        !            54:        RegistINT(IntmapFDC,  "FDC",  GetFDCDevice());
        !            55:        RegistINT(IntmapHDD,  "HDD",  NULL);
        !            56:        RegistINT(IntmapPRT,  "PRT",  NULL);
        !            57:        // FDD は4本を共有しているのでいろいろ特別扱い。
        !            58:        RegistINT(IntmapFDD0, "FDD0", gMainApp.FindObject<FDDDevice>(OBJ_FDD(0)));
        !            59:        RegistINT(IntmapFDD1, "FDD1", gMainApp.FindObject<FDDDevice>(OBJ_FDD(1)));
        !            60:        RegistINT(IntmapFDD2, "FDD2", gMainApp.FindObject<FDDDevice>(OBJ_FDD(2)));
        !            61:        RegistINT(IntmapFDD3, "FDD3", gMainApp.FindObject<FDDDevice>(OBJ_FDD(3)));
        !            62:        // 名前表示用
        !            63:        RegistINT(IntmapFDD,  "FDD",  NULL);
        !            64: 
        !            65:        // 表示順
        !            66:        disp_list = {
        !            67:                IntmapSPC,
        !            68:                IntmapFDC,
        !            69:                IntmapFDD,
        !            70:                IntmapHDD,
        !            71:                IntmapPRT,
        !            72:        };
1.1.1.7   root       73: 
                     74:        return true;
1.1       root       75: }
                     76: 
1.1.1.5   root       77: // リセット
1.1       root       78: void
1.1.1.5   root       79: PEDECDevice::ResetHard(bool poweron)
1.1       root       80: {
1.1.1.5   root       81:        inherited::ResetHard(poweron);
1.1.1.4   root       82: 
1.1.1.9 ! root       83:        intmap_enable = IntmapSPC;
        !            84:        ChangeInterrupt();
        !            85: 
1.1       root       86:        // XXX vector
                     87: }
                     88: 
1.1.1.9 ! root       89: busdata
1.1.1.2   root       90: PEDECDevice::Read(uint32 offset)
1.1       root       91: {
1.1.1.9 ! root       92:        busdata data;
        !            93: 
1.1.1.2   root       94:        switch (offset) {
1.1       root       95:         case 0:        // $E9C001 割り込みステータス
1.1.1.9 ! root       96:                data = GetStat();
        !            97:                break;
1.1       root       98: 
                     99:         case 1:        // $E9C003 割り込みベクタ
                    100:                // 書き込み専用
1.1.1.9 ! root      101:                data = 0xff;
        !           102:                break;
1.1       root      103: 
                    104:         default:
1.1.1.9 ! root      105:                data = 0xff;
        !           106:                break;
1.1       root      107:        }
1.1.1.9 ! root      108: 
        !           109:        // XXX wait?
        !           110:        return data;
1.1       root      111: }
                    112: 
1.1.1.9 ! root      113: busdata
1.1.1.2   root      114: PEDECDevice::Write(uint32 offset, uint32 data)
1.1       root      115: {
1.1.1.2   root      116:        switch (offset) {
1.1       root      117:         case 0:        // $E9C001 割り込みマスク
1.1.1.9 ! root      118:                intmap_enable = IntmapSPC;
        !           119:                intmap_enable |= (data & 0x08) ? IntmapHDD : 0;
        !           120:                intmap_enable |= (data & 0x04) ? IntmapFDC : 0;
        !           121:                intmap_enable |= (data & 0x02) ? IntmapFDD : 0;
        !           122:                intmap_enable |= (data & 0x01) ? IntmapPRT : 0;
1.1       root      123: 
1.1.1.6   root      124:                putlog(1, "Set Interrupt Mask HDD=%d FDC=%d FDD=%d PRT=%d",
1.1.1.9 ! root      125:                        ((intmap_enable & IntmapHDD) ? 1 : 0),
        !           126:                        ((intmap_enable & IntmapFDC) ? 1 : 0),
        !           127:                        ((intmap_enable & IntmapFDD) ? 1 : 0),
        !           128:                        ((intmap_enable & IntmapPRT) ? 1 : 0));
        !           129:                break;
1.1       root      130: 
                    131:         case 1:        // $E9C003 割り込みベクタ
                    132:                vector = data & 0xfc;
1.1.1.6   root      133:                putlog(1, "Set Interrupt Vector $%02x", vector);
1.1.1.9 ! root      134:                break;
1.1       root      135: 
                    136:         default:
1.1.1.9 ! root      137:                break;
1.1       root      138:        }
1.1.1.9 ! root      139: 
        !           140:        // XXX wait?
        !           141:        return 0;
1.1       root      142: }
                    143: 
1.1.1.9 ! root      144: busdata
1.1.1.2   root      145: PEDECDevice::Peek(uint32 offset)
1.1       root      146: {
1.1.1.2   root      147:        switch (offset) {
1.1       root      148:         case 0:
                    149:                return GetStat();
                    150: 
                    151:         case 1:
                    152:                // 書き込み専用
                    153:                return 0xff;
                    154: 
                    155:         default:
                    156:                return 0xff;
                    157:        }
                    158: }
                    159: 
1.1.1.4   root      160: void
                    161: PEDECDevice::MonitorUpdate(TextScreen& screen, uint intr_level, int y)
                    162: {
1.1.1.9 ! root      163:        for (uint32 map : disp_list) {
1.1.1.4   root      164:                int clz = __builtin_clz(map);
1.1.1.9 ! root      165:                screen.Puts(4, y, TA::OnOff(intmap_status & map), GetIntName(map));
        !           166:                if (intr_level >= 1 || (intmap_enable & map) == 0) {
1.1.1.8   root      167:                        screen.Puts(11, y, "Mask");
1.1.1.4   root      168:                }
1.1.1.9 ! root      169:                uint64 cnt = counter[clz];
        !           170:                if (__predict_false(map == IntmapFDD)) {
        !           171:                        // FDD は4つの和
        !           172:                        cnt += counter[clz + 1] + counter[clz + 2] + counter[clz + 3];
        !           173:                }
        !           174:                screen.Print(15, y, "%26s", format_number(cnt).c_str());
1.1.1.4   root      175:                y++;
                    176:        }
                    177: }
                    178: 
1.1       root      179: // 割り込みステータスレジスタの値を取得。
                    180: // (Peek からも呼ばれるので副作用を持たせてはいけない)
                    181: uint32
                    182: PEDECDevice::GetStat() const
                    183: {
                    184:        uint32 data = 0;
1.1.1.9 ! root      185:        data |= (intmap_status & IntmapFDC) ? 0x80 : 0;
        !           186:        data |= (intmap_status & IntmapFDD) ? 0x40 : 0;
        !           187:        data |= (intmap_status & IntmapPRT) ? 0x20 : 0;
        !           188:        data |= (intmap_status & IntmapHDD) ? 0x10 : 0;
        !           189:        data |= (intmap_enable & IntmapHDD) ? 0x08 : 0;
        !           190:        data |= (intmap_enable & IntmapFDC) ? 0x04 : 0;
        !           191:        data |= (intmap_enable & IntmapFDD) ? 0x02 : 0;
        !           192:        data |= (intmap_enable & IntmapPRT) ? 0x01 : 0;
1.1       root      193:        return data;
                    194: }
                    195: 
1.1.1.4   root      196: // 割り込み信号線の状態を変える
1.1       root      197: void
1.1.1.4   root      198: PEDECDevice::ChangeInterrupt()
1.1       root      199: {
1.1.1.4   root      200: #if 0 // こんなログ出したいかも
1.1       root      201:                // ログ表示のためだけ
1.1.1.9 ! root      202:                if ((intmap_enable & IntmapFDC)) {
1.1       root      203:                        putlog(1, "FDC からの割り込み要求");
                    204:                } else {
                    205:                        putlog(2, "FDC からの割り込み要求(マスク)");
                    206:                }
1.1.1.4   root      207: #endif
1.1       root      208: 
1.1.1.9 ! root      209:        uint32 stat = (intmap_status & intmap_enable);
1.1.1.7   root      210:        interrupt->ChangeINT(this, stat);
1.1       root      211: }
                    212: 
                    213: // 割り込みアクノリッジ
1.1.1.9 ! root      214: busdata
1.1       root      215: PEDECDevice::InterruptAcknowledge(int lv)
                    216: {
1.1.1.9 ! root      217:        uint32 stat = (intmap_status & intmap_enable);
1.1       root      218: 
                    219:        // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので
                    220:        // SPC を優先しておくのでいいだろう。
                    221:        if ((stat & IntmapSPC)) {
                    222:                // XXX PEDEC のベクタに影響されるか?
                    223:                return 0x6c;
                    224:        }
                    225: 
                    226:        if ((stat & IntmapFDC)) {
                    227:                return vector + 0;
1.1.1.6   root      228:        } else if ((stat & IntmapFDD)) {
                    229:                return vector + 1;
1.1       root      230:        } else {
1.1.1.9 ! root      231:                return busdata::BusErr;
1.1.1.6   root      232:        }
1.1.1.4   root      233: }

unix.superglobalmegacorp.com

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