⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncr.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/*	**      And try to select this target.	*/	SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select),		PADDR (reselect),	/*	**	Now there are 4 possibilities:	**	**	(1) The ncr looses arbitration.	**	This is ok, because it will try again,	**	when the bus becomes idle.	**	(But beware of the timeout function!)	**	**	(2) The ncr is reselected.	**	Then the script processor takes the jump	**	to the RESELECT label.	**	**	(3) The ncr completes the selection.	**	Then it will execute the next statement.	**	**	(4) There is a selection timeout.	**	Then the ncr should interrupt the host and stop.	**	Unfortunately, it seems to continue execution	**	of the script. But it will fail with an	**	IID-interrupt on the next WHEN.	*/	SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)),		0,	/*	**	Save target id to ctest0 register	*/	SCR_FROM_REG (sdid),		0,	SCR_TO_REG (ctest0),		0,	/*	**	Send the IDENTIFY and SIMPLE_TAG messages	**	(and the M_X_SYNC_REQ message)	*/	SCR_MOVE_TBL ^ SCR_MSG_OUT,		offsetof (struct dsb, smsg),#ifdef undef /* XXX better fail than try to deal with this ... */	SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_OUT)),		-16,#endif	SCR_CLR (SCR_ATN),		0,	SCR_COPY (1),		RADDR (sfbr),		NADDR (lastmsg),	/*	**	Selection complete.	**	Next time use the next slot.	*/	SCR_COPY (4),		RADDR (scratcha),		PADDR (startpos),}/*-------------------------< PREPARE >----------------------*/,{	/*	**      The ncr doesn't have an indirect load	**	or store command. So we have to	**	copy part of the control block to a	**	fixed place, where we can access it.	**	**	We patch the address part of a	**	COPY command with the DSA-register.	*/	SCR_COPY_F (4),		RADDR (dsa),		PADDR (loadpos),	/*	**	then we do the actual copy.	*/	SCR_COPY (sizeof (struct head)),	/*	**	continued after the next label ...	*/}/*-------------------------< LOADPOS >---------------------*/,{		0,		NADDR (header),	/*	**      Mark this ccb as not scheduled.	*/	SCR_COPY (8),		PADDR (idle),		NADDR (header.launch),	/*	**      Set a time stamp for this selection	*/	SCR_COPY (sizeof (struct timeval)),		KVAR (KVAR_TIME),		NADDR (header.stamp.select),	/*	**      load the savep (saved pointer) into	**      the TEMP register (actual pointer)	*/	SCR_COPY (4),		NADDR (header.savep),		RADDR (temp),	/*	**      Initialize the status registers	*/	SCR_COPY (4),		NADDR (header.status),		RADDR (scr0),}/*-------------------------< PREPARE2 >---------------------*/,{	/*	**      Load the synchronous mode register	*/	SCR_COPY (1),		NADDR (sync_st),		RADDR (sxfer),	/*	**      Load the wide mode and timing register	*/	SCR_COPY (1),		NADDR (wide_st),		RADDR (scntl3),	/*	**	Initialize the msgout buffer with a NOOP message.	*/	SCR_LOAD_REG (scratcha, M_NOOP),		0,	SCR_COPY (1),		RADDR (scratcha),		NADDR (msgout),	SCR_COPY (1),		RADDR (scratcha),		NADDR (msgin),	/*	**	Message in phase ?	*/	SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),		PADDR (dispatch),	/*	**	Extended or reject message ?	*/	SCR_FROM_REG (sbdl),		0,	SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),		PADDR (msg_in),	SCR_JUMP ^ IFTRUE (DATA (M_REJECT)),		PADDRH (msg_reject),	/*	**	normal processing	*/	SCR_JUMP,		PADDR (dispatch),}/*-------------------------< SETMSG >----------------------*/,{	SCR_COPY (1),		RADDR (scratcha),		NADDR (msgout),	SCR_SET (SCR_ATN),		0,}/*-------------------------< CLRACK >----------------------*/,{	/*	**	Terminate possible pending message phase.	*/	SCR_CLR (SCR_ACK),		0,}/*-----------------------< DISPATCH >----------------------*/,{	SCR_FROM_REG (HS_REG),		0,	SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),		SIR_NEGO_FAILED,	/*	**	remove bogus output signals	*/	SCR_REG_REG (socl, SCR_AND, CACK|CATN),		0,	SCR_RETURN ^ IFTRUE (WHEN (SCR_DATA_OUT)),		0,	SCR_RETURN ^ IFTRUE (IF (SCR_DATA_IN)),		0,	SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)),		PADDR (msg_out),	SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN)),		PADDR (msg_in),	SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)),		PADDR (command),	SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)),		PADDR (status),	/*	**      Discard one illegal phase byte, if required.	*/	SCR_LOAD_REG (scratcha, XE_BAD_PHASE),		0,	SCR_COPY (1),		RADDR (scratcha),		NADDR (xerr_st),	SCR_JUMPR ^ IFFALSE (IF (SCR_ILG_OUT)),		8,	SCR_MOVE_ABS (1) ^ SCR_ILG_OUT,		NADDR (scratch),	SCR_JUMPR ^ IFFALSE (IF (SCR_ILG_IN)),		8,	SCR_MOVE_ABS (1) ^ SCR_ILG_IN,		NADDR (scratch),	SCR_JUMP,		PADDR (dispatch),}/*-------------------------< NO_DATA >--------------------*/,{	/*	**	The target wants to tranfer too much data	**	or in the wrong direction.	**      Remember that in extended error.	*/	SCR_LOAD_REG (scratcha, XE_EXTRA_DATA),		0,	SCR_COPY (1),		RADDR (scratcha),		NADDR (xerr_st),	/*	**      Discard one data byte, if required.	*/	SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)),		8,	SCR_MOVE_ABS (1) ^ SCR_DATA_OUT,		NADDR (scratch),	SCR_JUMPR ^ IFFALSE (IF (SCR_DATA_IN)),		8,	SCR_MOVE_ABS (1) ^ SCR_DATA_IN,		NADDR (scratch),	/*	**      .. and repeat as required.	*/	SCR_CALL,		PADDR (dispatch),	SCR_JUMP,		PADDR (no_data),}/*-------------------------< CHECKATN >--------------------*/,{	/*	**	If AAP (bit 1 of scntl0 register) is set	**	and a parity error is detected,	**	the script processor asserts ATN.	**	**	The target should switch to a MSG_OUT phase	**	to get the message.	*/	SCR_FROM_REG (socl),		0,	SCR_JUMP ^ IFFALSE (MASK (CATN, CATN)),		PADDR (dispatch),	/*	**	count it	*/	SCR_REG_REG (PS_REG, SCR_ADD, 1),		0,	/*	**	Prepare a M_ID_ERROR message	**	(initiator detected error).	**	The target should retry the transfer.	*/	SCR_LOAD_REG (scratcha, M_ID_ERROR),		0,	SCR_JUMP,		PADDR (setmsg),}/*-------------------------< COMMAND >--------------------*/,{	/*	**	If this is not a GETCC transfer ...	*/	SCR_FROM_REG (SS_REG),		0,/*<<<*/	SCR_JUMPR ^ IFTRUE (DATA (S_CHECK_COND)),		28,	/*	**	... set a timestamp ...	*/	SCR_COPY (sizeof (struct timeval)),		KVAR (KVAR_TIME),		NADDR (header.stamp.command),	/*	**	... and send the command	*/	SCR_MOVE_TBL ^ SCR_COMMAND,		offsetof (struct dsb, cmd),	SCR_JUMP,		PADDR (dispatch),	/*	**	Send the GETCC command	*//*>>>*/	SCR_MOVE_TBL ^ SCR_COMMAND,		offsetof (struct dsb, scmd),	SCR_JUMP,		PADDR (dispatch),}/*-------------------------< STATUS >--------------------*/,{	/*	**	set the timestamp.	*/	SCR_COPY (sizeof (struct timeval)),		KVAR (KVAR_TIME),		NADDR (header.stamp.status),	/*	**	If this is a GETCC transfer,	*/	SCR_FROM_REG (SS_REG),		0,/*<<<*/	SCR_JUMPR ^ IFFALSE (DATA (S_CHECK_COND)),		40,	/*	**	get the status	*/	SCR_MOVE_ABS (1) ^ SCR_STATUS,		NADDR (scratch),	/*	**	Save status to scsi_status.	**	Mark as complete.	**	And wait for disconnect.	*/	SCR_TO_REG (SS_REG),		0,	SCR_REG_REG (SS_REG, SCR_OR, S_SENSE),		0,	SCR_LOAD_REG (HS_REG, HS_COMPLETE),		0,	SCR_JUMP,		PADDR (checkatn),	/*	**	If it was no GETCC transfer,	**	save the status to scsi_status.	*//*>>>*/	SCR_MOVE_ABS (1) ^ SCR_STATUS,		NADDR (scratch),	SCR_TO_REG (SS_REG),		0,	/*	**	if it was no check condition ...	*/	SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)),		PADDR (checkatn),	/*	**	... mark as complete.	*/	SCR_LOAD_REG (HS_REG, HS_COMPLETE),		0,	SCR_JUMP,		PADDR (checkatn),}/*-------------------------< MSG_IN >--------------------*/,{	/*	**	Get the first byte of the message	**	and save it to SCRATCHA.	**	**	The script processor doesn't negate the	**	ACK signal after this transfer.	*/	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,		NADDR (msgin[0]),	/*	**	Check for message parity error.	*/	SCR_TO_REG (scratcha),		0,	SCR_FROM_REG (socl),		0,	SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),		PADDRH (msg_parity),	SCR_FROM_REG (scratcha),		0,	/*	**	Parity was ok, handle this message.	*/	SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)),		PADDR (complete),	SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)),		PADDR (save_dp),	SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)),		PADDR (restore_dp),	SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),		PADDR (disconnect),	SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),		PADDRH (msg_extended),	SCR_JUMP ^ IFTRUE (DATA (M_NOOP)),		PADDR (clrack),	SCR_JUMP ^ IFTRUE (DATA (M_REJECT)),		PADDRH (msg_reject),	SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)),		PADDRH (msg_ign_residue),	/*	**	Rest of the messages left as	**	an exercise ...	**	**	Unimplemented messages:	**	fall through to MSG_BAD.	*/}/*-------------------------< MSG_BAD >------------------*/,{	/*	**	unimplemented message - reject it.	*/	SCR_INT,		SIR_REJECT_SENT,	SCR_LOAD_REG (scratcha, M_REJECT),		0,	SCR_JUMP,		PADDR (setmsg),}/*-------------------------< COMPLETE >-----------------*/,{	/*	**	Complete message.	**	**	If it's not the get condition code,	**	copy TEMP register to LASTP in header.	*/	SCR_FROM_REG (SS_REG),		0,/*<<<*/	SCR_JUMPR ^ IFTRUE (MASK (S_SENSE, S_SENSE)),		12,	SCR_COPY (4),		RADDR (temp),		NADDR (header.lastp),/*>>>*/	/*	**	When we terminate the cycle by clearing ACK,	**	the target may disconnect immediately.	**	**	We don't want to be told of an	**	"unexpected disconnect",	**	so we disable this feature.	*/	SCR_REG_REG (scntl2, SCR_AND, 0x7f),		0,	/*	**	Terminate cycle ...	*/	SCR_CLR (SCR_ACK|SCR_ATN),		0,	/*	**	... and wait for the disconnect.	*/	SCR_WAIT_DISC,		0,}/*-------------------------< CLEANUP >-------------------*/,{	/*	**      dsa:    Pointer to ccb	**	      or xxxxxxFF (no ccb)	**	**      HS_REG:   Host-Status (<>0!)	*/	SCR_FROM_REG (dsa),		0,	SCR_JUMP ^ IFTRUE (DATA (0xff)),		PADDR (signal),	/*	**      dsa is valid.	**	save the status registers	*/	SCR_COPY (4),		RADDR (scr0),		NADDR (header.status),	/*	**	and copy back the header to the ccb.	*/	SCR_COPY_F (4),		RADDR (dsa),		PADDR (cleanup0),	SCR_COPY (sizeof (struct head)),		NADDR (header),}/*-------------------------< CLEANUP0 >--------------------*/,{		0,	/*	**	If command resulted in "check condition"	**	status and is not yet completed,	**	try to get the condition code.	*/	SCR_FROM_REG (HS_REG),		0,/*<<<*/	SCR_JUMPR ^ IFFALSE (MASK (0, HS_DONEMASK)),		16,	SCR_FROM_REG (SS_REG),		0,	SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)),		PADDRH(getcc2),	/*	**	And make the DSA register invalid.	*//*>>>*/	SCR_LOAD_REG (dsa, 0xff), /* invalid */		0,}/*-------------------------< SIGNAL >----------------------*/,{	/*	**	if status = queue full,	**	reinsert in startqueue and stall queue.	*/	SCR_FROM_REG (SS_REG),		0,	SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)),		SIR_STALL_QUEUE,	/*	**	if job completed ...	*/	SCR_FROM_REG (HS_REG),		0,	/*	**	... signal completion to the host	*/	SCR_INT_FLY ^ IFFALSE (MASK (0, HS_DONEMASK)),		0,	/*	**	Auf zu neuen Schandtaten!	*/	SCR_JUMP,		PADDR(start),}/*-------------------------< SAVE_DP >------------------*/,{	/*	**	SAVE_DP message:	**	Copy TEMP register to SAVEP in header.	*/	SCR_COPY (4),		RADDR (temp),		NADDR (header.savep),	SCR_JUMP,		PADDR (clrack),}/*-------------------------< RESTORE_DP >---------------*/,{	/*	**	RESTORE_DP message:	**	Copy SAVEP in header to TEMP register.	*/	SCR_COPY (4),		NADDR (header.savep),		RADDR (temp),	SCR_JUMP,		PADDR (clrack),}/*-------------------------< DISCONNECT >---------------*/,{	/*	**	If QUIRK_AUTOSAVE is set,	**	do an "save pointer" operation.	*/	SCR_FROM_REG (QU_REG),		0,/*<<<*/	SCR_JUMPR ^ IFFALSE (MASK (QUIRK_AUTOSAVE, QUIRK_AUTOSAVE)),		12,	/*	**	like SAVE_DP message:	**	Copy TEMP register to SAVEP in header.	*/	SCR_COPY (4),		RADDR (temp),		NADDR (header.savep),/*>>>*/	/*	**	Check if temp==savep or temp==goalp:	**	if not, log a missing save pointer message.	**	In fact, it's a comparison mod 256.	**	**	Hmmm, I hadn't thought that I would be urged to	**	write this kind of ugly self modifying code.	**	**	It's unbelievable, but the ncr53c8xx isn't able	**	to subtract one register from another.	*/	SCR_FROM_REG (temp),		0,	/*	**	You are not expected to understand this ..	**	**	CAUTION: only little endian architectures supported! XXX	*/	SCR_COPY_F (1),		NADDR (header.savep),		PADDR (disconnect0),}/*-------------------------< DISCONNECT0 >--------------*/,{/*<<<*/	SCR_JUMPR ^ IFTRUE (DATA (1)),		20,	/*	**	neither this	*/	SCR_COPY_F (1),		NADDR (header.goalp),		PADDR (disconnect1),}/*-------------------------< DISCONNECT1 >--------------*/,{	SCR_INT ^ IFFALSE (DATA (1)),		SIR_MISSING_SAVE,/*>>>*/	/*	**	DISCONNECTing  ...	**	**	disable the "unexpected disconnect" feature,	**	and remove the ACK signal.	*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -