|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2017 [email protected] ! 4: // ! 5: ! 6: #include "scc.h" ! 7: #include "mpu.h" ! 8: ! 9: // IODevice ! 10: // | ! 11: // v ! 12: // upd7201Device (uPD7201 と Z8530 の共通部分) ! 13: // | ! 14: // +---------+----------+ ! 15: // v v ! 16: // SIODevice SCCDevice ! 17: // (LUNA, uPD7201) (X68030, Z8530) ! 18: ! 19: SCCDevice::SCCDevice() ! 20: { ! 21: logname = "scc"; ! 22: devname = "SCC"; ! 23: devaddr = baseaddr; ! 24: devlen = 0x2000; ! 25: } ! 26: ! 27: SCCDevice::~SCCDevice() ! 28: { ! 29: } ! 30: ! 31: // Z8530 は RD と WR を同時に Low にするとリセットがかかる。 ! 32: // 回路図からは PEDEC から繋がってるという以上のことは分からないけど ! 33: // 普通に考えればハードリセットでリセットされるよな。 ! 34: void ! 35: SCCDevice::ResetHard() ! 36: { ! 37: Reset(); ! 38: } ! 39: ! 40: uint64 ! 41: SCCDevice::Read8(uint32 addr) ! 42: { ! 43: uint32 an = addr - devaddr; ! 44: ! 45: switch (an) { ! 46: case 1: // $E98001 ! 47: return ReadCtrl(&cr.chan[1]); ! 48: ! 49: case 3: // $E98003 ! 50: // マウス非接続は 0x00 ? ! 51: putlog(0, "ChB データレジスタ読み込み (未実装)"); ! 52: return 0x00; ! 53: ! 54: case 5: // $E98005 ! 55: return ReadCtrl(&cr.chan[0]); ! 56: ! 57: case 7: // $E98007 ! 58: putlog(0, "ChA データレジスタ読み込み (未実装)"); ! 59: return ReadData(0); ! 60: ! 61: default: ! 62: break; ! 63: } ! 64: putlog(0, "未実装レジスタ読み込み"); ! 65: return (uint64)-1; ! 66: } ! 67: ! 68: uint64 ! 69: SCCDevice::Read16(uint32 addr) ! 70: { ! 71: return 0xff00 | Read8(addr + 1); ! 72: } ! 73: ! 74: uint64 ! 75: SCCDevice::Write8(uint32 addr, uint32 data) ! 76: { ! 77: uint32 an = addr - devaddr; ! 78: ! 79: switch (an) { ! 80: case 1: // $E98001 ! 81: WriteCtrl(&cr.chan[1], data); ! 82: return 0; ! 83: ! 84: case 3: // $E98003 ! 85: WriteData(&cr.chan[1], data); ! 86: return 0; ! 87: ! 88: case 5: // $E98005 ! 89: WriteCtrl(&cr.chan[0], data); ! 90: return 0; ! 91: ! 92: case 7: // $E98007 ! 93: WriteData(&cr.chan[0], data); ! 94: return 0; ! 95: ! 96: default: ! 97: break; ! 98: } ! 99: putlog(0, "未実装レジスタ書き込み"); ! 100: return (uint64)-1; ! 101: } ! 102: ! 103: uint64 ! 104: SCCDevice::Write16(uint32 addr, uint32 data) ! 105: { ! 106: return Write8(addr + 1, data); ! 107: } ! 108: ! 109: uint64 ! 110: SCCDevice::Peek8(uint32 addr) ! 111: { ! 112: // XXX ! 113: return 0xff; ! 114: } ! 115: ! 116: // Z8530 制御ポート読み込み ! 117: uint8 ! 118: SCCDevice::ReadCtrl(struct SIO::channel *chan) ! 119: { ! 120: return inherited::ReadCtrl(chan); ! 121: } ! 122: ! 123: // Z8530 制御ポート書き込み ! 124: void ! 125: SCCDevice::WriteCtrl(struct SIO::channel *chan, uint32 data) ! 126: { ! 127: switch (chan->ptr) { ! 128: case 0: // WR0 ! 129: chan->cr0 = data; ! 130: ! 131: switch ((chan->cr0 & SIO::WR0_CMD) >> 3) { ! 132: case 0: ! 133: case 1: ! 134: // コマンド 0、1 がレジスタ切り替え ! 135: chan->ptr = chan->cr0 & SIO::WR0_PTR; ! 136: putlog(3, "WR0%s <- $%02x (ptr=%d)", chan->name, data, chan->ptr); ! 137: break; ! 138: ! 139: case 2: // Reset Ext/Status Interrupts ! 140: putlog(0, "WR0 Reset Ext/Status Interrupts 未実装"); ! 141: break; ! 142: case 3: // Send Abort ! 143: putlog(0, "WR0 Send Abort 未実装"); ! 144: break; ! 145: case 4: // Enable Int on Next Rx Character ! 146: putlog(0, "WR0 Enable Int on Next Rx Character 未実装"); ! 147: break; ! 148: case 5: // Reset Tx Int Pending ! 149: putlog(0, "WR0 Reset Tx Int Pending 未実装"); ! 150: break; ! 151: case 6: // Error Reset ! 152: putlog(0, "WR0 Error Reset 未実装"); ! 153: break; ! 154: case 7: // Reset Highest IUS ! 155: putlog(0, "WR0 Reset Highest IUS"); ! 156: break; ! 157: } ! 158: break; ! 159: ! 160: case 2: // WR2 ! 161: // Z8530 の WR2 は A/B 共通でベクタ設定 ! 162: putlog(2, "WR2 <- $%02x ベクタ設定", data); ! 163: cr.vector = data; ! 164: // アクセス後は WR0 へ戻す ! 165: chan->ptr = 0; ! 166: break; ! 167: ! 168: case 1: // WR1 ! 169: case 3: ! 170: case 4: ! 171: case 5: ! 172: case 6: ! 173: case 7: ! 174: inherited::WriteCtrl(chan, data); ! 175: break; ! 176: ! 177: case 8: // WR8 ! 178: WriteData(chan, data); ! 179: // アクセス後は WR0 へ戻す ! 180: chan->ptr = 0; ! 181: break; ! 182: ! 183: case 9: // WR9 ! 184: putlog(2, "WR%d%s <- $%02x", chan->ptr, chan->name, data); ! 185: switch ((data & 0xc0) >> 6) { ! 186: case 0: // No Reset ! 187: break; ! 188: case 1: // Channel Reset A ! 189: ResetChannel(&cr.chan[0]); ! 190: break; ! 191: case 2: // Channel Reset B ! 192: ResetChannel(&cr.chan[1]); ! 193: break; ! 194: case 3: // Force Hardware Reset ! 195: Reset(); ! 196: break; ! 197: default: ! 198: __unreachable(); ! 199: } ! 200: // アクセス後は WR0 へ戻す ! 201: chan->ptr = 0; ! 202: break; ! 203: ! 204: case 11: // WR11 ! 205: putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data); ! 206: chan->wr11 = data; ! 207: // アクセス後は WR0 へ戻す ! 208: chan->ptr = 0; ! 209: break; ! 210: ! 211: case 12: // WR12 ! 212: chan->tc = (chan->tc & 0xff00) | data; ! 213: putlog(2, "WR%d%s TC(L)=%04x", chan->ptr, chan->name, chan->tc); ! 214: // アクセス後は WR0 へ戻す ! 215: chan->ptr = 0; ! 216: break; ! 217: ! 218: case 13: // WR13 ! 219: chan->tc = (chan->tc & 0x00ff) | (data << 8); ! 220: putlog(2, "WR%d%s TC(H)=%04x", chan->ptr, chan->name, chan->tc); ! 221: // アクセス後は WR0 へ戻す ! 222: chan->ptr = 0; ! 223: break; ! 224: ! 225: case 14: // WR14 ! 226: putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data); ! 227: chan->wr14 = data; ! 228: // アクセス後は WR0 へ戻す ! 229: chan->ptr = 0; ! 230: break; ! 231: ! 232: case 15: // WR15 ! 233: putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data); ! 234: chan->wr15 = data; ! 235: // アクセス後は WR0 へ戻す ! 236: chan->ptr = 0; ! 237: break; ! 238: ! 239: default: ! 240: PANIC("未実装レジスタ書き込み WR%d%s <- $%02x", ! 241: chan->ptr, chan->name, data); ! 242: break; ! 243: } ! 244: } ! 245: ! 246: // 割り込みを上げる ! 247: void ! 248: SCCDevice::Interrupt() ! 249: { ! 250: putlog(0, "割り込み(未実装)"); ! 251: gMPU->Interrupt(5, 0x50/*XXX*/); ! 252: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.