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