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

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

unix.superglobalmegacorp.com

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