📄 unichrome.cc
字号:
//------------------------------------------------------------------------------void Unichrome::resetDestinationPitch(){ const ModeInfo& modeInfo = ModeInfo::get(currentModeIndex); setDestinationPitch(modeInfo.width * modeInfo.bpp/8);}//------------------------------------------------------------------------------void Unichrome::setDestinationPitch(size_t pitch){ setPitch( (state.pitch&0x0000ffff)<<3, pitch);}//------------------------------------------------------------------------------void Unichrome::setMonoPattern(const uint32_t pattern[2], size_t xOffset, size_t yOffset){ fifo.prepare(8); uint32_t pataddr = ((yOffset&0x7)<<29) | ((xOffset&0x07)<<26); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::MONOPAT0, pattern[0]); fifo.add2D(Register::MONOPAT1, pattern[1]); fifo.add2D(Register::PATADDR, pataddr);}//------------------------------------------------------------------------------void Unichrome::drawLine(size_t x1, size_t y1, size_t x2, size_t y2){ uint32_t command = Constant::GECMD_LINE |Constant::GECMD_FIXCOLOR_PAT | Constant::ROP_P | Constant::GECMD_CLIP_ENABLED; unsigned error = 1; ssize_t dx = x2 - x1; ssize_t dy = y2 - y1; if (dx<0) { dx = 0 - dx; error = 0; command |= Constant::GECMD_DECX; } if (dy<0) { dy = 0 - dy; error = 0; command |= Constant::GECMD_DECY; } if (dy>dx) { ssize_t tmp = dy; dy = dx; dx = tmp; command |= Constant::GECMD_Y_MAJOR; } fifo.prepare(14); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::MONOPAT0, 0xff); fifo.add2D(Register::LINE_K1K2, Util::combine32( ((dy-dx)<<1) & 0x3fff, (dy<<1) & 0x3fff)); fifo.add2D(Register::LINE_XY, Util::combine32(x1, y1)); fifo.add2D(Register::DIMENSION, dx); fifo.add2D(Register::LINE_ERROR, ((dy<<1) - dx - error) & 0x3fff); fifo.add2D(Register::COMMAND, command);}//------------------------------------------------------------------------------void Unichrome::fillRectangle(size_t x, size_t y, size_t width, size_t height){ fifo.prepare(8); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::DSTPOS, Util::combine32(x, y)); fifo.add2D(Register::DIMENSION, Util::combine32(width-1, height-1)); fifo.add2D(Register::COMMAND, Constant::GECMD_BLT | Constant::ROP_P | Constant::GECMD_CLIP_ENABLED | Constant::GECMD_FIXCOLOR_PAT);}//------------------------------------------------------------------------------void Unichrome::blit(size_t x, size_t y, size_t width, size_t height, size_t dx, size_t dy, Window::blitType_t blitType){ uint32_t command = Constant::GECMD_BLT; switch(blitType) { case Window::BLIT_MONO_TRANSPARENT_COPY: command |= Constant::GECMD_MSRC_TRANS; case Window::BLIT_MONO_COPY: command |= Constant::GECMD_SRC_MONO; case Window::BLIT_COPY: command |= Constant::ROP_S; break; case Window::BLIT_MONO_TRANSPARENT_PATTERN: command |= Constant::GECMD_MPAT_TRANS; case Window::BLIT_MONO_PATTERN: command |= Constant::ROP_P | Constant::GECMD_PAT_REG | Constant::GECMD_PAT_MONO; break; } if (x<dx) { command |= Constant::GECMD_DECX; x += width - 1; dx += width - 1; } if (y<dy) { command |= Constant::GECMD_DECY; y += height - 1; dy += height - 1; } fifo.prepare(10); fifo.addHeader(Constant::CMD_PARATYPE_NOTTEX); fifo.add2D(Register::SRCPOS, Util::combine32(x, y)); fifo.add2D(Register::DSTPOS, Util::combine32(dx, dy)); fifo.add2D(Register::DIMENSION, Util::combine32(width-1, height-1)); fifo.add2D(Register::COMMAND, command); }//------------------------------------------------------------------------------void Unichrome::flush(){ fifo.flush();}//------------------------------------------------------------------------------bool Unichrome::waitGraphicsEngine(){ return waitGraphicsEngine(io);}//------------------------------------------------------------------------------MPEGDecoder& Unichrome::getMPEGDecoder(){ return mpegDecoder;}//------------------------------------------------------------------------------millis_t Unichrome::waitHWFlipFinished(size_t& fieldNumber){ assert(usingHWFlipping()); millis_t flipTime = INVALID_MILLIS; if (v1FlipPending) { flipTime = flipperThread->finishFlip(fieldNumber); if (flipTime==INVALID_MILLIS) { Log::debug("unichrome::Unichrome::waitHWFlipFinished: last field was skipped because of being late\n"); } v1FlipPending = false; } return flipTime;}//------------------------------------------------------------------------------void Unichrome::startHWFlip(size_t fieldNumber, ssize_t fieldCompensation){ assert(usingHWFlipping()); assert(!v1FlipPending); flipperThread->startFlip(fieldNumber, fieldCompensation, v1BufferOffsets[nextV1Buffer]); nextV1Buffer = 1 - nextV1Buffer; v1FlipPending = true;}//------------------------------------------------------------------------------void Unichrome::setSPUPalette(const unsigned* palette){ for(size_t i = 0; i<16; ++i) { uint32_t y = (palette[i]>>16) & 0xff; uint32_t cr = (palette[i]>>8) & 0xff; uint32_t cb = (palette[i]>>0) & 0xff; uint32_t x = (cr<<24) | (cb<<16) | (y<<8) | (i<<4) | Constant::SUBP_RGB; io.reg(Register::SUBP_RAM_TABLE_CONTROL) = x; }}//------------------------------------------------------------------------------volatile unsigned char* Unichrome::getSPUBuffer(size_t& width, size_t& height){ if (spuOffset==(size_t)-1) return 0; else { width = spuWidth; height = spuHeight; return io.getFrameBuffer() + spuOffset; }}//------------------------------------------------------------------------------void Unichrome::enableSPU(){ io.reg(Register::SUBP_CONTROL) |= Constant::SUBP_HQV_ENABLE;}//------------------------------------------------------------------------------void Unichrome::disableSPU(){ io.reg(Register::SUBP_CONTROL) &= ~Constant::SUBP_HQV_ENABLE;}//------------------------------------------------------------------------------//------------------------------------------------------------------------------void Unichrome::enableMMIO(){ io.miscOutput2.write8(io.miscOutput2.read8() | 0x01); io.miscOutput.write8(io.miscInput.read8() | 0x01); unlockExtendedRegister(); io.sequencer.write(0x1a, io.sequencer.read(0x1a) | 0x68);}//------------------------------------------------------------------------------void Unichrome::unlockExtendedRegister(){ io.sequencer.write(0x10, 0x01);}//------------------------------------------------------------------------------void Unichrome::turnOffScreen(){ io.control.writeMasked(0x17, 0x00, 0x80);} //------------------------------------------------------------------------------void Unichrome::unlockCRT(){ io.control.writeMasked(0x11, 0, 0x80); io.control.writeMasked(0x47, 0, 0x01);}//------------------------------------------------------------------------------void Unichrome::setupCRT(const CRTSettings& horizontal, const CRTSettings& vertical){ io.control.write(0x09, 0x00); IGA1Horizontal_total.write(io.control, horizontal.total/8 - 5); IGA1Horizontal_addressable.write(io.control, horizontal.addressable/8 - 1); IGA1Horizontal_blankStart.write(io.control, horizontal.blankStart/8 - 1); IGA1Horizontal_blankEnd.write(io.control, horizontal.blankEnd/8 - 1); IGA1Horizontal_synchStart.write(io.control, horizontal.synchStart/8 - 1); IGA1Horizontal_synchEnd.write(io.control, (horizontal.synchEnd-horizontal.synchStart)/8 - 1); IGA1Vertical_total.write(io.control, vertical.total - 2); IGA1Vertical_addressable.write(io.control, vertical.addressable - 1); IGA1Vertical_blankStart.write(io.control, vertical.blankStart - 1); IGA1Vertical_blankEnd.write(io.control, vertical.blankEnd - 1); IGA1Vertical_synchStart.write(io.control, vertical.synchStart - 1); IGA1Vertical_synchEnd.write(io.control, vertical.synchEnd - vertical.synchStart - 1); io.control.writeMasked(0x09, 0x40, 0x40);}//------------------------------------------------------------------------------void Unichrome::lockCRT(){ io.control.writeMasked(0x11, 0x80, 0x80);}//------------------------------------------------------------------------------void Unichrome::setupIGA1(size_t width, size_t bpp){ IGA1Other_offset.write(io.control, width * (bpp / 8) / 8); IGA1Other_fetchCount.write(io.sequencer, width * (bpp/8) / 16 + 4);}//------------------------------------------------------------------------------void Unichrome::openScreen(){ io.status.read8(); io.attribute.write8(0x20); io.control.write(0x6a, 0x40); io.control.write(0x6b, 0x81); io.control.write(0x6c, 0x01);}//------------------------------------------------------------------------------void Unichrome::setVCLK(size_t vclk){ io.control.writeMasked(0x17, 0x00, 0x80); io.sequencer.write(0x46, vclk>>8); io.sequencer.write(0x47, vclk&0xff); io.control.writeMasked(0x17, 0x80, 0x80); io.sequencer.writeMasked(0x40, 0x02, 0x02); io.sequencer.writeMasked(0x40, 0x00, 0x02); io.miscOutput.write8(io.miscInput.read8() | 0x0c);}//------------------------------------------------------------------------------void Unichrome::setRegisters(){ io.sequencer.writeMasked(0x1a, 0x00, 0x40); io.sequencer.writeMasked(0x1a, 0x04, 0x04);}//------------------------------------------------------------------------------void Unichrome::init2D(size_t width, size_t height, size_t bpp){ //enableMMIO(); for(size_t i = 0; i<=0x040; i+=4) { io.reg(i) = 0; } state.bgColor = 0; state.keyControl = 0; state.sourceBase = 0; state.destinationBase = 0; io.reg(Register::TRANSET) = 0x00100000; io.reg(Register::TRANSPACE) = 0x00000000; io.reg(Register::TRANSPACE) = 0x00333004; io.reg(Register::TRANSPACE) = 0x60000000; io.reg(Register::TRANSPACE) = 0x61000000; io.reg(Register::TRANSPACE) = 0x62000000; io.reg(Register::TRANSPACE) = 0x63000000; io.reg(Register::TRANSPACE) = 0x64000000; io.reg(Register::TRANSPACE) = 0x7d000000; io.reg(Register::TRANSET) = 0xfe020000; io.reg(Register::TRANSPACE) = 0x00000000; // disable VQ io.reg(Register::TRANSET) = 0x00fe0000; io.reg(Register::TRANSPACE) = 0x00000004; io.reg(Register::TRANSPACE) = 0x40008c0f; io.reg(Register::TRANSPACE) = 0x44000000; io.reg(Register::TRANSPACE) = 0x45080c04; io.reg(Register::TRANSPACE) = 0x46800408; switch(bpp) { case 32: io.reg(Register::MODE) = Constant::MODE_32BPP; break; case 16: io.reg(Register::MODE) = Constant::MODE_16BPP; break; default: break; } io.reg(Register::CLIPBR) = Util::combine32(width, height); size_t pitch = width * (bpp / 8) / 8; io.reg(Register::PITCH) = state.pitch = Constant::MASK_ENABLE_PITCH | Util::combine32(pitch, pitch);}//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -