📄 ncr710init2.n
字号:
int NCR710_SPURIOUS_CMD if 0 ; if clear, spurious commandint NCR710_READY ; else, ack host command;/*****************************************************************************;*;* ncr710InitStart - start new initiator thread, selecting target and;* continuing to transfer command, data, messages as requested.;*;* At this point the script requires some data in the scratch registers:;*;* scratch 0: host flags (halt after data in, disable SCSI timeout);* scratch 1: message out status (none, pending, or sent);* scratch 2: message in status;* scratch 3: undefined;*;* When the script finishes, these registers are updated to contain:;*;* scratch 0: info transfer phase currently being serviced;* scratch 1: message out status (none, pending, or sent);* scratch 2: message in status;* scratch 3: contents of LCRC reg (after a reselection);*/PROC ncr710InitStart:move PHASE_NONE to CURRENT_PHASEcall REL(timeoutEnable)call REL(mismatchATNIntrDisable);; If required to identify, select w. ATN and try to transfer IDENTIFY message; (if this fails, continue silently). Otherwise, select without ATN.;move HOST_FLAGS & FLAGS_IDENTIFY to sfbrjump REL(selNoAtn) if 0select atn from OFFSET_DEVICE, REL(checkNewCmd); the following now transfers the IDENTIFY message plus any; other message concatenated to it.;; NB this code will not tolerate phase mismatches during the message out; transfer. Therefore, things will go badly wrong if the target rejects; either the IDENTIFY or the following message (for example).jump REL(doneSelect), when not MSG_OUTmove from OFFSET_IDENT_OUT, when MSG_OUT; if there was a normal message concatenated to the IDENTIFY; then we have now sent it. Handle as per normal completion of MSG OUT phase.move MSG_OUT_STATE to sfbr ; if (msg out == pending)jump REL(doneSelect) if not M_OUT_PENDINGmove M_OUT_SENT to sfbr ; msg out = sentmove sfbr to MSG_OUT_STATEjump REL(doneSelect)selNoAtn:select from OFFSET_DEVICE, REL(checkNewCmd); Note: must wait for any info xfer phase to be requested before proceeding; to disable timeout. Otherwise, the "select" appears to always hang up.jump REL(doneSelect), when not MSG_OUT;; Interrupt host if requested, else continue to phase-sequencing code;doneSelect:call REL(timeoutDisable)jump REL(nextPhase);/*****************************************************************************;*;* ncr710InitContinue - resume an initiator thread;*;* At this point the script requires some data in the scratch registers:;*;* scratch 0: host flags (assert ATN on selection);* scratch 1: message out status (none, pending, or sent);* scratch 2: message in status;* scratch 3: undefined;*;* When the script finishes, these registers are updated to contain:;*;* scratch 0: info transfer phase currently being serviced;* scratch 1: message out status (none, pending, or sent);* scratch 2: message in status;* scratch 3: contents of LCRC reg (after a reselection);*/ PROC ncr710InitContinue:call REL(timeoutDisable)nextPhase:call REL(mismatchATNIntrEnable)move MSG_OUT_STATE to sfbr ; if (msg out == pending)call REL(assertAtn) if M_OUT_PENDING ; assert ATNclear ack;; If a message out has just been sent, and the current phase is no longer; message out, the target has accepted the message. Reset the message out; state to NONE, and interrupt the host to handle msg out post-processing.;jump REL(phaseSwitch), when MSG_OUT ; if ((phase != msg out)move MSG_OUT_STATE to sfbrjump REL(phaseSwitch) if not M_OUT_SENT ; && (msg out == sent))move M_OUT_NONE to sfbr ; msg out = nonemove sfbr to MSG_OUT_STATEint NCR710_MESSAGE_OUT_SENT;; Normal info transfer request processing;phaseSwitch:jump REL(doDataOut), when DATA_OUTjump REL(doDataIn) if DATA_INjump REL(doCommand) if COMMANDjump REL(doStatus) if STATUSjump REL(doMsgOut) if MSG_OUTjump REL(doMsgIn) if MSG_INint NCR710_ILLEGAL_PHASE;/*****************************************************************************;*;* doDataOut - handle DATA OUT phase;*/ doDataOut:move PHASE_DATA_OUT to CURRENT_PHASEmove from OFFSET_DATA, when DATA_OUTjump REL(nextPhase);/*****************************************************************************;*;* doDataIn - handle DATA IN phase;*/ doDataIn:move PHASE_DATA_IN to CURRENT_PHASEmove from OFFSET_DATA, when DATA_INjump REL(nextPhase);/*****************************************************************************;*;* doCommand - handle COMMAND phase;*/ doCommand:move PHASE_COMMAND to CURRENT_PHASEmove from OFFSET_CMD, when CMDjump REL(nextPhase);/*****************************************************************************;*;* doStatus - handle STATUS phase;*/ doStatus:move PHASE_STATUS to CURRENT_PHASEmove from OFFSET_STATUS, when STATUSjump REL(nextPhase);/*****************************************************************************;*;* doMsgOut - handle MSG OUT phase;*/ doMsgOut:move PHASE_MSG_OUT to CURRENT_PHASEmove MSG_OUT_STATE to sfbr ; if msg out == noneint NCR710_NO_MSG_OUT if M_OUT_NONE ; send NO-OP (host does it)call REL(assertAtn) if M_OUT_SENT ; assert ATN for retriesmove from OFFSET_MSG_OUT, when MSG_OUTmove M_OUT_SENT to sfbrmove sfbr to MSG_OUT_STATE ; msg out = sentjump REL(nextPhase);/*****************************************************************************;*;* doMsgIn - handle MSG IN phase;*;* Note: there is little point in having the '710 parse the message type;* unless it can save the host some work by doing so; DISCONNECT and;* COMMAND COMPLETE are really the only cases in point. Multi-byte messages;* are handled specially - see the comments below.;*/ doMsgIn:move PHASE_MSG_IN to CURRENT_PHASEmove MSG_IN_STATE to sfbrjump REL(contExtMsg) if M_IN_EXT_MSG_DATAmove from OFFSET_MSG_IN, when MSG_INjump REL(twobyte) if 0x20 and mask 0x0fjump REL(disconn) if M_DISCONNECTjump REL(complete) if M_CMD_COMPLETEjump REL(extended) if M_EXT_MSGint NCR710_MESSAGE_IN_RECVD ; host handles all others;; Have received a DISCONNECT message;disconn:clear ackcall REL(timeoutEnable)wait disconnectint NCR710_DISCONNECTED;; Have received a COMMAND COMPLETE message;complete:clear ackcall REL(timeoutEnable)wait disconnectint NCR710_CMD_COMPLETE;; Have received the first byte of a two-byte message;; Read the second byte and then interrupt the host.;twobyte:clear ackmove from OFFSET_MSG_IN_SECOND, when MSG_INint NCR710_MESSAGE_IN_RECVD;; Have received the first byte of an extended message;; Get the number of bytes in the message proper, then interrupt the host; so it can set up the MSG_IN_REST pointer/count accordingly. (The 53C710; can not dynamically change this itself without having static data which; would then need to be relocated at runtime - what a loser !);; [ A "quick-and-dirty" alternative might be to set up the pointer for; reading the message length so that it puts the byte read into the count; field for reading the message itself. This _should_ work, and would; avoid interrupting the host, but seems a bit flakey. ];extended:clear ackmove from OFFSET_MSG_IN_SECOND, when MSG_INmove M_IN_EXT_MSG_DATA to sfbrmove sfbr to MSG_IN_STATEint NCR710_EXT_MESSAGE_SIZEcontExtMsg:clear ackmove from OFFSET_MSG_IN_REST, when MSG_INmove M_IN_NONE to sfbrmove sfbr to MSG_IN_STATEint NCR710_MESSAGE_IN_RECVD ; at last !/******************************************************************************** ncr710TgtDisconnect - disconnect from SCSI bus**/PROC ncr710TgtDisconnect:call REL(mismatchATNIntrDisable)set targetdisconnectclear targetint NCR710_DISCONNECTED/******************************************************************************** miscellaneous useful subroutines - mainly to improve readability of the* main script. Call/return overhead is not an issue (I think).*/;; assertAtn - assert the SCSI ATN signal;assertAtn:set atnreturn;; timeoutEnable - enable the SCSI {inter-byte, select, disconnect} timeout;timeoutEnable:move ctest7 & (~CTEST7_NO_TIMEOUT & 0xff) to ctest7return;; timeoutDisable - disable the SCSI {inter-byte, select, disconnect} timeout;timeoutDisable:move ctest7 | CTEST7_NO_TIMEOUT to ctest7return;; mismatchATNIntrEnable - enable the phase mismatch / ATN interrupt;mismatchATNIntrEnable:move sien | SIEN_MISMATCH_ATN to sfbrmove sfbr to sienreturn;; mismatchATNIntrDisable - disable the phase mismatch / ATN interrupt;mismatchATNIntrDisable:move sien & (~SIEN_MISMATCH_ATN & 0xff) to sfbrmove sfbr to sienreturn; End of Script
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -