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

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

unix.superglobalmegacorp.com

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