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

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.10! root       90: PEDECDevice::ReadPort(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?
1.1.1.10! root      110:        data |= BusData::Size1;
1.1.1.9   root      111:        return data;
1.1       root      112: }
                    113: 
1.1.1.9   root      114: busdata
1.1.1.10! root      115: PEDECDevice::WritePort(uint32 offset, uint32 data)
1.1       root      116: {
1.1.1.2   root      117:        switch (offset) {
1.1       root      118:         case 0:        // $E9C001 割り込みマスク
1.1.1.9   root      119:                intmap_enable = IntmapSPC;
                    120:                intmap_enable |= (data & 0x08) ? IntmapHDD : 0;
                    121:                intmap_enable |= (data & 0x04) ? IntmapFDC : 0;
                    122:                intmap_enable |= (data & 0x02) ? IntmapFDD : 0;
                    123:                intmap_enable |= (data & 0x01) ? IntmapPRT : 0;
1.1       root      124: 
1.1.1.10! root      125:                putlog(1, "Set Interrupt Mask HDD=%u FDC=%u FDD=%u PRT=%u",
1.1.1.9   root      126:                        ((intmap_enable & IntmapHDD) ? 1 : 0),
                    127:                        ((intmap_enable & IntmapFDC) ? 1 : 0),
                    128:                        ((intmap_enable & IntmapFDD) ? 1 : 0),
                    129:                        ((intmap_enable & IntmapPRT) ? 1 : 0));
                    130:                break;
1.1       root      131: 
                    132:         case 1:        // $E9C003 割り込みベクタ
                    133:                vector = data & 0xfc;
1.1.1.6   root      134:                putlog(1, "Set Interrupt Vector $%02x", vector);
1.1.1.9   root      135:                break;
1.1       root      136: 
                    137:         default:
1.1.1.9   root      138:                break;
1.1       root      139:        }
1.1.1.9   root      140: 
                    141:        // XXX wait?
1.1.1.10! root      142:        busdata r = BusData::Size1;
        !           143:        return r;
1.1       root      144: }
                    145: 
1.1.1.9   root      146: busdata
1.1.1.10! root      147: PEDECDevice::PeekPort(uint32 offset)
1.1       root      148: {
1.1.1.2   root      149:        switch (offset) {
1.1       root      150:         case 0:
                    151:                return GetStat();
                    152: 
                    153:         case 1:
                    154:                // 書き込み専用
                    155:                return 0xff;
                    156: 
                    157:         default:
                    158:                return 0xff;
                    159:        }
                    160: }
                    161: 
1.1.1.10! root      162: bool
        !           163: PEDECDevice::PokePort(uint32 offset, uint32 data)
        !           164: {
        !           165:        return false;
        !           166: }
        !           167: 
1.1.1.4   root      168: void
                    169: PEDECDevice::MonitorUpdate(TextScreen& screen, uint intr_level, int y)
                    170: {
1.1.1.9   root      171:        for (uint32 map : disp_list) {
1.1.1.4   root      172:                int clz = __builtin_clz(map);
1.1.1.9   root      173:                screen.Puts(4, y, TA::OnOff(intmap_status & map), GetIntName(map));
                    174:                if (intr_level >= 1 || (intmap_enable & map) == 0) {
1.1.1.8   root      175:                        screen.Puts(11, y, "Mask");
1.1.1.4   root      176:                }
1.1.1.9   root      177:                uint64 cnt = counter[clz];
                    178:                if (__predict_false(map == IntmapFDD)) {
                    179:                        // FDD は4つの和
                    180:                        cnt += counter[clz + 1] + counter[clz + 2] + counter[clz + 3];
                    181:                }
                    182:                screen.Print(15, y, "%26s", format_number(cnt).c_str());
1.1.1.4   root      183:                y++;
                    184:        }
                    185: }
                    186: 
1.1       root      187: // 割り込みステータスレジスタの値を取得。
                    188: // (Peek からも呼ばれるので副作用を持たせてはいけない)
                    189: uint32
                    190: PEDECDevice::GetStat() const
                    191: {
                    192:        uint32 data = 0;
1.1.1.9   root      193:        data |= (intmap_status & IntmapFDC) ? 0x80 : 0;
                    194:        data |= (intmap_status & IntmapFDD) ? 0x40 : 0;
                    195:        data |= (intmap_status & IntmapPRT) ? 0x20 : 0;
                    196:        data |= (intmap_status & IntmapHDD) ? 0x10 : 0;
                    197:        data |= (intmap_enable & IntmapHDD) ? 0x08 : 0;
                    198:        data |= (intmap_enable & IntmapFDC) ? 0x04 : 0;
                    199:        data |= (intmap_enable & IntmapFDD) ? 0x02 : 0;
                    200:        data |= (intmap_enable & IntmapPRT) ? 0x01 : 0;
1.1       root      201:        return data;
                    202: }
                    203: 
1.1.1.4   root      204: // 割り込み信号線の状態を変える
1.1       root      205: void
1.1.1.4   root      206: PEDECDevice::ChangeInterrupt()
1.1       root      207: {
1.1.1.4   root      208: #if 0 // こんなログ出したいかも
1.1       root      209:                // ログ表示のためだけ
1.1.1.9   root      210:                if ((intmap_enable & IntmapFDC)) {
1.1       root      211:                        putlog(1, "FDC からの割り込み要求");
                    212:                } else {
                    213:                        putlog(2, "FDC からの割り込み要求(マスク)");
                    214:                }
1.1.1.4   root      215: #endif
1.1       root      216: 
1.1.1.9   root      217:        uint32 stat = (intmap_status & intmap_enable);
1.1.1.7   root      218:        interrupt->ChangeINT(this, stat);
1.1       root      219: }
                    220: 
                    221: // 割り込みアクノリッジ
1.1.1.9   root      222: busdata
1.1       root      223: PEDECDevice::InterruptAcknowledge(int lv)
                    224: {
1.1.1.9   root      225:        uint32 stat = (intmap_status & intmap_enable);
1.1       root      226: 
                    227:        // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので
                    228:        // SPC を優先しておくのでいいだろう。
                    229:        if ((stat & IntmapSPC)) {
                    230:                // XXX PEDEC のベクタに影響されるか?
                    231:                return 0x6c;
                    232:        }
                    233: 
                    234:        if ((stat & IntmapFDC)) {
                    235:                return vector + 0;
1.1.1.6   root      236:        } else if ((stat & IntmapFDD)) {
                    237:                return vector + 1;
1.1       root      238:        } else {
1.1.1.10! root      239:                return BusData::BusErr;
1.1.1.6   root      240:        }
1.1.1.4   root      241: }

unix.superglobalmegacorp.com

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