From: Wouter V. <m97...@us...> - 2005-01-31 16:36:59
|
Update of /cvsroot/openmsx/openMSX/src/video/v9990 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14560/src/video/v9990 Modified Files: V9990.cc V9990.hh V9990CmdEngine.cc V9990CmdEngine.hh Log Message: implemented V9990 SRCH cmd Index: V9990.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/v9990/V9990.cc,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- V9990.cc 20 Jan 2005 21:21:17 -0000 1.33 +++ V9990.cc 31 Jan 2005 16:36:48 -0000 1.34 @@ -70,7 +70,7 @@ vram.reset(new V9990VRAM(this, time)); // create Command Engine - cmdEngine.reset(new V9990CmdEngine(this)); + cmdEngine.reset(new V9990CmdEngine(this, time)); // Start with NTSC timing palTiming = false; @@ -194,10 +194,10 @@ int y = ticks / V9990DisplayTiming::UC_TICKS_PER_LINE; bool hr = (x < 64) || (576 <= x); // TODO not correct bool vr = (y < 14) || (226 <= y); // TODO not correct - result = (cmdEngine->getTransfer(time) ? 0x80 : 0x00) | + result = cmdEngine->getStatus(time) | (vr ? 0x40 : 0x00) | (hr ? 0x20 : 0x00) | - (status & 0x1F); + (status & 0x06); break; } case KANJI_ROM_1: @@ -216,9 +216,9 @@ break; } - PRT_DEBUG("[" << time << "] " - "V9990::readIO - port=0x" << std::hex << (int)port << - " val=0x" << std::hex << (int)result); + //PRT_DEBUG("[" << time << "] " + // "V9990::readIO - port=0x" << std::hex << (int)port << + // " val=0x" << std::hex << (int)result); return result; } @@ -233,9 +233,9 @@ { port &= 0x0F; - PRT_DEBUG("[" << time << "] " - "V9990::writeIO - port=0x" << std::hex << int(port) << - " val=0x" << std::hex << int(val)); + //PRT_DEBUG("[" << time << "] " + // "V9990::writeIO - port=0x" << std::hex << int(port) << + // " val=0x" << std::hex << int(val)); switch (port) { case VRAM_DATA: { @@ -480,8 +480,14 @@ // TODO sync(time) (if needed at all) // byte result; - if(regAccess[reg] != NO_ACCESS && regAccess[reg] != WR_ONLY) { - result = regs[reg]; + if (regAccess[reg] != NO_ACCESS && regAccess[reg] != WR_ONLY) { + if (reg < CMD_PARAM_BORDER_X_0) { + result = regs[reg]; + } else { + word borderX = cmdEngine->getBorderX(time); + return (reg == CMD_PARAM_BORDER_X_0) + ? (borderX & 0xFF) : (borderX >> 8); + } } else { result = 0xFF; } Index: V9990.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/v9990/V9990.hh,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- V9990.hh 22 Jan 2005 20:33:17 -0000 1.30 +++ V9990.hh 31 Jan 2005 16:36:48 -0000 1.31 @@ -200,17 +200,20 @@ /** Return the image width */ inline int getImageWidth() { - return (256 << ((regs[SCREEN_MODE_0] & 0x0C) >> 2)); + switch (regs[SCREEN_MODE_0] & 0xC0) { + case 0x00: // P1 + return 256; + case 0x40: // P2 + return 512; + case 0x80: // Bx + default: // standby TODO check this + return (256 << ((regs[SCREEN_MODE_0] & 0x0C) >> 2)); + } } - - /** Command execution started - */ - inline void cmdStart() { status |= 0x01; } /** Command execution ready */ inline void cmdReady() { - status &= 0xFE; raiseIRQ(CMD_IRQ); } Index: V9990CmdEngine.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/v9990/V9990CmdEngine.cc,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- V9990CmdEngine.cc 22 Jan 2005 22:13:42 -0000 1.19 +++ V9990CmdEngine.cc 31 Jan 2005 16:36:49 -0000 1.20 @@ -147,7 +147,7 @@ // ==================================================================== /** Constructor */ -V9990CmdEngine::V9990CmdEngine(V9990* vdp_) +V9990CmdEngine::V9990CmdEngine(V9990* vdp_, const EmuTime& time) : vdp(vdp_) , cmdTraceSetting("v9990cmdtrace", "V9990 command tracing on/off", false) { @@ -173,8 +173,7 @@ createEngines<CmdPSET> (0x0E); createEngines<CmdADVN> (0x0F); - transfer = false; - currentCommand = NULL; + reset(time); } V9990CmdEngine::~V9990CmdEngine() @@ -191,7 +190,8 @@ void V9990CmdEngine::reset(const EmuTime& time) { currentCommand = NULL; - transfer = false; + status = 0; + borderX = 0; } void V9990CmdEngine::setCmdReg(byte reg, byte value, const EmuTime& time) @@ -269,7 +269,7 @@ if (cmdTraceSetting.getValue()) { reportV9990Command(); } - vdp->cmdStart(); + status |= CE; currentCommand = commands[CMD >> 4][vdp->getColorMode()]; if (currentCommand) currentCommand->start(time); break; @@ -374,13 +374,13 @@ } engine->ANX = engine->NX; engine->ANY = engine->NY; - engine->transfer = false; + engine->status &= ~TR; } void V9990CmdEngine::CmdLMMC<V9990CmdEngine::V9990Bpp16>::execute(const EmuTime& time) { - if (engine->transfer) { - engine->transfer = false; + if (engine->status & TR) { + engine->status &= ~TR; int width = engine->vdp->getImageWidth(); byte value = vram->readVRAM(engine->dstAddress); @@ -411,8 +411,8 @@ template <class Mode> void V9990CmdEngine::CmdLMMC<Mode>::execute(const EmuTime& time) { - if (engine->transfer) { - engine->transfer = false; + if (engine->status & TR) { + engine->status &= ~TR; int width = engine->vdp->getImageWidth() / Mode::PIXELS_PER_BYTE; byte data = engine->data; for (int i = 0; (engine->ANY > 0) && (i < Mode::PIXELS_PER_BYTE); ++i) { @@ -587,14 +587,14 @@ { engine->ANX = engine->NX; engine->ANY = engine->NY; - engine->transfer = false; + engine->status &= ~TR; } template <class Mode> void V9990CmdEngine::CmdCMMC<Mode>::execute(const EmuTime& time) { - if (engine->transfer) { - engine->transfer = false; + if (engine->status & TR) { + engine->status &= ~TR; int width = engine->vdp->getImageWidth(); if (Mode::PIXELS_PER_BYTE) { @@ -985,13 +985,44 @@ template <class Mode> void V9990CmdEngine::CmdSRCH<Mode>::start(const EmuTime& time) { - std::cout << "V9990: SRCH not yet implemented" << std::endl; - engine->cmdReady(); // TODO dummy implementation + engine->ASX = engine->SX; + // TODO should be done by sync + execute(time); } template <class Mode> void V9990CmdEngine::CmdSRCH<Mode>::execute(const EmuTime& time) { + int ppl = engine->vdp->getImageWidth(); + int width = ppl; + if (Mode::PIXELS_PER_BYTE) { + // hack to avoid "warning: division by zero" + int ppb = Mode::PIXELS_PER_BYTE; + width /= ppb; + } + + word CL = Mode::shiftDown(engine->fgCol, 0); + int TX = (engine->ARG & DIX) ? -1 : 1; + bool AEQ = (engine->ARG & NEQ) != 0; // TODO: Do we look for "==" or "!="? + //int delta = LINE_TIMING[engine->getTiming()]; + + //while (clock.before(time)) { + while (true) { + //clock += delta; + word value = Mode::point(vram, engine->ASX, engine->SY, width); + if ((value == CL) ^ AEQ) { + engine->status |= BD; // border detected + engine->cmdReady(); + engine->borderX = engine->ASX; + break; + } + if ((engine->ASX += TX) & ppl) { + engine->status &= ~BD; // border not detected + engine->cmdReady(); + engine->borderX = engine->ASX; + break; + } + } } // ==================================================================== @@ -1080,7 +1111,7 @@ { sync(time); data = value; - transfer = true; + status |= TR; } byte V9990CmdEngine::getCmdData(const EmuTime& time) @@ -1088,9 +1119,9 @@ sync(time); byte value = 0xFF; - if (transfer) { + if (status & TR) { value = data; - transfer = false; + status &= ~TR; } return value; } @@ -1133,7 +1164,8 @@ void V9990CmdEngine::cmdReady() { - currentCommand = (V9990Cmd *) NULL; + currentCommand = NULL; + status &= ~CE; vdp->cmdReady(); } Index: V9990CmdEngine.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/v9990/V9990CmdEngine.hh,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- V9990CmdEngine.hh 22 Jan 2005 22:13:42 -0000 1.16 +++ V9990CmdEngine.hh 31 Jan 2005 16:36:49 -0000 1.17 @@ -17,9 +17,14 @@ */ class V9990CmdEngine { public: + // status bits + static const byte TR = 0x80; + static const byte BD = 0x10; + static const byte CE = 0x01; + /** Constructor */ - V9990CmdEngine(V9990* vdp); + V9990CmdEngine(V9990* vdp, const EmuTime& time); /** Destructor */ @@ -49,11 +54,19 @@ */ byte getCmdData(const EmuTime& time); - /** cmd engine ready for transfer (bit 7 in status reg) + /** Get command engine related status bits + * - TR command data transfer ready (bit 7) + * - BD border color detect (bit 4) + * - CE command being executed (bit 0) */ - bool getTransfer(const EmuTime& time) { + byte getStatus(const EmuTime& time) { sync(time); - return transfer; + return status; + } + + word getBorderX(const EmuTime& time) { + sync(time); + return borderX; } private: @@ -270,11 +283,15 @@ /** VRAM */ //V9990VRAM* vram; - - /** Transfer a byte to/from the CPU - */ - bool transfer; + /** Status bits + */ + byte status; + + /** The X coord of a border detected by SRCH + */ + word borderX; + /** Data byte to transfer between V9990 and CPU */ byte data; |