📄 unichrome.cc
字号:
name, i+1, sleepCycles); } Scheduler::sleepInterruptible("unichrome::Unichrome::wait", Util::currentTimeMillis()+sleepLength); } if (Scheduler::isInterrupted()) return false; Log::fatal("unichrome::Unichrome::wait(%s): timeout!\n", name); assert(0);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------bool Unichrome::isCommandRegulatorBusy(IO& io){ return (io.reg(Register::STATUS) & Constant::MASK_STATUS_CMD_REG_BUSY)!=0;}//------------------------------------------------------------------------------bool Unichrome::waitCommandRegulator(IO& io){ return wait(io, &isCommandRegulatorBusy, "command regulator", 1000, 5, 5);}//------------------------------------------------------------------------------bool Unichrome::isGraphicsEngineBusy(IO& io){ return (io.reg(Register::STATUS) & (Constant::MASK_STATUS_CMD_REG_BUSY | Constant::MASK_STATUS_2D_BUSY | Constant::MASK_STATUS_3D_BUSY) )!=0;}//------------------------------------------------------------------------------bool Unichrome::waitGraphicsEngine(IO& io){ return wait(io, &isGraphicsEngineBusy, "graphics engine", 1000, 5, 5);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------inline bool Unichrome::isHQVFlipping(){ uint32_t hqvControl = io.reg(Register::HQV_CONTROL); return (hqvControl & (Constant::HQV_SW_FLIP|Constant::HQV_SUBPIC_FLIP)) || !(hqvControl & Constant::HQV_FLIP_STATUS);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------Unichrome::Unichrome() : lastMemoryBlock(0), fifo(io), tvEncoder(TVEncoder::create(io)), flipperThread(FlipperThread::create()), currentMode(ModeInfo::get(0).getMode()), currentModeIndex(0), mpegDecoder(*this), useHQV(true), nextV1Buffer(0), v1FlipPending(false), spuOffset( (size_t)-1 ), spuWidth(0), spuHeight(0), frameBufferWindow(*this, 0, 720, 576){ setMode(currentMode); if (usingHWFlipping()) { flipperThread->start(); }}//------------------------------------------------------------------------------Unichrome::~Unichrome(){ delete flipperThread; delete tvEncoder;}//------------------------------------------------------------------------------size_t Unichrome::getMemorySize(){ return IO::FRAMEBUFFER_SIZE;}//------------------------------------------------------------------------------MemoryBlock* Unichrome::allocateMemoryBlock(size_t size){ size_t topOffset = (lastMemoryBlock==0) ? getMemorySize() : lastMemoryBlock->getOffset(); size = (size+15) & (~15); MemoryBlock* memoryBlock = new MemoryBlock(lastMemoryBlock, *this, topOffset - size, size); lastMemoryBlock = memoryBlock; return memoryBlock;}//------------------------------------------------------------------------------bool Unichrome::usingHWFlipping(){ return flipperThread!=0;}//------------------------------------------------------------------------------void Unichrome::stop(){ if (usingHWFlipping()) { flipperThread->stop(); }}//------------------------------------------------------------------------------void Unichrome::setMode(const Mode& mode){ const ModeInfo* modeInfo = ModeInfo::find(mode, currentModeIndex); if (modeInfo==0) { Log::fatal("unichrome::Unichrome::setMode: cannot find mode!\n"); return; } currentMode = mode; turnOffScreen(); for(size_t i = 0; i<ModeInfo::numSequencerRegisters; ++i) { io.sequencer.write(i+ModeInfo::sequencerRegisterOffset, modeInfo->sequenceRegisters[i]); } io.miscOutput.write8(modeInfo->miscRegister); unlockCRT(); setupCRT(modeInfo->horizontalCRT, modeInfo->verticalCRT); lockCRT(); for(size_t i = 0; i<ModeInfo::numAttributeRegisters; ++i) { io.attribute.write(i, modeInfo->attributeRegisters[i]); } for(size_t i = 0; i<ModeInfo::numGraphicsRegisters; ++i) { io.graphics.write(i, modeInfo->graphicsRegisters[i]); } unlockExtendedRegister(); io.sequencer.writeMasked(0x15, modeInfo->extModeRegister, 0xfe); setupIGA1(modeInfo->width, modeInfo->bpp); openScreen(); setVCLK(modeInfo->vclk); if (tvEncoder) { tvEncoder->setMode(mode); } setRegisters(); init2D(modeInfo->width, modeInfo->height, modeInfo->bpp); init3D(); setupV1(modeInfo->width, modeInfo->height, modeInfo->width, modeInfo->height, 0, 0, modeInfo->width, modeInfo->height); frameBufferWindow.setArea(0, 0, modeInfo->width, modeInfo->height);}//------------------------------------------------------------------------------void Unichrome::setAspectRatio(aspectRatio_t ar){ mpegDecoder.setAspectRatio(ar);}//------------------------------------------------------------------------------void Unichrome::getOutputSize(size_t& width, size_t& height){ const ModeInfo& modeInfo = ModeInfo::get(currentModeIndex); width = modeInfo.width; height = modeInfo.height;}//------------------------------------------------------------------------------volatile unsigned char* Unichrome::getFrameBuffer(){ return io.getFrameBuffer();}//------------------------------------------------------------------------------size_t Unichrome::getFrameBufferSize() const{ const ModeInfo& modeInfo = ModeInfo::get(currentModeIndex); size_t size = modeInfo.width; size *= modeInfo.height; size *= modeInfo.bpp/8; size += 7; size /= 8; size *= 8; return size;}//------------------------------------------------------------------------------void Unichrome::resetSourceBase(){ setSourceBase(0);}//------------------------------------------------------------------------------void Unichrome::setSourceBase(size_t offset){ uint32_t value = offset/8; if (value!=state.sourceBase) { fifo.prepare(4); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::SRCBASE, value); state.sourceBase = value; }}//------------------------------------------------------------------------------void Unichrome::resetDestinationBase(){ setDestinationBase(0);}//------------------------------------------------------------------------------void Unichrome::setDestinationBase(size_t offset){ uint32_t value = offset/8; if (value!=state.destinationBase) { fifo.prepare(4); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::DSTBASE, value); state.destinationBase = value; }}//------------------------------------------------------------------------------void Unichrome::setForeground(uint32_t color){ fifo.prepare(4); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::FGCOLOR, color);}//------------------------------------------------------------------------------void Unichrome::setBackground(uint32_t color){ if (state.bgColor!=color) { fifo.prepare(4); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::BGCOLOR, color); state.bgColor = color; }}//------------------------------------------------------------------------------void Unichrome::disableKeying(){ if (state.keyControl!=0) { fifo.prepare(4); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::KEYCONTROL, 0); state.keyControl = 0; }}//------------------------------------------------------------------------------void Unichrome::enableSourceKeying(bool invert){ uint32_t value = Constant::KEY_ENABLE_SRCKEY; if (invert) { value |= Constant::KEY_INVERT_KEY | Constant::KEY_MASK_RED | Constant::KEY_MASK_GREEN | Constant::KEY_MASK_BLUE; } if (state.keyControl!=value) { fifo.prepare(4); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::KEYCONTROL, value); state.keyControl = value; }}//------------------------------------------------------------------------------void Unichrome::setSourceKey(uint32_t color){ if (state.bgColor!=color) { fifo.prepare(4); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::SRCCOLORKEY, color); state.bgColor = color; }}//------------------------------------------------------------------------------void Unichrome::resetPitch(){ const ModeInfo& modeInfo = ModeInfo::get(currentModeIndex); setPitch(modeInfo.width * modeInfo.bpp/8, modeInfo.width * modeInfo.bpp/8);}//------------------------------------------------------------------------------void Unichrome::setPitch(size_t source, size_t destination){ source /= 8; destination /= 8; uint32_t value = Constant::MASK_ENABLE_PITCH | Util::combine32(source, destination); if (value!=state.pitch) { fifo.prepare(4); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::PITCH, value); state.pitch = value; }}//------------------------------------------------------------------------------void Unichrome::resetSourcePitch(){ const ModeInfo& modeInfo = ModeInfo::get(currentModeIndex); setSourcePitch(modeInfo.width * modeInfo.bpp/8);}//------------------------------------------------------------------------------void Unichrome::setSourcePitch(size_t pitch){ setPitch(pitch, (state.pitch&0xffff0000)>>13);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -