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

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()
        !            14: {
        !            15:        logname = "pedec";
        !            16:        devname = "PEDEC";
        !            17:        devaddr = baseaddr;
        !            18:        devlen  = 0x2000;
        !            19: }
        !            20: 
        !            21: PEDECDevice::~PEDECDevice()
        !            22: {
        !            23: }
        !            24: 
        !            25: void
        !            26: PEDECDevice::ResetHard()
        !            27: {
        !            28:        int_asserted = 0;
        !            29:        int_enabled = IntmapSPC;
        !            30:        // XXX vector
        !            31: }
        !            32: 
        !            33: uint64
        !            34: PEDECDevice::Read(uint32 addr)
        !            35: {
        !            36:        switch (addr) {
        !            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
        !            50: PEDECDevice::Write(uint32 addr, uint32 data)
        !            51: {
        !            52:        switch (addr) {
        !            53:         case 0:        // $E9C001 割り込みマスク
        !            54:                int_enabled = IntmapSPC;
        !            55:                int_enabled |= (data & 0x08) ? IntmapHDD : 0;
        !            56:                int_enabled |= (data & 0x04) ? IntmapFDC : 0;
        !            57:                int_enabled |= (data & 0x02) ? IntmapFDD : 0;
        !            58:                int_enabled |= (data & 0x01) ? IntmapPRT : 0;
        !            59: 
        !            60:                putlog(1, "割り込みマスク設定 HDD=%d FDC=%d FDD=%d PRT=%d",
        !            61:                        ((int_enabled & IntmapHDD) ? 1 : 0),
        !            62:                        ((int_enabled & IntmapFDC) ? 1 : 0),
        !            63:                        ((int_enabled & IntmapFDD) ? 1 : 0),
        !            64:                        ((int_enabled & IntmapPRT) ? 1 : 0));
        !            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
        !            78: PEDECDevice::Peek(uint32 addr)
        !            79: {
        !            80:        switch (addr) {
        !            81:         case 0:
        !            82:                return GetStat();
        !            83: 
        !            84:         case 1:
        !            85:                // 書き込み専用
        !            86:                return 0xff;
        !            87: 
        !            88:         default:
        !            89:                return 0xff;
        !            90:        }
        !            91: }
        !            92: 
        !            93: // 割り込みステータスレジスタの値を取得。
        !            94: // (Peek からも呼ばれるので副作用を持たせてはいけない)
        !            95: uint32
        !            96: PEDECDevice::GetStat() const
        !            97: {
        !            98:        uint32 data = 0;
        !            99:        data |= (int_asserted & IntmapFDC) ? 0x80 : 0;
        !           100:        data |= (int_asserted & IntmapFDD) ? 0x40 : 0;
        !           101:        data |= (int_asserted & IntmapPRT) ? 0x20 : 0;
        !           102:        data |= (int_asserted & IntmapHDD) ? 0x10 : 0;
        !           103:        data |= (int_enabled  & IntmapHDD) ? 0x08 : 0;
        !           104:        data |= (int_enabled  & IntmapFDC) ? 0x04 : 0;
        !           105:        data |= (int_enabled  & IntmapFDD) ? 0x02 : 0;
        !           106:        data |= (int_enabled  & IntmapPRT) ? 0x01 : 0;
        !           107:        return data;
        !           108: }
        !           109: 
        !           110: // 子デバイスが割り込み信号線をアサートした
        !           111: void
        !           112: PEDECDevice::AssertINT(Device *source)
        !           113: {
        !           114:        if (__predict_true(source == gSPC.get())) {
        !           115:                int_asserted |= IntmapSPC;
        !           116: 
        !           117:        } else if (__predict_true(source == gFDC.get())) {
        !           118:                int_asserted |= IntmapFDC;
        !           119:                // ログ表示のためだけ
        !           120:                if ((int_enabled & IntmapFDC)) {
        !           121:                        putlog(1, "FDC からの割り込み要求");
        !           122:                } else {
        !           123:                        putlog(2, "FDC からの割り込み要求(マスク)");
        !           124:                }
        !           125: 
        !           126:        } else {
        !           127:                PANIC("Unknown interrupt source");
        !           128:        }
        !           129: 
        !           130:        ChangeInterrupt();
        !           131: }
        !           132: 
        !           133: // 子デバイスが割り込み信号線をネゲートした
        !           134: void
        !           135: PEDECDevice::NegateINT(Device *source)
        !           136: {
        !           137:        if (__predict_true(source == gSPC.get())) {
        !           138:                int_asserted &= ~IntmapSPC;
        !           139:        } else if (__predict_true(source == gFDC.get())) {
        !           140:                int_asserted &= ~IntmapFDC;
        !           141:        } else {
        !           142:                PANIC("Unknown interrupt source");
        !           143:        }
        !           144: 
        !           145:        ChangeInterrupt();
        !           146: }
        !           147: 
        !           148: // 割り込み信号線の状態を変える
        !           149: void
        !           150: PEDECDevice::ChangeInterrupt()
        !           151: {
        !           152:        uint32 stat = (int_asserted & int_enabled);
        !           153:        gInterrupt->ChangeINT(this, stat);
        !           154: }
        !           155: 
        !           156: // 割り込みアクノリッジ
        !           157: int
        !           158: PEDECDevice::InterruptAcknowledge(int lv)
        !           159: {
        !           160:        uint32 stat = (int_asserted & int_enabled);
        !           161: 
        !           162:        // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので
        !           163:        // SPC を優先しておくのでいいだろう。
        !           164:        if ((stat & IntmapSPC)) {
        !           165:                // XXX PEDEC のベクタに影響されるか?
        !           166:                return 0x6c;
        !           167:        }
        !           168: 
        !           169:        if ((stat & IntmapFDC)) {
        !           170:                return vector + 0;
        !           171:        } else {
        !           172:                PANIC("Unknown interrupt acknowledge");
        !           173:        }
        !           174: }

unix.superglobalmegacorp.com

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