|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2017 [email protected] ! 4: // ! 5: ! 6: #include "crtc.h" ! 7: #include "mfp.h" ! 8: #include "renderer.h" ! 9: #include "tvram.h" ! 10: ! 11: CRTCDevice::CRTCDevice() ! 12: { ! 13: logname = "crtc"; ! 14: devname = "CRTC"; ! 15: devaddr = 0xe80000; ! 16: devlen = 0x2000; ! 17: ! 18: vdisp_event.dev = this; ! 19: vdisp_event.func = (DeviceCallback_t)&CRTCDevice::VDispCallback; ! 20: vdisp_event.name = "CRTC V-DISP"; ! 21: } ! 22: ! 23: CRTCDevice::~CRTCDevice() ! 24: { ! 25: } ! 26: ! 27: void ! 28: CRTCDevice::ResetHard() ! 29: { ! 30: // XXX 初期値適当 ! 31: crtc.r[20] = 0x0016; ! 32: ! 33: // XXX 適当 ! 34: // すぐに垂直帰線期間を開始する ! 35: vdisp_event.time = 0; ! 36: vdisp_event.code = 1; ! 37: gScheduler->AddEvent(&vdisp_event); ! 38: } ! 39: ! 40: uint64 ! 41: CRTCDevice::Read8(uint32 addr) ! 42: { ! 43: uint32 an = (addr - devaddr) / 2; ! 44: uint16 data; ! 45: ! 46: switch (an) { ! 47: case CRTC::R00 ... CRTC::R23: ! 48: data = crtc.r[an]; ! 49: if ((addr & 1) == 0) { ! 50: data >>= 8; ! 51: putlog(2, "R%02d(H) -> $%02x", an, data); ! 52: } else { ! 53: data &= 0xff; ! 54: putlog(2, "R%02d(L) -> $%02x", an, data); ! 55: } ! 56: break; ! 57: ! 58: case CRTC::REG_OP: // $E80480 ! 59: data = crtc.op; ! 60: if ((addr & 1) == 0) { ! 61: data >>= 8; ! 62: putlog(2, "$E80480 -> $%02x", data); ! 63: } else { ! 64: data &= 0xff; ! 65: putlog(2, "$E80481 -> $%02x", data); ! 66: } ! 67: break; ! 68: ! 69: default: ! 70: putlog(1, "Read8 $%06x 未実装ポート読み込み", addr); ! 71: data = 0xff; ! 72: } ! 73: ! 74: return data; ! 75: } ! 76: ! 77: uint64 ! 78: CRTCDevice::Read16(uint32 addr) ! 79: { ! 80: uint32 an = (addr - devaddr) / 2; ! 81: uint16 data; ! 82: ! 83: switch (an) { ! 84: case CRTC::R00 ... CRTC::R23: ! 85: data = crtc.r[an]; ! 86: putlog(2, "R%02d -> $%04x", an, data); ! 87: return data; ! 88: ! 89: default: ! 90: putlog(1, "$%06x 未実装読み込み", addr); ! 91: return 0; ! 92: } ! 93: } ! 94: ! 95: uint64 ! 96: CRTCDevice::Write8(uint32 addr, uint32 data) ! 97: { ! 98: uint32 an = (addr - devaddr) / 2; ! 99: ! 100: switch (an) { ! 101: case CRTC::R00 ... CRTC::R23: ! 102: // 16ビットにしてから書き込む ! 103: if((addr & 1) == 0) { ! 104: data = (data << 8) | (crtc.r[an] & 0x00ff); ! 105: putlog(2, "R%02d(H) = $%04x", an, data); ! 106: } else { ! 107: data = (data & 0xff) | (crtc.r[an] & 0xff00); ! 108: putlog(2, "R%02d(L) = $%04x", an, data); ! 109: } ! 110: WriteReg(an, data); ! 111: break; ! 112: ! 113: case CRTC::REG_OP: ! 114: // 下位8ビットのみ有効 ! 115: if ((addr & 1) == 1) { ! 116: putlog(2, "$E80481 <- $%02x", data); ! 117: crtc.op = data & 0x0b; ! 118: } ! 119: break; ! 120: ! 121: default: ! 122: putlog(1, "Write8 $%06x <- $%02x 未実装書き込み", addr, data); ! 123: break; ! 124: } ! 125: return 0; ! 126: } ! 127: ! 128: uint64 ! 129: CRTCDevice::Write16(uint32 addr, uint32 data) ! 130: { ! 131: uint32 an = (addr - devaddr) / 2; ! 132: ! 133: switch (an) { ! 134: case CRTC::R00 ... CRTC::R23: ! 135: putlog(2, "R%02d <- $%04x", an, data); ! 136: WriteReg(an, data); ! 137: break; ! 138: ! 139: case CRTC::REG_OP: ! 140: putlog(2, "$E80481 <- $%02x", data); ! 141: crtc.op = data & 0x0b; ! 142: break; ! 143: ! 144: default: ! 145: putlog(1, "$%06x <- $%04x 未実装書き込み", addr, data); ! 146: break; ! 147: } ! 148: return 0; ! 149: } ! 150: ! 151: // Write8/16 の下請け。内部アクセス用 ! 152: // offset は CRTC::R00 .. CRTC::R23 ! 153: void ! 154: CRTCDevice::WriteReg(uint32 reg, uint32 data) ! 155: { ! 156: crtc.r[reg] = data; ! 157: ! 158: switch (reg) { ! 159: case CRTC::R21: ! 160: gTVRAM->set_crtc_21(crtc.r[21]); ! 161: break; ! 162: } ! 163: } ! 164: ! 165: uint64 ! 166: CRTCDevice::Peek8(uint32 addr) ! 167: { ! 168: uint32 an2 = addr - devaddr; ! 169: ! 170: switch (an2) { ! 171: case CRTC::R00 ... (CRTC::R23 * 2): ! 172: if ((an2 & 1) == 0) { ! 173: return crtc.r[an2 / 2] >> 8; ! 174: } else { ! 175: return crtc.r[an2 / 2] & 0xff; ! 176: } ! 177: break; ! 178: ! 179: case CRTC::REG_OP * 2 + 1: ! 180: return crtc.op; ! 181: ! 182: default: ! 183: return 0xff; ! 184: } ! 185: } ! 186: ! 187: // 垂直表示・帰線イベント ! 188: // arg == 1 なら表示期間開始、arg == 0 なら帰線期間開始。 ! 189: void ! 190: CRTCDevice::VDispCallback(int arg) ! 191: { ! 192: // GPIP の状態を更新 ! 193: gMFP->SetVDisp(arg); ! 194: ! 195: // 今はここで1画面まるごと作成 ! 196: if (arg) { ! 197: // Render に作画指示 ! 198: gRenderer->Render(); ! 199: } ! 200: ! 201: // 次のタイミングを計算 ! 202: // XXX まだ CRTC から計算していない ! 203: if (arg) { ! 204: // 垂直表示期間 ! 205: vdisp_event.time = 16250_usec; ! 206: } else { ! 207: // 垂直帰線期間 ! 208: vdisp_event.time = 1778_usec; ! 209: } ! 210: vdisp_event.code = 1 - arg; ! 211: gScheduler->AddEvent(&vdisp_event); ! 212: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.