📄 i2ellis.c
字号:
//// If outgoing mailbox is empty, sends mail and returns true. If outgoing// mailbox is not empty, returns false.//// This version operates on IntelliPort-II - style FIFO's////******************************************************************************static intiiTrySendMailII(i2eBordStrPtr pB, unsigned char mail){ int port = pB->i2ePointer; OUTB(port, SEL_OUTMAIL); if (INB(port) == 0) { OUTB(port, SEL_OUTMAIL); OUTB(port, mail); return 1; } return 0;}//******************************************************************************// Function: iiTrySendMailIIEX(pB,mail)// Parameters: pB - pointer to board structure// mail - value to write to mailbox//// Returns: True if the transmit mailbox is empty, and mail is sent.// False if it not empty.//// Description://// If outgoing mailbox is empty, sends mail and returns true. If outgoing// mailbox is not empty, returns false.//// This version operates on IntelliPort-IIEX - style FIFO's////******************************************************************************static intiiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail){ if(INB(pB->i2eStatus) & STE_OUT_MAIL) { return 0; } OUTB(pB->i2eXMail, mail); return 1;}//******************************************************************************// Function: iiGetMailII(pB,mail)// Parameters: pB - pointer to board structure//// Returns: Mailbox data or NO_MAIL_HERE.//// Description://// If no mail available, returns NO_MAIL_HERE otherwise returns the data from// the mailbox, which is guaranteed != NO_MAIL_HERE.//// This version operates on IntelliPort-II - style FIFO's////******************************************************************************static unsigned shortiiGetMailII(i2eBordStrPtr pB){ if (HAS_MAIL(pB)) { OUTB(pB->i2ePointer, SEL_INMAIL); return INB(pB->i2ePointer); } else { return NO_MAIL_HERE; }}//******************************************************************************// Function: iiGetMailIIEX(pB,mail)// Parameters: pB - pointer to board structure//// Returns: Mailbox data or NO_MAIL_HERE.//// Description://// If no mail available, returns NO_MAIL_HERE otherwise returns the data from// the mailbox, which is guaranteed != NO_MAIL_HERE.//// This version operates on IntelliPort-IIEX - style FIFO's////******************************************************************************static unsigned shortiiGetMailIIEX(i2eBordStrPtr pB){ if (HAS_MAIL(pB)) { return INB(pB->i2eXMail); } else { return NO_MAIL_HERE; }}//******************************************************************************// Function: iiEnableMailIrqII(pB)// Parameters: pB - pointer to board structure//// Returns: Nothing//// Description://// Enables board to interrupt host (only) by writing to host's in-bound mailbox.//// This version operates on IntelliPort-II - style FIFO's////******************************************************************************static voidiiEnableMailIrqII(i2eBordStrPtr pB){ OUTB(pB->i2ePointer, SEL_MASK); OUTB(pB->i2ePointer, ST_IN_MAIL);}//******************************************************************************// Function: iiEnableMailIrqIIEX(pB)// Parameters: pB - pointer to board structure//// Returns: Nothing//// Description://// Enables board to interrupt host (only) by writing to host's in-bound mailbox.//// This version operates on IntelliPort-IIEX - style FIFO's////******************************************************************************static voidiiEnableMailIrqIIEX(i2eBordStrPtr pB){ OUTB(pB->i2eXMask, MX_IN_MAIL);}//******************************************************************************// Function: iiWriteMaskII(pB)// Parameters: pB - pointer to board structure//// Returns: Nothing//// Description://// Writes arbitrary value to the mask register.//// This version operates on IntelliPort-II - style FIFO's////******************************************************************************static voidiiWriteMaskII(i2eBordStrPtr pB, unsigned char value){ OUTB(pB->i2ePointer, SEL_MASK); OUTB(pB->i2ePointer, value);}//******************************************************************************// Function: iiWriteMaskIIEX(pB)// Parameters: pB - pointer to board structure//// Returns: Nothing//// Description://// Writes arbitrary value to the mask register.//// This version operates on IntelliPort-IIEX - style FIFO's////******************************************************************************static voidiiWriteMaskIIEX(i2eBordStrPtr pB, unsigned char value){ OUTB(pB->i2eXMask, value);}//******************************************************************************// Function: iiDownloadBlock(pB, pSource, isStandard)// Parameters: pB - pointer to board structure// pSource - loadware block to download// isStandard - True if "standard" loadware, else false.//// Returns: Success or Failure//// Description://// Downloads a single block (at pSource)to the board referenced by pB. Caller// sets isStandard to true/false according to whether the "standard" loadware is// what's being loaded. The normal process, then, is to perform an iiInitialize// to the board, then perform some number of iiDownloadBlocks using the returned// state to determine when download is complete.//// Possible return values: (see I2ELLIS.H)// II_DOWN_BADVALID// II_DOWN_BADFILE// II_DOWN_CONTINUING// II_DOWN_GOOD// II_DOWN_BAD// II_DOWN_BADSTATE// II_DOWN_TIMEOUT//// Uses the i2eState and i2eToLoad fields (initialized at iiInitialize) to// determine whether this is the first block, whether to check for magic// numbers, how many blocks there are to go...////******************************************************************************static intiiDownloadBlock ( i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard){ int itemp; int loadedFirst; if (pB->i2eValid != I2E_MAGIC) return II_DOWN_BADVALID; switch(pB->i2eState) { case II_STATE_READY: // Loading the first block after reset. Must check the magic number of the // loadfile, store the number of blocks we expect to load. if (pSource->e.loadMagic != MAGIC_LOADFILE) { return II_DOWN_BADFILE; } // Next we store the total number of blocks to load, including this one. pB->i2eToLoad = 1 + pSource->e.loadBlocksMore; // Set the state, store the version numbers. ('Cause this may have come // from a file - we might want to report these versions and revisions in // case of an error! pB->i2eState = II_STATE_LOADING; pB->i2eLVersion = pSource->e.loadVersion; pB->i2eLRevision = pSource->e.loadRevision; pB->i2eLSub = pSource->e.loadSubRevision; // The time and date of compilation is also available but don't bother // storing it for normal purposes. loadedFirst = 1; break; case II_STATE_LOADING: loadedFirst = 0; break; default: return II_DOWN_BADSTATE; } // Now we must be in the II_STATE_LOADING state, and we assume i2eToLoad // must be positive still, because otherwise we would have cleaned up last // time and set the state to II_STATE_LOADED. if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { return II_DOWN_TIMEOUT; } if (!iiWriteBuf(pB, pSource->c, LOADWARE_BLOCK_SIZE)) { return II_DOWN_BADVALID; } // If we just loaded the first block, wait for the fifo to empty an extra // long time to allow for any special startup code in the firmware, like // sending status messages to the LCD's. if (loadedFirst) { if (!iiWaitForTxEmpty(pB, MAX_DLOAD_START_TIME)) { return II_DOWN_TIMEOUT; } } // Determine whether this was our last block! if (--(pB->i2eToLoad)) { return II_DOWN_CONTINUING; // more to come... } // It WAS our last block: Clean up operations... // ...Wait for last buffer to drain from the board... if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { return II_DOWN_TIMEOUT; } // If there were only a single block written, this would come back // immediately and be harmless, though not strictly necessary. itemp = MAX_DLOAD_ACK_TIME/10; while (--itemp) { if (HAS_INPUT(pB)) { switch(BYTE_FROM(pB)) { case LOADWARE_OK: pB->i2eState = isStandard ? II_STATE_STDLOADED :II_STATE_LOADED; // Some revisions of the bootstrap firmware (e.g. ISA-8 1.0.2) // will, // if there is a debug port attached, require some // time to send information to the debug port now. It will do // this before // executing any of the code we just downloaded. // It may take up to 700 milliseconds. if (pB->i2ePom.e.porDiag2 & POR_DEBUG_PORT) { iiDelay(pB, 700); } return II_DOWN_GOOD; case LOADWARE_BAD: default: return II_DOWN_BAD; } } iiDelay(pB, 10); // 10 mS granularity on checking condition } // Drop-through --> timed out waiting for firmware confirmation pB->i2eState = II_STATE_BADLOAD; return II_DOWN_TIMEOUT;}//******************************************************************************// Function: iiDownloadAll(pB, pSource, isStandard, size)// Parameters: pB - pointer to board structure// pSource - loadware block to download// isStandard - True if "standard" loadware, else false.// size - size of data to download (in bytes)//// Returns: Success or Failure//// Description://// Given a pointer to a board structure, a pointer to the beginning of some// loadware, whether it is considered the "standard loadware", and the size of// the array in bytes loads the entire array to the board as loadware.//// Assumes the board has been freshly reset and the power-up reset message read.// (i.e., in II_STATE_READY). Complains if state is bad, or if there seems to be// too much or too little data to load, or if iiDownloadBlock complains.//******************************************************************************static intiiDownloadAll(i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard, int size){ int status; // We know (from context) board should be ready for the first block of // download. Complain if not. if (pB->i2eState != II_STATE_READY) return II_DOWN_BADSTATE; while (size > 0) { size -= LOADWARE_BLOCK_SIZE; // How much data should there be left to // load after the following operation ? // Note we just bump pSource by "one", because its size is actually that // of an entire block, same as LOADWARE_BLOCK_SIZE. status = iiDownloadBlock(pB, pSource++, isStandard); switch(status) { case II_DOWN_GOOD: return ( (size > 0) ? II_DOWN_OVER : II_DOWN_GOOD); case II_DOWN_CONTINUING: break; default: return status; } } // We shouldn't drop out: it means "while" caught us with nothing left to // download, yet the previous DownloadBlock did not return complete. Ergo, // not enough data to match the size byte in the header. return II_DOWN_UNDER;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -