|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.