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

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: //          |
                     24: //          +-- SysCtlrDevice  (LUNA88K の割り込みコントローラ)
                     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: // グローバル参照用
                     32: PEDECDevice *gPEDEC;
1.1       root       33: 
1.1.1.5   root       34: // コンストラクタ
1.1       root       35: PEDECDevice::PEDECDevice()
1.1.1.3   root       36:        : inherited("PEDEC")
1.1       root       37: {
                     38:        devaddr = baseaddr;
                     39:        devlen  = 0x2000;
                     40: }
                     41: 
1.1.1.5   root       42: // デストラクタ
1.1       root       43: PEDECDevice::~PEDECDevice()
                     44: {
1.1.1.5   root       45:        gPEDEC = NULL;
1.1       root       46: }
                     47: 
1.1.1.5   root       48: // リセット
1.1       root       49: void
1.1.1.5   root       50: PEDECDevice::ResetHard(bool poweron)
1.1       root       51: {
1.1.1.5   root       52:        inherited::ResetHard(poweron);
1.1.1.4   root       53: 
                     54:        intmap_enabled = IntmapSPC;
1.1       root       55:        // XXX vector
                     56: }
                     57: 
                     58: uint64
1.1.1.2   root       59: PEDECDevice::Read(uint32 offset)
1.1       root       60: {
1.1.1.2   root       61:        switch (offset) {
1.1       root       62:         case 0:        // $E9C001 割り込みステータス
                     63:                return GetStat();
                     64: 
                     65:         case 1:        // $E9C003 割り込みベクタ
                     66:                // 書き込み専用
                     67:                return 0xff;
                     68: 
                     69:         default:
                     70:                return 0xff;
                     71:        }
                     72: }
                     73: 
                     74: uint64
1.1.1.2   root       75: PEDECDevice::Write(uint32 offset, uint32 data)
1.1       root       76: {
1.1.1.2   root       77:        switch (offset) {
1.1       root       78:         case 0:        // $E9C001 割り込みマスク
1.1.1.4   root       79:                intmap_enabled = IntmapSPC;
                     80:                intmap_enabled |= (data & 0x08) ? IntmapHDD : 0;
                     81:                intmap_enabled |= (data & 0x04) ? IntmapFDC : 0;
                     82:                intmap_enabled |= (data & 0x02) ? IntmapFDD : 0;
                     83:                intmap_enabled |= (data & 0x01) ? IntmapPRT : 0;
1.1       root       84: 
1.1.1.6 ! root       85:                putlog(1, "Set Interrupt Mask HDD=%d FDC=%d FDD=%d PRT=%d",
1.1.1.4   root       86:                        ((intmap_enabled & IntmapHDD) ? 1 : 0),
                     87:                        ((intmap_enabled & IntmapFDC) ? 1 : 0),
                     88:                        ((intmap_enabled & IntmapFDD) ? 1 : 0),
                     89:                        ((intmap_enabled & IntmapPRT) ? 1 : 0));
1.1       root       90:                return 0;
                     91: 
                     92:         case 1:        // $E9C003 割り込みベクタ
                     93:                vector = data & 0xfc;
1.1.1.6 ! root       94:                putlog(1, "Set Interrupt Vector $%02x", vector);
1.1       root       95:                return 0;
                     96: 
                     97:         default:
                     98:                return 0;
                     99:        }
                    100: }
                    101: 
                    102: uint64
1.1.1.2   root      103: PEDECDevice::Peek(uint32 offset)
1.1       root      104: {
1.1.1.2   root      105:        switch (offset) {
1.1       root      106:         case 0:
                    107:                return GetStat();
                    108: 
                    109:         case 1:
                    110:                // 書き込み専用
                    111:                return 0xff;
                    112: 
                    113:         default:
                    114:                return 0xff;
                    115:        }
                    116: }
                    117: 
1.1.1.4   root      118: void
                    119: PEDECDevice::MonitorUpdate(TextScreen& screen, uint intr_level, int y)
                    120: {
                    121:        struct {
                    122:                const char *name;
                    123:                uint32 map;
                    124:        } table[] = {
                    125:                { "SPC",        IntmapSPC },
                    126:                { "FDC",        IntmapFDC },
                    127:                { "FDD",        IntmapFDD },
                    128:                { "HDD",        IntmapHDD },
                    129:                { "PRT",        IntmapPRT },
                    130:        };
                    131: 
                    132:        for (int i = 0; i < countof(table); i++) {
                    133:                uint32 map = table[i].map;
                    134:                int clz = __builtin_clz(map);
                    135:                screen.Puts(3, y, TA::OnOff(intmap & map), table[i].name);
                    136:                screen.Print(8, y, "%11" PRIu64, counter[clz]);
                    137: 
                    138:                if (intr_level >= 1 || (intmap_enabled & map) == 0) {
                    139:                        screen.Puts(21, y, "Mask");
                    140:                }
                    141:                y++;
                    142:        }
                    143: }
                    144: 
1.1       root      145: // 割り込みステータスレジスタの値を取得。
                    146: // (Peek からも呼ばれるので副作用を持たせてはいけない)
                    147: uint32
                    148: PEDECDevice::GetStat() const
                    149: {
                    150:        uint32 data = 0;
1.1.1.4   root      151:        data |= (intmap & IntmapFDC) ? 0x80 : 0;
                    152:        data |= (intmap & IntmapFDD) ? 0x40 : 0;
                    153:        data |= (intmap & IntmapPRT) ? 0x20 : 0;
                    154:        data |= (intmap & IntmapHDD) ? 0x10 : 0;
                    155:        data |= (intmap_enabled & IntmapHDD) ? 0x08 : 0;
                    156:        data |= (intmap_enabled & IntmapFDC) ? 0x04 : 0;
                    157:        data |= (intmap_enabled & IntmapFDD) ? 0x02 : 0;
                    158:        data |= (intmap_enabled & IntmapPRT) ? 0x01 : 0;
1.1       root      159:        return data;
                    160: }
                    161: 
1.1.1.4   root      162: // 割り込み信号線の状態を変える
1.1       root      163: void
1.1.1.4   root      164: PEDECDevice::ChangeInterrupt()
1.1       root      165: {
1.1.1.4   root      166: #if 0 // こんなログ出したいかも
1.1       root      167:                // ログ表示のためだけ
1.1.1.4   root      168:                if ((intmap_enabled & IntmapFDC)) {
1.1       root      169:                        putlog(1, "FDC からの割り込み要求");
                    170:                } else {
                    171:                        putlog(2, "FDC からの割り込み要求(マスク)");
                    172:                }
1.1.1.4   root      173: #endif
1.1       root      174: 
1.1.1.4   root      175:        uint32 stat = (intmap & intmap_enabled);
1.1       root      176:        gInterrupt->ChangeINT(this, stat);
                    177: }
                    178: 
                    179: // 割り込みアクノリッジ
                    180: int
                    181: PEDECDevice::InterruptAcknowledge(int lv)
                    182: {
1.1.1.4   root      183:        uint32 stat = (intmap & intmap_enabled);
1.1       root      184: 
                    185:        // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので
                    186:        // SPC を優先しておくのでいいだろう。
                    187:        if ((stat & IntmapSPC)) {
                    188:                // XXX PEDEC のベクタに影響されるか?
                    189:                return 0x6c;
                    190:        }
                    191: 
                    192:        if ((stat & IntmapFDC)) {
                    193:                return vector + 0;
1.1.1.6 ! root      194:        } else if ((stat & IntmapFDD)) {
        !           195:                return vector + 1;
1.1       root      196:        } else {
1.1.1.5   root      197:                VMPANIC("Unknown interrupt acknowledge");
1.1       root      198:        }
                    199: }
1.1.1.4   root      200: 
                    201: // デバイスから Intmap 値を引く
                    202: uint32
                    203: PEDECDevice::GetIntmap(Device *source) const
                    204: {
1.1.1.5   root      205:        if (__predict_true(source == gSPC)) {
1.1.1.4   root      206:                return IntmapSPC;
                    207:        }
1.1.1.5   root      208:        if (__predict_true(source == gFDC)) {
1.1.1.4   root      209:                return IntmapFDC;
                    210:        }
1.1.1.6 ! root      211:        if (dynamic_cast<FDDDevice*>(source)) {
        !           212:                return IntmapFDD;
        !           213:        }
1.1.1.5   root      214:        VMPANIC("Unsupported interrupt device");
1.1.1.4   root      215: }

unix.superglobalmegacorp.com

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