|
|
1.1 ! root 1: 1 ! 2: 2 ; Copyright (c) 1997-1999 Apple Computer, Inc. All rights reserved. ! 3: 3 ; ! 4: 4 ; @APPLE_LICENSE_HEADER_START@ ! 5: 5 ; ! 6: 6 ; The contents of this file constitute Original Code as defined in and ! 7: 7 ; are subject to the Apple Public Source License Version 1.1 (the ! 8: 8 ; "License"). You may not use this file except in compliance with the ! 9: 9 ; License. Please obtain a copy of the License at ! 10: 10 ; http://www.apple.com/publicsource and read it before using this file. ! 11: 11 ; ! 12: 12 ; This Original Code and all software distributed under the License are ! 13: 13 ; distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: 14 ; EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: 15 ; INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: 16 ; FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: 17 ; License for the specific language governing rights and limitations ! 18: 18 ; under the License. ! 19: 19 ; ! 20: 20 ; @APPLE_LICENSE_HEADER_END@ ! 21: 21 ; ! 22: 22 ; File Ownership: ! 23: 23 ; ! 24: 24 ; DRI: Mike Johnson ! 25: 25 ; ! 26: 26 ; Other Contact: Russ Berkoff ! 27: 27 ; ! 28: 28 ; Technology: SCSI ! 29: 29 ; ! 30: 30 ; Writers: ! 31: 31 ; ! 32: 32 ; (MLJ) Mike Johnson ! 33: 33 ; (RRA) Rick Auricchio ! 34: 34 ! 35: 35 ! 36: 36 ; NCR Errata Listing 125 Item 1 : Clear the SCNTL0 start bit ! 37: 37 ; when jump to reselect during select (try_reselect) ! 38: 38 ; ! 39: 39 ; NCR Errata Listing 117 Item 4 : Bad parity if odd bytes during ! 40: 40 ; wide transfer. Only for DATA OUT in Initiator mode. ! 41: 41 ; (Confirm by Manfred Eierle 3rd June 93 not during DATA IN) ! 42: 42 ! 43: 43 ARCH 825A ;specifically for 825a and 875 (new instructions) ! 44: 44 ! 45: 45 ! 46: 46 ;***************************************************************** ! 47: 47 ; ! 48: 48 ; Phase codes - These values represent which action is being handled ! 49: 49 ; ! 50: 50 ;***************************************************************** ! 51: 51 ! 52: 52 ABSOLUTE kphase_DATA_OUT = 0x00 ! 53: 53 ABSOLUTE kphase_DATA_IN = 0x01 ! 54: 54 ABSOLUTE kphase_COMMAND = 0x02 ! 55: 55 ABSOLUTE kphase_STATUS = 0x03 ! 56: 56 ABSOLUTE kphase_MSG_OUT = 0x06 ! 57: 57 ABSOLUTE kphase_MSG_IN = 0x07 ! 58: 58 ABSOLUTE kphase_SELECT = 0x08 ! 59: 59 ABSOLUTE kphase_RESELECT = 0x09 ! 60: 60 ABSOLUTE kphase_ABORT_CURRENT = 0x0A ! 61: 61 ABSOLUTE kphase_ABORT_MAILBOX = 0x0B ! 62: 62 ABSOLUTE kphase_CMD_COMPLETE = 0x0C ! 63: 63 ABSOLUTE kphase_DISCONNECT = 0x0D ! 64: 64 ABSOLUTE kphase_saveDataPointer = 0x0E ; ??? driver work to be done ! 65: 65 ABSOLUTE kphase_restoreDataPointer = 0x0F ; ??? driver work to be done ! 66: 66 ! 67: 67 ! 68: 68 ;***************************************************************** ! 69: 69 ; interrupt codes ! 70: 70 ;***************************************************************** ! 71: 71 ! 72: 72 ABSOLUTE unknown_phase = 0x00 ; A spurious phase on SCSI Bus ! 73: 73 ABSOLUTE status_error = 0x01 ; IO completes, but with status error ! 74: 74 ABSOLUTE unexpected_msg = 0x02 ; An 'unknown' message is in ld_message var ! 75: 75 ABSOLUTE unexpected_ext_msg = 0x03 ; An 'unknown' extended message in ld_message ! 76: 76 ABSOLUTE wide_32_not_supported = 0x04 ; The device wants 32 bits data phase ! 77: 77 ABSOLUTE no_msgin_after_reselect = 0x05 ; No message-in after reselection ! 78: 78 ABSOLUTE reqack_too_large = 0x06 ; The device answer ReqAck offset is greater than 8 ! 79: 79 ABSOLUTE unknown_reselect = 0x07 ; The valid bit in SFBR reg not set ! 80: 80 ABSOLUTE unallocated_nexus = 0x08 ; nexus index -> 0xFFFFFFFF ! 81: 81 ABSOLUTE abort_mailbox = 0x09 ; Abort/BDR mailbox completed ! 82: 82 ABSOLUTE abort_current = 0x0A ; Abort/BDR current op completed ! 83: 83 ABSOLUTE unknown_message_out = 0x0B ; Unknown phase before message out ! 84: 84 ABSOLUTE unknown_msg_reject = 0x0C ; Unknown message reject ! 85: 85 ABSOLUTE negotiateSDTR = 0x0D ; Sync negotiation rx'd ! 86: 86 ABSOLUTE negotiateWDTR = 0x0E ; Wide negotiation rx'd ! 87: 87 ABSOLUTE sglist_complete = 0x0F ; SGList complete ! 88: 88 ! 89: 89 ! 90: 90 ;***************************************************************** ! 91: 91 ; ! 92: 92 ; Data structure for T/L/Q Nexus: ! 93: 93 ; ! 94: 94 ;***************************************************************** ! 95: 95 ! 96: 96 ABSOLUTE TLQ_SCSI_ID = 0 ; 4 SCSI ID et al for SELECT instruction ! 97: 97 ABSOLUTE TLQ_xferAdr = 4 ; 4 Physical address of CHMOV instructions ! 98: 98 ABSOLUTE TLQ_MSGOp = 8 ; 8 Byte count, data adr -> TLQ_MSGO ! 99: 99 ABSOLUTE TLQ_CDBp = 16 ; 8 Byte count, data adr -> TLQ_CDB ! 100: 100 ABSOLUTE TLQ_CDP = 24 ; 4 Current Data Pointer ! 101: 101 ABSOLUTE TLQ_SDP = 28 ; 4 Saved Data Pointer ! 102: 102 ABSOLUTE TLQ_index = 32 ; 1 index into nexus array ! 103: 103 ABSOLUTE TLQ_xferStarted= 33 ; 1 transfer started flag ! 104: 104 ABSOLUTE TLQ_IWR = 34 ; 1 flag to Ignore Wide Residue ! 105: 105 ABSOLUTE TLQ_pad = 35 ; 1 pad byte ! 106: 106 ! 107: 107 ! 108: 108 ;***************************************************************** ! 109: 109 ; ! 110: 110 ; ENTRY declarations - Declare entry points for driver ! 111: 111 ; ! 112: 112 ;***************************************************************** ! 113: 113 ! 114: 114 ENTRY select_phase ! 115: 115 ENTRY phase_handler ! 116: 116 ENTRY issueMessageOut ; for negotiation and Reject messages ! 117: 117 ENTRY issueAbort_BDR ; to immediately Abort or Bus-Device-Reset ! 118: 118 ENTRY clearACK ; MsgIn done - clr ACK, jump to phase handler ! 119: 119 ! 120: 120 ! 121: 121 ;***************************************************************** ! 122: 122 ; ! 123: 123 ; Define local data structure at start of SCRIPTS. ! 124: 124 ; This structure is allocated by the following nops. ! 125: 125 ; ! 126: 126 ;***************************************************************** ! 127: 127 ; ! 128: 128 ! 129: 129 RELATIVE local_data \ ! 130: 130 00000000: ld_AbortCode = 4{??}\ ; 1 byte code to Abort or BDR ! 131: 131 00000004: ld_zeroes = 4{??}\ ; 4 bytes of 0 to clear registers ! 132: 132 00000008: ld_status = 4{??}\ ; Status byte from target ! 133: 133 0000000C: ld_counter = 4{??}\ ; index into mailbox array ! 134: 134 00000010: ld_AbortBdr_mailbox = 4{??}\ ; Abort/BusDeviceReset mailbox ! 135: 135 00000014: ld_IOdone_mailbox = 4{??}\ ; [ nexus 0 0 semaphore ] ! 136: 136 00000018: ld_sched_mlbx_base_adr = 4{??}\ ; base addr of mailbox array ! 137: 137 0000001C: ld_mailboxp = 4{??}\ ; address of current mailbox ! 138: 138 00000020: ld_scsi_id = 4{??}\ ; ptr to current mailbox ! 139: 139 00000024: ld_nexus_array_base = 4{??}\ ; base address of Nexus pointers ! 140: 140 00000028: ld_nexus_index = 4{??}\ ; index to Nexus pointer ! 141: 141 0000002C: ld_nexus = 4{??}\ ; address of Nexus ! 142: 142 00000030: ld_phase_flag = 4{??}\ ; for debugging ! 143: 143 00000034: ld_device_table_base_adr = 4{??}\ ; device configuration table ! 144: 144 00000038: ld_scratch = 4{??}\ ; scratch memory ! 145: 145 0000003C: ld_unused = 4{??}\ ; unused ! 146: 146 00000040: ld_message = 4{??}\ ; buffer for MsgIn bytes ! 147: 147 00000044: ld_message4 = 4{??}\ ; buffer continuation ! 148: 148 00000048: ld_pad = 4{??}\ ; padding ! 149: 149 0000004C: ld_size = 4{??} ; size of this structure ! 150: 150 ! 151: 151 ! 152: 152 00000000: PROC BSC_SCRIPT: ! 153: 153 ! 154: 154 ; *** These NOPs must be at address 0. *** ! 155: 155 ; *** This is reserved space for the structure "local_data". *** ! 156: 156 ; *** The driver inits this area to zero. *** ! 157: 157 ! 158: 158 00000000: 80000000 00000000 nop 0 ; ld_AbortCode, ld_zeroes ! 159: 159 00000008: 80000000 00000000 nop 0 ; ld_status, ld_counter ! 160: 160 ! 161: 161 00000010: 80000000 00000000 nop 0 ; ld_AbortBdr_mailbox, ld_IOdone_mailbox ! 162: 162 00000018: 80000000 00000000 nop 0 ; ld_sched_mlbx_base_adr, ld_mailboxp ! 163: 163 ! 164: 164 00000020: 80000000 00000000 nop 0 ; ld_scsi_id, ld_nexus_array_base ! 165: 165 00000028: 80000000 00000000 nop 0 ; ld_nexus_index, ld_nexus ! 166: 166 ! 167: 167 00000030: 80000000 00000000 nop 0 ; ld_phase_flag, ld_device_table_base_adr ! 168: 168 00000038: 80000000 00000000 nop 0 ; ld_scratch, ld_unused ! 169: 169 ! 170: 170 00000040: 80000000 00000000 nop 0 ; ld_message, ld_message4 ! 171: 171 00000048: 80000000 0000004C nop ld_size ; ld_pad, ld_size (Use ld_size or lose it) ! 172: 172 ! 173: 173 00000050: 80000000 0000000F nop sglist_complete ; use sglist_complete or lose it from gen'd output file ! 174: 174 ! 175: 175 ;**************************************************************************** ! 176: 176 ; ! 177: 177 ; findNexusFromIndex - load DSA with pointer to Nexus given a Nexus index: ! 178: 178 ; ! 179: 179 ;**************************************************************************** ! 180: 180 ! 181: 181 00000058: findNexusFromIndex: ! 182: 182 ! 183: 183 00000058: E1340004 00000028 load SCRATCHA0, 4, ld_nexus_index ; load index and leading zeroes ! 184: 184 00000060: 60000400 00000000 clear CARRY ! 185: 185 00000068: 79340000 00000000 move SCRATCHA0 SHL 0 to SCRATCHA0 ; double the index ! 186: 186 00000070: 79350000 00000000 move SCRATCHA1 SHL 0 to SCRATCHA1 ! 187: 187 00000078: 79340000 00000000 move SCRATCHA0 SHL 0 to SCRATCHA0 ; double again ! 188: 188 00000080: 79350000 00000000 move SCRATCHA1 SHL 0 to SCRATCHA1 ; A0 now has index to 4-byte address ! 189: 189 00000088: E0340004 0000009C store SCRATCHA0, 4, patchArrayOffset+4 ; *** patch the code ! 190: 190 ! 191: 191 00000090: E1100004 00000024 load DSA0, 4, ld_nexus_array_base ; load base address of array of Nexus pointers ! 192: 192 00000098: patchArrayOffset: ! 193: 193 00000098: F1100004 00000000 load DSA0, 4, DSAREL( 0 ) ; *** patched offset. Load pointer. ! 194: 194 ! 195: 195 000000A0: 72100000 00000000 move DSA0 to SFBR ; Ensure pointer is not 0xFFFFFFFF ! 196: 196 000000A8: 980C00FF 00000008 int unallocated_nexus, if 0xFF ; Interrupt if NFG ! 197: 197 ! 198: 198 000000B0: E0100004 0000002C store DSA0, 4, ld_nexus ; Store the Nexus pointer ! 199: 199 000000B8: 90080000 00000000 return ; end findNexusFromIndex ! 200: 200 ! 201: 201 ! 202: 202 ;**************************************************************************** ! 203: 203 ; ! 204: 204 ; initContext - Initialize the registers for Sync and Wide using ! 205: 205 ; values stored in the device configuration table. ! 206: 206 ; Return with values in SCRATCHB for Select code. ! 207: 207 ; ! 208: 208 ;**************************************************************************** ! 209: 209 ! 210: 210 000000C0: initContext: ! 211: 211 ! 212: 212 000000C0: E15C0004 00000020 load SCRATCHB0, 4, ld_scsi_id ; load 4-bit SCSI ID and zeroes ! 213: 213 000000C8: 60000400 00000000 clear CARRY ! 214: 214 000000D0: 795C0000 00000000 move SCRATCHB0 SHL SCRATCHB0 ; * 2 ! 215: 215 000000D8: 795C0000 00000000 move SCRATCHB0 SHL SCRATCHB0 ; * 2 -> UInt32 index ! 216: 216 000000E0: E05C0004 000000F4 store SCRATCHB0, 4, patchGetDevConfigOffset+4 ; *** Patch load code ! 217: 217 ! 218: 218 000000E8: E1100004 00000034 load DSA0, 4, ld_device_table_base_adr ; load base physical addr of tables ! 219: 219 ! 220: 220 000000F0: patchGetDevConfigOffset: ! 221: 221 000000F0: F15C0004 00000000 load SCRATCHB0, 4, DSAREL( 0 ) ; *** Patched table offset *** ! 222: 222 ! 223: 223 ; SCRATCHB0 = 0 ! 224: 224 ; SCRATCHB1 = TP,MO (SXFER bits7-5 bits3-0) ! 225: 225 ; SCRATCHB2 = 0 (position for SCSI ID) ! 226: 226 ; SCRATCHB3 = SCCF,EWS (SCNTL3 bits6-4 bit 3) ! 227: 227 ! 228: 228 000000F8: 725D0000 00000000 move SCRATCHB1 to SFBR ; init SXFER from B1 ! 229: 229 00000100: 6A050000 00000000 move SFBR to SXFER ! 230: 230 ; Init SCNTL3 from B3 ! 231: 231 00000108: 725F0000 00000000 move SCRATCHB3 to SFBR ! 232: 232 00000110: 6A030000 00000000 move SFBR to SCNTL3 ! 233: 233 00000118: 90080000 00000000 return ; return with SCRATCHB intact. ! 234: 234 ! 235: 235 ! 236: 236 ;***************************************************************** ! 237: 237 ; ! 238: 238 ; Select_phase: ! 239: 239 ; Clear the SIGP bit. ! 240: 240 ; Check if any Abort/BusDeviceReset request waiting. ! 241: 241 ; Nexus is found in the list of 256 mailboxes. ! 242: 242 ; If current mailbox is empty, jump to reselect_phase. ! 243: 243 ; SCRIPTS tries to select device. ! 244: 244 ; If select fails due to reselect, jump to reselect_phase ! 245: 245 ; Select Timeout handled by driver. ! 246: 246 ; If select succeeds, clear the mailbox entry ! 247: 247 ; and increment the mailbox counter. ! 248: 248 ; Jump to the phase_handler (hopefully for MSG_OUT) ! 249: 249 ; ! 250: 250 ;***************************************************************** ! 251: 251 ! 252: 252 00000120: select_phase: ! 253: 253 ! 254: 254 00000120: 7A1A0000 00000000 move CTEST2 | 0x00 to CTEST2 ; Clear SIGP bit from ISTAT reg ! 255: 255 ! 256: 256 ; Check abort mailbox: ! 257: 257 ! 258: 258 00000128: E1340004 00000010 load SCRATCHA0, 4, ld_AbortBdr_mailbox ; Get AbortBdr mailbox ! 259: 259 ; The Identify byte in byte 0 is also the semaphore ! 260: 260 ; A0 = Identify byte (0xC0 + LUN N.B. Disconnect allowed) ! 261: 261 ; A1 = Tag, if any ! 262: 262 ; A2 = SCSI ID ! 263: 263 ; A3 = Abort code Abort=0x06; Abort Tag=0D; Bus Device Reset=0x0C ! 264: 264 00000130: 72340000 00000000 move SCRATCHA0 to SFBR ; test the semaphore/Identify ! 265: 265 00000138: 80840000 000005F0 jump rel( AbortMailbox ), if not 0 ; jump if aborting ! 266: 266 ! 267: 267 ! 268: 268 ; Get the next IO nexus in the mailboxes circular list. ! 269: 269 ; Calculate current mailbox address as so: ! 270: 270 ; counter byte index * 4 to get mailbox index ! 271: 271 ; add base physical address of mailboxes giving current mailbox address ! 272: 272 ! 273: 273 00000140: E1340004 0000000C load SCRATCHA0, 4, ld_counter ; get 1-byte mailbox counter & 0s ! 274: 274 00000148: 60000400 00000000 clear CARRY ! 275: 275 00000150: 79340000 00000000 move SCRATCHA0 SHL 0 to SCRATCHA0 ; double it ! 276: 276 00000158: 79350000 00000000 move SCRATCHA1 SHL 0 to SCRATCHA1 ! 277: 277 00000160: 79340000 00000000 move SCRATCHA0 SHL 0 to SCRATCHA0 ; double it again ! 278: 278 00000168: 79350000 00000000 move SCRATCHA1 SHL 0 to SCRATCHA1 ; now have a UInt32 index ! 279: 279 00000170: E0340004 0000018C store SCRATCHA0, 4, fetchMailbox+4 ; *** patch the load DSA instruction ! 280: 280 00000178: E0340004 0000025C store SCRATCHA0, 4, clear_mailbox+4 ; *** patch the store DSA instruction ! 281: 281 ! 282: 282 00000180: E1100004 00000018 load DSA0, 4, ld_sched_mlbx_base_adr ; load base physical address of mailboxes ! 283: 283 ! 284: 284 00000188: fetchMailbox: ! 285: 285 00000188: F1100004 00000000 load DSA0, 4, DSAREL( 0 ) ; *** Patched offset. Load Nexus address ! 286: 286 00000190: E0100004 0000002C store DSA0, 4, ld_nexus ; save pointer to current Nexus ! 287: 287 00000198: E1340004 0000002C load SCRATCHA0, 4, ld_nexus ; copy to A0 ! 288: 288 ! 289: 289 000001A0: 72340000 00000000 move SCRATCHA0 to SFBR ; ! 290: 290 000001A8: 808C0001 00000098 jump rel( next_mailbox ), if 1 ; if low-byte == 0x01 then cancelled mailbox ! 291: 291 ! 292: 292 000001B0: 72B50000 00000000 move SCRATCHA1 | SFBR to SFBR ; if non-zero, have implicit semaphore ! 293: 293 000001B8: 72B60000 00000000 move SCRATCHA2 | SFBR to SFBR ! 294: 294 000001C0: 72B70000 00000000 move SCRATCHA3 | SFBR to SFBR ! 295: 295 000001C8: 808C0000 00000458 jump rel( reselect_phase ), if 0 ; go to reselect_phase if empty ! 296: 296 ! 297: 297 ;***************************************************************** ! 298: 298 ; ! 299: 299 ; Something in mailbox: we have work to do ! 300: 300 ; ! 301: 301 ;***************************************************************** ! 302: 302 ! 303: 303 000001D0: 785C0800 00000000 move kphase_SELECT to SCRATCHB0 ; set phase indicator ! 304: 304 000001D8: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 305: 305 ! 306: 306 000001E0: E15C0004 00000004 load SCRATCHB0, 4, ld_zeroes ; clr the invalid-nexus-index flag ! 307: 307 000001E8: F15C0001 00000020 load SCRATCHB0, 1, DSAREL( TLQ_index ) ; get index byte from nexus ! 308: 308 000001F0: E05C0004 00000028 store SCRATCHB0, 4, ld_nexus_index ; save it in local data ! 309: 309 ! 310: 310 000001F8: E1100004 0000002C load DSA0, 4, ld_nexus ; restore DSA register ! 311: 311 00000200: F15E0001 00000002 load SCRATCHB2, 1, DSAREL( TLQ_SCSI_ID+2 ) ; get Target's SCSI ID ! 312: 312 00000208: 725E0000 00000000 move SCRATCHB2 to SFBR ! 313: 313 00000210: 6A5C0000 00000000 move SFBR to SCRATCHB0 ; position it ! 314: 314 00000218: E05C0001 00000020 store SCRATCHB0, 1, ld_scsi_id ; save it ! 315: 315 00000220: 88880000 FFFFFE98 call rel( initContext ) ; setup Sync/Wide regs in SCRATCHB ! 316: 316 00000228: E1100004 0000002C load DSA0, 4, ld_nexus ; restore DSA register ! 317: 317 00000230: F05D0001 00000001 store SCRATCHB1, 1, DSAREL( TLQ_SCSI_ID+1 ) ; SXFER ! 318: 318 00000238: F05F0001 00000003 store SCRATCHB3, 1, DSAREL( TLQ_SCSI_ID+3 ) ; SCNTL3 ! 319: 319 ! 320: 320 ;********************** select the device ******************************** ! 321: 321 00000240: 47000000 000003D0 SELECT ATN from TLQ_SCSI_ID, rel( try_reselect ) ; ************************ ! 322: 322 ;************************************************************************* ! 323: 323 ! 324: 324 ; looking good - clear the mailbox: ! 325: 325 ! 326: 326 00000248: next_mailbox: ! 327: 327 00000248: E1340004 00000004 load SCRATCHA0, 4, ld_zeroes ; zero out scratch register A ! 328: 328 00000250: E1100004 00000018 load DSA0, 4, ld_sched_mlbx_base_adr ; load base physical address of mailboxes ! 329: 329 00000258: clear_mailbox: ! 330: 330 00000258: F0340004 00000000 store SCRATCHA0, 4, DSAREL( 0 ) ; *** Patched offset. Zero the mailbox ! 331: 331 ! 332: 332 ; Update the index to the mailbox circular list: ! 333: 333 00000260: E15C0001 0000000C load SCRATCHB0, 1, ld_counter ; get counter (mailbox index) ! 334: 334 00000268: 7E5C0100 00000000 move SCRATCHB0 + 1 to SCRATCHB0 ; add 1 ! 335: 335 00000270: E05C0001 0000000C store SCRATCHB0, 1, ld_counter ; put it back ! 336: 336 ! 337: 337 00000278: E15C0001 0000002C load SCRATCHB0, 1, ld_nexus ; if low-byte == 0x01 then cancelled mailbox ! 338: 338 00000280: 725C0000 00000000 move SCRATCHB0 to SFBR ! 339: 339 00000288: 808C0001 FFFFFE90 jump rel( select_phase ), if 1 ! 340: 340 ! 341: 341 ; *** FALL THROUGH TO phase_handler *** ! 342: 342 ! 343: 343 ! 344: 344 ;***************************************************************** ! 345: 345 ; ! 346: 346 ; Phase_handler ! 347: 347 ; The phase handler script is a dispatcher function of SCSI phase ! 348: 348 ; ! 349: 349 ;***************************************************************** ! 350: 350 ! 351: 351 00000290: phase_handler: ! 352: 352 00000290: E1100004 0000002C load DSA0, 4, ld_nexus ; reload DSA ! 353: 353 00000298: 828B0000 00000088 jump rel( command_phase ), when CMD ; wait for REQ ! 354: 354 000002A0: 808A0000 000000A8 jump rel( data_out_phase ), if DATA_OUT ; already latched REQ signal ! 355: 355 000002A8: 868A0000 00000020 jump rel( message_out_phase ), if MSG_OUT ! 356: 356 000002B0: 818A0000 000000E0 jump rel( data_in_phase ), if DATA_IN ! 357: 357 000002B8: 838A0000 00000108 jump rel( status_phase ), if STATUS ! 358: 358 000002C0: 878A0000 00000120 jump rel( message_in_phase ), if MSG_IN ! 359: 359 000002C8: 98080000 00000000 int unknown_phase ! 360: 360 ! 361: 361 ! 362: 362 ;***************************************************************** ! 363: 363 ; ! 364: 364 ; Message-Out phase ! 365: 365 ; ! 366: 366 ;***************************************************************** ! 367: 367 ! 368: 368 000002D0: message_out_phase: ! 369: 369 000002D0: 785C0600 00000000 move kphase_MSG_OUT to SCRATCHB0 ; Set phase indicator ! 370: 370 000002D8: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 371: 371 ! 372: 372 000002E0: 1E000000 00000008 move from TLQ_MSGOp, when MSG_OUT ; put out the message(s) ! 373: 373 000002E8: 80880000 FFFFFFA0 jump rel( phase_handler ) ! 374: 374 ! 375: 375 ! 376: 376 ; issueMessageOut - Driver entry point for Sync/Wide negotiation and ! 377: 377 ; to issue message Reject: ! 378: 378 ! 379: 379 000002F0: issueMessageOut: ! 380: 380 000002F0: 58000008 00000000 set ATN ; tell Target we have something to say ! 381: 381 000002F8: 60000040 00000000 clear ACK ! 382: 382 00000300: 868B0000 FFFFFFC8 jump rel( message_out_phase ), when MSG_OUT ; wait for REQ. Jump if msg-out phase. ! 383: 383 00000308: 87820000 FFFFFF80 jump rel( phase_handler ), if not MSG_IN ; jump if weird phase ! 384: 384 00000310: 0F000001 00000039 move 1, ld_scratch+1, when MSG_IN ; dump the msg byte ! 385: 385 00000318: 60000040 00000000 clear ACK ; accept Target's last msg-in byte ! 386: 386 00000320: 80880000 FFFFFFC8 jump rel( issueMessageOut ) ! 387: 387 ! 388: 388 ! 389: 389 ;***************************************************************** ! 390: 390 ; ! 391: 391 ; Command phase ! 392: 392 ; ! 393: 393 ;***************************************************************** ! 394: 394 ! 395: 395 00000328: command_phase: ! 396: 396 00000328: 785C0200 00000000 move kphase_COMMAND to SCRATCHB0 ; Set phase indicator ! 397: 397 00000330: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 398: 398 ! 399: 399 00000338: 60000008 00000000 clear ATN ; In case we missed the sending nego ! 400: 400 00000340: 1A000000 00000010 move FROM TLQ_CDBp, when CMD ; issue the CDB ! 401: 401 00000348: 80880000 FFFFFF40 jump rel( phase_handler ) ! 402: 402 ! 403: 403 ! 404: 404 ;***************************************************************** ! 405: 405 ; ! 406: 406 ; Data_out_phase ! 407: 407 ; ! 408: 408 ;***************************************************************** ! 409: 409 ! 410: 410 00000350: data_out_phase: ! 411: 411 00000350: 785C0000 00000000 move kphase_DATA_OUT to SCRATCHB0 ; Set phase indicator ! 412: 412 00000358: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 413: 413 ! 414: 414 00000360: 88880000 00000008 call rel( driverXfer ) ; call driver-built CHMOV instructions ! 415: 415 00000368: 80880000 FFFFFF20 jump rel( phase_handler ) ; if all data xfer'd, get next phase ! 416: 416 ! 417: 417 00000370: driverXfer: ; get here from data-in code also ! 418: 418 00000370: F1340004 00000004 load SCRATCHA0, 4, DSAREL( TLQ_xferAdr ) ! 419: 419 00000378: E0340004 00000394 store SCRATCHA0, 4, doItPatch+4 ; *** patch the JUMP address ! 420: 420 00000380: 7835FF00 00000000 move 0xFF to SCRATCHA1 ! 421: 421 00000388: F0350001 00000021 store SCRATCHA1, 1, DSAREL( TLQ_xferStarted ) ! 422: 422 ! 423: 423 00000390: doItPatch: ! 424: 424 00000390: 80080000 00000333 jump 0x0333 ; *** patched address ! 425: 425 ! 426: 426 ! 427: 427 ! 428: 428 ;***************************************************************** ! 429: 429 ; ! 430: 430 ; Data_in_phase ! 431: 431 ; 875 sets ATN if bad parity detected. ! 432: 432 ; Use of CHMOV instructions assures that we properly handle ! 433: 433 ; a leftover wide byte in the SWIDE or SODL register, depending ! 434: 434 ; on the data direction. This can happen in either of two conditions: ! 435: 435 ; 1. The Target disconnects at an odd boundary. This is ! 436: 436 ; extremely unlikely with disk devices. ! 437: 437 ; 2. The client passes either an odd buffer address or ! 438: 438 ; an odd transfer count. When the Target disconnects (at ! 439: 439 ; an even boundary, we end up with the extra wide ! 440: 440 ; byte in SWIDE or SODL. MacOS does this with VM on. ! 441: 441 ; ! 442: 442 ;***************************************************************** ! 443: 443 ! 444: 444 00000398: data_in_phase: ! 445: 445 00000398: 785C0100 00000000 move kphase_DATA_IN to SCRATCHB0 ; Set phase indicator ! 446: 446 000003A0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 447: 447 ! 448: 448 000003A8: 88880000 FFFFFFC0 call rel( driverXfer ) ; call driver-built CHMOV instructions ! 449: 449 ! 450: 450 ; The driver gets interrupted if a phase mismatch occurs as when ! 451: 451 ; the Target goes MSG-IN with a Disconnect. ! 452: 452 ; The driver codes either a RETURN if the Scatter/Gather list is complete or ! 453: 453 ; an INT if more Scatter/Gather elements need to be generated. ! 454: 454 ; On the Macintosh, client programs expect extra incoming data to be dumped. ! 455: 455 ; For example, during boot the ROM reads 512 bytes from a 2K-byte-sector CD. ! 456: 456 ! 457: 457 000003B0: bucket_loop: ! 458: 458 000003B0: 81830000 FFFFFED8 jump rel( phase_handler ), when not DATA_IN ; wait for phase, exit if changed ! 459: 459 000003B8: 01000001 00000008 CHMOV 1, ld_status, when DATA_IN ; eat a byte ! 460: 460 000003C0: 80880000 FFFFFFE8 jump rel( bucket_loop ); ; keep dumping bytes ! 461: 461 ! 462: 462 ! 463: 463 ;***************************************************************** ! 464: 464 ; ! 465: 465 ; Status phase ! 466: 466 ; ! 467: 467 ;***************************************************************** ! 468: 468 ! 469: 469 000003C8: status_phase: ! 470: 470 000003C8: 785C0300 00000000 move kphase_STATUS to SCRATCHB0 ; Set phase indicator ! 471: 471 000003D0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 472: 472 ! 473: 473 000003D8: 0B000001 00000008 move 1, ld_status, when STATUS ; Read Status byte from bus ! 474: 474 000003E0: 80880000 FFFFFEA8 jump rel( phase_handler ) ! 475: 475 ! 476: 476 ! 477: 477 ;***************************************************************** ! 478: 478 ; ! 479: 479 ; Message-In phase ! 480: 480 ; ! 481: 481 ;***************************************************************** ! 482: 482 ! 483: 483 000003E8: message_in_phase: ! 484: 484 000003E8: 785C0700 00000000 move kphase_MSG_IN to SCRATCHB0 ; Set phase indicator ! 485: 485 000003F0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 486: 486 ! 487: 487 000003F8: 0F000001 00000040 move 1, ld_message, when MSG_IN ; Read byte from bus ! 488: 488 ! 489: 489 00000400: 808C0000 000000C0 jump rel( cmdComplete ), if 0x00 ; Command Complete ! 490: 490 00000408: 808C0002 000001A8 jump rel( saveDataPointer ), if 0x02 ; Save Data Pointer ! 491: 491 00000410: 808C0004 00000148 jump rel( disconnect_msg ), if 0x04 ; Disconnect ! 492: 492 00000418: 808C0023 00000038 jump rel( ignoreWideResidue ), if 0x23 ; Ignore Wide Residue ! 493: 493 00000420: 808C0003 000001B0 jump rel( restoreDataPointer ), if 0x03 ; Restore Data Pointer ! 494: 494 00000428: 808C0001 00000058 jump rel( extended_msg ), if 0x01 ; Extended message ! 495: 495 00000430: 808C0007 00000008 jump rel( msg_reject ), if 0x07 ; Message Reject ! 496: 496 ; Identify, if 0x80-FF ; Identify + LUN ! 497: 497 ; simple_queue_tag, if 0x20 ; Simple Queue Tag ! 498: 498 ; initiate_recovery, if 0x0F ; Initiate Recovery ! 499: 499 ; linked_cde_complete, if 0x0A/0x0B ! 500: 500 00000438: 98080000 00000002 int unexpected_msg ; unknown ! 501: 501 ! 502: 502 00000440: msg_reject: ! 503: 503 00000440: 98080000 0000000C int unknown_msg_reject ! 504: 504 ! 505: 505 00000448: clearACK: ; ENTRY point to end negotiation ! 506: 506 00000448: 60000040 00000000 clear ACK ! 507: 507 00000450: 80880000 FFFFFE38 jump rel( phase_handler ) ! 508: 508 ! 509: 509 ! 510: 510 ! 511: 511 ;***************************************************************** ! 512: 512 ; ! 513: 513 ; Ignore Wide Residue ! 514: 514 ; ! 515: 515 ;***************************************************************** ! 516: 516 ! 517: 517 00000458: ignoreWideResidue: ; this is a two byte message so snag the 2nd byte here ! 518: 518 00000458: 60000040 00000000 clear ACK ! 519: 519 00000460: 0F000001 00000041 move 1, ld_message+1, when MSG_IN ; save residue count ! 520: 520 00000468: 6A5E0000 00000000 move SFBR to SCRATCHB2 ; byte is still in SFBR. Position it. ! 521: 521 00000470: F05E0001 00000022 store SCRATCHB2, 1, DSAREL( TLQ_IWR ) ; Store residue count in Nexus for driver. ! 522: 522 00000478: 60000040 00000000 clear ACK ! 523: 523 00000480: 80880000 FFFFFE08 jump rel( phase_handler ) ! 524: 524 ! 525: 525 ! 526: 526 ;***************************************************************** ! 527: 527 ; ! 528: 528 ; Extended message ! 529: 529 ; Accept Wide and Synchronous Data Transfer messages ! 530: 530 ; ! 531: 531 ;***************************************************************** ! 532: 532 ! 533: 533 00000488: extended_msg: ! 534: 534 00000488: 60000040 00000000 clear ACK ! 535: 535 00000490: 0F000001 00000041 move 1, ld_message+1, when MSG_IN ; read msg length byte from bus ! 536: 536 00000498: 60000040 00000000 clear ACK ! 537: 537 000004A0: 0F000001 00000042 move 1, ld_message+2, when MSG_IN ; read ext msg code from bus ! 538: 538 000004A8: 60000040 00000000 clear ACK ! 539: 539 ; extended_identify, IF 0x02 ! 540: 540 ; modify_data_pointer, if 0x00 ! 541: 541 000004B0: 808C0001 00000140 jump rel( sdtr ), if 0x01 ; jump if SDTR, sync negotiation msg ! 542: 542 000004B8: 808C0003 00000148 jump rel( wdtr ), if 0x03 ; jump if WDTR, wide negotiation msg ! 543: 543 000004C0: 98080000 00000003 int unexpected_ext_msg ; let driver deal with unknown ! 544: 544 ! 545: 545 ! 546: 546 ;***************************************************************** ! 547: 547 ; ! 548: 548 ; Command complete ! 549: 549 ; The Command-Complete message is sent to indicate that the ! 550: 550 ; IO operation has completed and valid status has been sent. ! 551: 551 ; The Target should then disconnect. ! 552: 552 ; SCRIPTS must spin until the IOdone mailbox is empty. ! 553: 553 ; Then it sets the IOdone mailbox with the current Nexus. ! 554: 554 ; The status message is analyzed. ! 555: 555 ; If status is good, INTF the driver and jump to select_phase. ! 556: 556 ; If status is NG, save it in the NEXUS and INT the driver. ! 557: 557 ; ! 558: 558 ;***************************************************************** ! 559: 559 ! 560: 560 000004C8: cmdComplete: ! 561: 561 000004C8: 785C0C00 00000000 move kphase_CMD_COMPLETE to SCRATCHB0 ; Set phase indicator ! 562: 562 000004D0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 563: 563 ! 564: 564 000004D8: 7C027F00 00000000 move SCNTL2 & 0X7F to SCNTL2 ; Clr SDU: SCSI Disconnect Unexpected ! 565: 565 000004E0: 60000040 00000000 clear ACK ! 566: 566 000004E8: 48000000 00000000 WAIT DISCONNECT ! 567: 567 ! 568: 568 000004F0: testMbxLp: ; loop until IOdone mailbox empty ! 569: 569 000004F0: E1340004 00000014 load SCRATCHA0, 4, ld_IOdone_mailbox ! 570: 570 000004F8: 72370000 00000000 move SCRATCHA3 to SFBR ; A3 = semaphore ! 571: 571 00000500: 80840000 FFFFFFE8 jump rel( testMbxLp ), if not 0 ! 572: 572 ! 573: 573 ; Fill in the IOdone mailbox with the following: ! 574: 574 ; A0 = index to Nexus ! 575: 575 ; A1 = Status ! 576: 576 ; A2 = 0 ! 577: 577 ; A3 = semaphore (FF = set) ! 578: 578 00000508: E1340001 00000028 load SCRATCHA0, 1, ld_nexus_index ; A0 = index to Nexus ! 579: 579 00000510: E15C0001 00000008 load SCRATCHB0, 1, ld_status ! 580: 580 00000518: 725C0000 00000000 move SCRATCHB0 to SFBR ! 581: 581 00000520: 6A350000 00000000 move SFBR to SCRATCHA1 ; A1 = Status ! 582: 582 00000528: 78360000 00000000 move 0x00 to SCRATCHA2 ; A2 = 0 ! 583: 583 00000530: 7837FF00 00000000 move 0xFF to SCRATCHA3 ; A3 = semaphore IOdone mailbox ! 584: 584 00000538: E0340004 00000014 store SCRATCHA0, 4, ld_IOdone_mailbox ! 585: 585 ! 586: 586 00000540: 72350000 00000000 move SCRATCHA1 to SFBR ; Test the Status of this IO ! 587: 587 ; SFBR = status msg ! 588: 588 ; Test status - If good, Interrupt on the fly and jump to select phase ! 589: 589 00000548: 981CC100 000000FF intfly 0xFF, if 0 and mask 0xC1 ; mask off reserved bits ! 590: 590 00000550: 808CC100 FFFFFBC8 jump rel( select_phase ), if 0 and mask 0xC1 ! 591: 591 00000558: 98080000 00000001 int status_error ; Status err. Interrupt driver & stop ! 592: 592 ! 593: 593 ! 594: 594 ;***************************************************************** ! 595: 595 ; ! 596: 596 ; Disconnect ! 597: 597 ; The 8xx Accepts the disconnection and jumps to the select_phase ! 598: 598 ; to check for another IO ! 599: 599 ; ! 600: 600 ;***************************************************************** ! 601: 601 ! 602: 602 00000560: disconnect_msg: ! 603: 603 00000560: E15C0001 00000030 load SCRATCHB0, 1, ld_phase_flag ! 604: 604 00000568: 725C0000 00000000 move SCRATCHB0 to SFBR ! 605: 605 ; If we got here from reselect just bailout since ld_nexus is ! 606: 606 ; not setup and the code using it is not needed anyway (no data xfer) ! 607: 607 00000570: 808C0009 00000010 jump rel( bailout ), if kphase_RESELECT ! 608: 608 ! 609: 609 00000578: 785C0D00 00000000 move kphase_DISCONNECT to SCRATCHB0 ! 610: 610 00000580: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 611: 611 ! 612: 612 00000588: bailout: ! 613: 613 00000588: 785FFF00 00000000 move 0xFF to SCRATCHB3 ; invalidate nexus index for driver ! 614: 614 00000590: E05F0001 0000002B store SCRATCHB3, 1, ld_nexus_index+3 ! 615: 615 00000598: 7C027F00 00000000 move SCNTL2 & 0x7F to SCNTL2 ; Clr SDU: SCSI Disconnect Unexpected ! 616: 616 000005A0: 60000040 00000000 clear ACK ! 617: 617 000005A8: 48000000 00000000 WAIT DISCONNECT ; wait for bus-free ! 618: 618 000005B0: 80880000 FFFFFB68 jump rel( select_phase ) ; go see if more to do ! 619: 619 ! 620: 620 ! 621: 621 ;****************************************************************** ! 622: 622 ; ! 623: 623 ; ??? mlj - saveDataPointer and restoreDataPointer are incorrect. ! 624: 624 ; ??? They basically do nothing. ! 625: 625 ; Save Data Pointer ! 626: 626 ; ! 627: 627 ;***************************************************************** ! 628: 628 ! 629: 629 000005B8: saveDataPointer: ! 630: 630 000005B8: 785C0E00 00000000 move kphase_saveDataPointer to SCRATCHB0 ! 631: 631 000005C0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 632: 632 000005C8: 60000040 00000000 clear ACK ! 633: 633 000005D0: 80880000 FFFFFCB8 jump rel( phase_handler ) ! 634: 634 ! 635: 635 ! 636: 636 ;****************************************************************** ! 637: 637 ; ! 638: 638 ; ??? mlj - saveDataPointer and restoreDataPointer are incorrect. ! 639: 639 ; ??? They basically do nothing. ! 640: 640 ; Restore Data Pointer ! 641: 641 ; The local values still blocks, still bytes and data address ! 642: 642 ; must be loaded from the corresponding NEXUS data set. ! 643: 643 ; This message should followed an IDE (parity error) ! 644: 644 ; ! 645: 645 ;***************************************************************** ! 646: 646 ! 647: 647 000005D8: restoreDataPointer: ! 648: 648 000005D8: 785C0F00 00000000 move kphase_restoreDataPointer to SCRATCHB0 ! 649: 649 000005E0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 650: 650 000005E8: 60000040 00000000 clear ACK ! 651: 651 000005F0: 80880000 FFFFFC98 jump rel( phase_handler ) ! 652: 652 ! 653: 653 ! 654: 654 ;***************************************************************** ! 655: 655 ; ! 656: 656 ; Synchronous data transfer request or response ! 657: 657 ; ! 658: 658 ;***************************************************************** ! 659: 659 000005F8: sdtr: ! 660: 660 000005F8: 0F000002 00000043 move 2, ld_message+3, when MSG_IN ; Read period & offset from bus ! 661: 661 00000600: 98080000 0000000D int negotiateSDTR ! 662: 662 ! 663: 663 ! 664: 664 ;*************************************************************************** ! 665: 665 ; ! 666: 666 ; Wide Data Transfer request or response ! 667: 667 ; ! 668: 668 ;*************************************************************************** ! 669: 669 00000608: wdtr: ! 670: 670 00000608: 0F000001 00000043 move 1, ld_message+3, when MSG_IN ; get Transfer Width Exponent fm bus ! 671: 671 00000610: 98080000 0000000E int negotiateWDTR ! 672: 672 ! 673: 673 ! 674: 674 ;***************************************************************** ! 675: 675 ; ! 676: 676 ; Reselect phase ! 677: 677 ; The chip waits here either for a Reselection from a Target or ! 678: 678 ; a SIGP from the driver indicating something in the mailbox. ! 679: 679 ; If reselected, the script uses the Nexus value which is either ! 680: 680 ; a Tag or a SCSI ID/LUN combo to lookup the Nexus. ! 681: 681 ; Then init the SXFER and SCNTL3 registers from the device config table. ! 682: 682 ; ! 683: 683 ;***************************************************************** ! 684: 684 ! 685: 685 00000618: try_reselect: ; Select failed - probably reselecting ! 686: 686 ; Cf NCR Errata Listing 117 Item 1: ! 687: 687 00000618: 7C00DF00 00000000 move SCNTL0 & 0xDF to SCNTL0 ; clr Start bit ! 688: 688 00000620: 7A1A0000 00000000 move CTEST2 | 0x00 to CTEST2 ; Clear SIGP bit from ISTAT reg ! 689: 689 ! 690: 690 00000628: reselect_phase: ! 691: 691 00000628: 785C0900 00000000 move kphase_RESELECT to SCRATCHB0 ; Set phase indicator ! 692: 692 00000630: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 693: 693 ! 694: 694 00000638: 785FFF00 00000000 move 0xFF to SCRATCHB3 ; invalidate nexus index for driver ! 695: 695 00000640: E05F0001 0000002B store SCRATCHB3, 1, ld_nexus_index+3 ! 696: 696 ! 697: 697 ; wait here for reselect from a Target ! 698: 698 ; or SIGP from the driver ! 699: 699 ! 700: 700 00000648: 54000000 FFFFFAD0 WAIT RESELECT REL( select_phase ) ; jump if SIGP ! 701: 701 ! 702: 702 ; Reselected: ! 703: 703 ! 704: 704 00000650: 720A0000 00000000 move SSID to SFBR ; SSID = [ Valxxx Scsi_id ] ! 705: 705 00000658: 980C7F00 00000007 int unknown_reselect, if 0 and mask 0x7F; Interrupt if VAL bit not set ! 706: 706 00000660: 6C5C0F00 00000000 move SFBR & 0x0F to SCRATCHB0 ; B0 = Target ID ! 707: 707 00000668: E05C0001 00000020 store SCRATCHB0, 1, ld_scsi_id ; save it ! 708: 708 ! 709: 709 00000670: 88880000 FFFFFA48 call rel( initContext ) ; setup sync regs here ! 710: 710 ! 711: 711 00000678: 9F030000 00000005 int no_msgin_after_reselect, when not MSG_IN ! 712: 712 ! 713: 713 00000680: 0F000001 00000040 move 1, ld_message, when MSG_IN ; Read Identify byte from bus ! 714: 714 ! 715: 715 ; if another REQ is asserted, a SimpleQueueTag message should be next ! 716: 716 ! 717: 717 00000688: 60000040 00000000 clear ACK ; notify Target: msg byte rx'd ! 718: 718 00000690: 878B0000 00000048 jump rel( getNextMsg ), when MSG_IN ; jump if SimpleQueueTag coming ! 719: 719 ! 720: 720 ; untagged operation: ! 721: 721 ! 722: 722 00000698: 6C340700 00000000 move SFBR & 0x07 to SCRATCHA0 ; isolate LUN from Identify byte ! 723: 723 ! 724: 724 000006A0: E15C0001 00000020 load SCRATCHB0, 1, ld_scsi_id ; B0 = Target ID ! 725: 725 000006A8: 60000400 00000000 clear CARRY ! 726: 726 000006B0: 715C0000 00000000 move SCRATCHB0 SHL SFBR ; shift left #1 ! 727: 727 000006B8: 695C0000 00000000 move SFBR SHL SCRATCHB0 ; shift left #2 ! 728: 728 000006C0: 715C0000 00000000 move SCRATCHB0 SHL SFBR ; shift left #3 ! 729: 729 000006C8: 7AB40000 00000000 move SCRATCHA0 | SFBR to SCRATCHA0 ; form Nexus index = 0b0TTTTLLL ! 730: 730 ! 731: 731 000006D0: E0340001 00000028 store SCRATCHA0, 1, ld_nexus_index ; store as index to Nexus ! 732: 732 000006D8: 80880000 00000030 jump rel( haveNexusIndex ) ! 733: 733 ! 734: 734 ; should be tagged operation: ! 735: 735 ! 736: 736 000006E0: getNextMsg: ! 737: 737 000006E0: 0F000001 00000040 move 1, ld_message, when MSG_IN ; read message byte from bus ! 738: 738 000006E8: 808C0004 FFFFFE70 jump rel( disconnect_msg ), if 0x04 ; if Disconnect, oh well. ! 739: 739 000006F0: 60000040 00000000 clear ACK ! 740: 740 000006F8: 80840020 FFFFFB90 jump rel( phase_handler ), if not 0x20; Branch if not Queue tag code ! 741: 741 ; get the Queue Tag and save as the nexus index ! 742: 742 00000700: 0F000001 00000028 move 1, ld_nexus_index, when MSG_IN ; Nexus index <- Tag from bus ! 743: 743 00000708: 60000040 00000000 clear ACK ; acknowledge it ! 744: 744 ! 745: 745 00000710: haveNexusIndex: ! 746: 746 00000710: 785F0000 00000000 move 0x00 to SCRATCHB3 ; clear invalid-nexus-index flag ! 747: 747 00000718: E05F0001 0000002B store SCRATCHB3, 1, ld_nexus_index+3 ! 748: 748 00000720: 88880000 FFFFF930 call rel( findNexusFromIndex ) ; set DSA <- Nexus pointer ! 749: 749 00000728: 80880000 FFFFFB60 jump rel( phase_handler ) ; start handling phases. ! 750: 750 ! 751: 751 ! 752: 752 ;***************************************************************** ! 753: 753 ; ! 754: 754 ; AbortMailbox - Abort (or BusDeviceReset) the mailbox entry. ! 755: 755 ; This is a queued operation - not an immediate ! 756: 756 ; operation as is issueAbort_BDR. ! 757: 757 ; The Abort message clears all IO processes for the ! 758: 758 ; selecting Initiator on the specified LUN. ! 759: 759 ; ! 760: 760 ; The Bus Device Reset message clears all IO processes for ! 761: 761 ; all Initiators on all LUNs of selected Target. ! 762: 762 ; It forces a hard reset condition to the selected SCSI device. ! 763: 763 ; ! 764: 764 ; A0 = Identify byte (0xC0 + LUN N.B. Disconnect allowed) ! 765: 765 ; A1 = Tag, if any ! 766: 766 ; A2 = SCSI ID ! 767: 767 ; A3 = Abort code Abort=0x06; Abort Tag=0D; Bus Device Reset=0x0C ! 768: 768 ; ! 769: 769 ; Mailbox not cleared by SCRIPTS so that driver can find SCSI ID when done ! 770: 770 ; N.B.: Device is Async and Narrow after BDR!!! ! 771: 771 ; Driver must set the device config table values accordingly. ! 772: 772 ;***************************************************************** ! 773: 773 ! 774: 774 00000730: AbortMailbox: ! 775: 775 00000730: 785C0B00 00000000 move kphase_ABORT_MAILBOX to SCRATCHB0 ; Set phase code ! 776: 776 00000738: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 777: 777 ! 778: 778 00000740: 785FFF00 00000000 move 0xFF to SCRATCHB3 ; invalidate nexus index for driver ! 779: 779 00000748: E05F0001 0000002B store SCRATCHB3, 1, ld_nexus_index+3 ! 780: 780 ! 781: 781 00000750: E15E0001 00000012 load SCRATCHB2, 1, ld_AbortBdr_mailbox+2 ; get SCSI ID ! 782: 782 00000758: E05E0001 00000762 store SCRATCHB2, 1, AbortSelect+2 ; *** Patch the Select/ATN instruction ! 783: 783 ! 784: 784 00000760: AbortSelect: ! 785: 785 00000760: 45000000 FFFFFEB0 SELECT ATN 0, REL( try_reselect ) ; *** Patched SCSI ID ! 786: 786 ! 787: 787 00000768: 72350000 00000000 move SCRATCHA1 to SFBR ; check for Tag ! 788: 788 00000770: 80840000 00000038 jump rel( taggedAbort ) if not 0x00 ; jump if tagged abort ! 789: 789 ! 790: 790 ; untagged Abort or BusDeviceReset: ! 791: 791 ! 792: 792 00000778: 72370000 00000000 move SCRATCHA3 to SFBR ; position the abort code ! 793: 793 00000780: 6A350000 00000000 move SFBR to SCRATCHA1 ! 794: 794 00000788: E0340002 00000038 store SCRATCHA0, 2, ld_scratch ; Store Identify and Abort msgs ! 795: 795 00000790: 78020000 00000000 move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected ! 796: 796 00000798: 0E000002 00000038 move 2, ld_scratch , when MSG_OUT ; emit Identify and Abort messages ! 797: 797 000007A0: 48000000 00000000 WAIT DISCONNECT ! 798: 798 000007A8: 98080000 00000009 int abort_mailbox ! 799: 799 ! 800: 800 ; AbortTag: ! 801: 801 ! 802: 802 000007B0: taggedAbort: ! 803: 803 000007B0: 72350000 00000000 move SCRATCHA1 to SFBR ; position the Tag ! 804: 804 000007B8: 6A360000 00000000 move SFBR to SCRATCHA2 ! 805: 805 000007C0: 78352000 00000000 move 0x20 to SCRATCHA1 ; gen SimpleQueueTag code ! 806: 806 000007C8: E0340004 00000038 store SCRATCHA0, 4, ld_scratch ; store Identify, SQT, Tag, AbortTag ! 807: 807 000007D0: 78020000 00000000 move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected ! 808: 808 000007D8: 0E000004 00000038 move 4, ld_scratch, when MSG_OUT ; emit all 4 bytes ! 809: 809 000007E0: 48000000 00000000 WAIT DISCONNECT ! 810: 810 000007E8: 98080000 00000009 int abort_mailbox ! 811: 811 ! 812: 812 ! 813: 813 ;***************************************************************** ! 814: 814 ; ! 815: 815 ; issueAbort_BDR - Abort (or BusDeviceReset) the current operation. ! 816: 816 ; This is an immediate operation - not a queued operation ! 817: 817 ; as is AbortMailbox. ! 818: 818 ; The Abort message clears all IO processes for the ! 819: 819 ; selecting Initiator on the specified LUN. ! 820: 820 ; ! 821: 821 ; The Bus Device Reset message clears all IO processes for ! 822: 822 ; all Initiators on all LUNs of selected Target. ! 823: 823 ; It forces a hard reset condition to the selected SCSI device. ! 824: 824 ; ! 825: 825 ;***************************************************************** ! 826: 826 ! 827: 827 000007F0: issueAbort_BDR: ! 828: 828 000007F0: 785C0A00 00000000 move kphase_ABORT_CURRENT to SCRATCHB0 ; Set phase code ! 829: 829 000007F8: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag ! 830: 830 ! 831: 831 00000800: 74140800 00000000 move ISTAT & 0x08 to SFBR ; see if Target connected to bus ! 832: 832 00000808: 980C0000 0000000A int abort_current, if 0 ; interrupt driver if not connected ! 833: 833 ! 834: 834 00000810: 58000008 00000000 SET ATN ; get Target's attention ! 835: 835 00000818: E1100004 0000002C load DSA0, 4, ld_nexus ; load pointer to Nexus ! 836: 836 ! 837: 837 00000820: bucketLoop: ! 838: 838 00000820: 60000040 00000000 clear ACK ! 839: 839 00000828: 868B0000 000000A8 jump rel( sendAbortBDR ), when MSG_OUT ; wait for REQ. Jump if OK. ! 840: 840 ! 841: 841 00000830: 838A0000 00000030 jump rel( BucketInStatus ), if STATUS ; bit bucket in ! 842: 842 00000838: 878A0000 00000038 jump rel( BucketInMsg ), if MSG_IN ; bit bucket in ! 843: 843 00000840: 818A0000 00000040 jump rel( BucketInData ), if DATA_IN ; bit bucket in ! 844: 844 ! 845: 845 00000848: 7834AD00 00000000 move 0xAD to SCRATCHA0 ! 846: 846 00000850: 808A0000 00000040 jump rel( BucketOutData ), if DATA_OUT ; bit bucket out ! 847: 847 00000858: 828A0000 00000058 jump rel( BucketOutCmd ), if CMD ; bit bucket out ! 848: 848 00000860: 98080000 00000000 int unknown_phase ; back to driver for harsher measures ! 849: 849 ! 850: 850 ! 851: 851 00000868: BucketInStatus: ! 852: 852 00000868: 0B000001 00000038 move 1, ld_scratch, when STATUS ; eat the Status byte ! 853: 853 00000870: 80880000 FFFFFFA8 jump rel( bucketLoop ); ; keep bit-bucketing bytes ! 854: 854 ! 855: 855 00000878: BucketInMsg: ! 856: 856 00000878: 0F000001 00000038 move 1, ld_scratch, when MSG_IN ; eat a message byte ! 857: 857 00000880: 80880000 FFFFFF98 jump rel( bucketLoop ); ; keep bit-bucketing bytes ! 858: 858 ! 859: 859 00000888: BucketInData: ! 860: 860 00000888: 09000001 00000038 move 1, ld_scratch, when DATA_IN ; eat a data byte ! 861: 861 00000890: 80880000 FFFFFF88 jump rel( bucketLoop ); ; keep bit-bucketing bytes ! 862: 862 ! 863: 863 00000898: BucketOutData: ! 864: 864 00000898: 7B347300 00000000 move SCRATCHA0 xor 0x73 to SCRATCHA0 ; gen 0xDEAD ... ! 865: 865 000008A0: E0340001 00000038 store SCRATCHA0, 1, ld_scratch ! 866: 866 000008A8: 08000001 00000038 move 1, ld_scratch, when DATA_OUT ; pad a byte out ! 867: 867 000008B0: 80880000 FFFFFF68 jump rel( bucketLoop ); ; keep bit-bucketing bytes ! 868: 868 ! 869: 869 000008B8: BucketOutCmd: ! 870: 870 000008B8: 78340000 00000000 move 0x00 to SCRATCHA0 ; load Null, TestUnitReady, whatever ! 871: 871 000008C0: E0340001 00000038 store SCRATCHA0, 1, ld_scratch ! 872: 872 000008C8: 0A000001 00000038 move 1, ld_scratch, when CMD ; pad a byte out ! 873: 873 000008D0: 80880000 FFFFFF48 jump rel( bucketLoop ); ; keep bit-bucketing bytes ! 874: 874 ! 875: 875 ! 876: 876 000008D8: sendAbortBDR: ! 877: 877 000008D8: 78020000 00000000 move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected ! 878: 878 000008E0: 0E000001 00000000 move 1, ld_AbortCode, when MSG_OUT ; Send Abort(06) or BDR(0C) message ! 879: 879 000008E8: E1340004 00000004 load SCRATCHA0, 4, ld_zeroes ; load 0's ! 880: 880 000008F0: E0340004 00000000 store SCRATCHA0, 4, ld_AbortCode ; clear the Abort code ! 881: 881 000008F8: 48000000 00000000 WAIT DISCONNECT ! 882: 882 00000900: 98080000 0000000A int abort_current ; went BusFree - tell Driver ! 883: ! 884: --SYMBOL---------------------------VALUE------TYPE------- ! 885: abort_current 0000000A ABSOLUTE ! 886: abort_mailbox 00000009 ABSOLUTE ! 887: kphase_ABORT_MAILBOX 0000000B ABSOLUTE ! 888: kphase_ABORT_CURRENT 0000000A ABSOLUTE ! 889: kphase_CMD_COMPLETE 0000000C ABSOLUTE ! 890: kphase_COMMAND 00000002 ABSOLUTE ! 891: kphase_DATA_IN 00000001 ABSOLUTE ! 892: kphase_DATA_OUT 00000000 ABSOLUTE ! 893: kphase_DISCONNECT 0000000D ABSOLUTE ! 894: kphase_MSG_IN 00000007 ABSOLUTE ! 895: kphase_MSG_OUT 00000006 ABSOLUTE ! 896: kphase_RESELECT 00000009 ABSOLUTE ! 897: kphase_SELECT 00000008 ABSOLUTE ! 898: kphase_STATUS 00000003 ABSOLUTE ! 899: kphase_restoreDataPointer 0000000F ABSOLUTE ! 900: kphase_saveDataPointer 0000000E ABSOLUTE ! 901: negotiateWDTR 0000000E ABSOLUTE ! 902: negotiateSDTR 0000000D ABSOLUTE ! 903: no_msgin_after_reselect 00000005 ABSOLUTE ! 904: reqack_too_large 00000006 ABSOLUTE ! 905: sglist_complete 0000000F ABSOLUTE ! 906: status_error 00000001 ABSOLUTE ! 907: TLQ_CDP 00000018 ABSOLUTE ! 908: TLQ_CDBp 00000010 ABSOLUTE ! 909: TLQ_IWR 00000022 ABSOLUTE ! 910: TLQ_MSGOp 00000008 ABSOLUTE ! 911: TLQ_SDP 0000001C ABSOLUTE ! 912: TLQ_index 00000020 ABSOLUTE ! 913: TLQ_pad 00000023 ABSOLUTE ! 914: TLQ_xferAdr 00000004 ABSOLUTE ! 915: TLQ_SCSI_ID 00000000 ABSOLUTE ! 916: TLQ_xferStarted 00000021 ABSOLUTE ! 917: unallocated_nexus 00000008 ABSOLUTE ! 918: unexpected_ext_msg 00000003 ABSOLUTE ! 919: unexpected_msg 00000002 ABSOLUTE ! 920: unknown_message_out 0000000B ABSOLUTE ! 921: unknown_msg_reject 0000000C ABSOLUTE ! 922: unknown_phase 00000000 ABSOLUTE ! 923: unknown_reselect 00000007 ABSOLUTE ! 924: wide_32_not_supported 00000004 ABSOLUTE ! 925: BSC_SCRIPT 00000000 CODE SEGMENT ! 926: SCRIPT 00000000 CODE SEGMENT ! 927: local_data 00000000 DATA SEGMENT ! 928: clearACK 00000448 ENTRY ! 929: issueAbort_BDR 000007F0 ENTRY ! 930: issueMessageOut 000002F0 ENTRY ! 931: phase_handler 00000290 ENTRY ! 932: select_phase 00000120 ENTRY ! 933: AbortSelect 00000760 LABEL ! 934: AbortMailbox 00000730 LABEL ! 935: BucketInData 00000888 LABEL ! 936: BucketInMsg 00000878 LABEL ! 937: BucketInStatus 00000868 LABEL ! 938: BucketOutCmd 000008B8 LABEL ! 939: BucketOutData 00000898 LABEL ! 940: bucketLoop 00000820 LABEL ! 941: bailout 00000588 LABEL ! 942: bucket_loop 000003B0 LABEL ! 943: clear_mailbox 00000258 LABEL ! 944: cmdComplete 000004C8 LABEL ! 945: command_phase 00000328 LABEL ! 946: data_in_phase 00000398 LABEL ! 947: data_out_phase 00000350 LABEL ! 948: disconnect_msg 00000560 LABEL ! 949: doItPatch 00000390 LABEL ! 950: driverXfer 00000370 LABEL ! 951: extended_msg 00000488 LABEL ! 952: fetchMailbox 00000188 LABEL ! 953: findNexusFromIndex 00000058 LABEL ! 954: getNextMsg 000006E0 LABEL ! 955: haveNexusIndex 00000710 LABEL ! 956: ignoreWideResidue 00000458 LABEL ! 957: initContext 000000C0 LABEL ! 958: message_in_phase 000003E8 LABEL ! 959: message_out_phase 000002D0 LABEL ! 960: msg_reject 00000440 LABEL ! 961: next_mailbox 00000248 LABEL ! 962: patchGetDevConfigOffset 000000F0 LABEL ! 963: patchArrayOffset 00000098 LABEL ! 964: reselect_phase 00000628 LABEL ! 965: restoreDataPointer 000005D8 LABEL ! 966: sdtr 000005F8 LABEL ! 967: saveDataPointer 000005B8 LABEL ! 968: sendAbortBDR 000008D8 LABEL ! 969: status_phase 000003C8 LABEL ! 970: taggedAbort 000007B0 LABEL ! 971: testMbxLp 000004F0 LABEL ! 972: try_reselect 00000618 LABEL ! 973: wdtr 00000608 LABEL ! 974: ld_IOdone_mailbox 00000014 RELATIVE. ! 975: ld_AbortBdr_mailbox 00000010 RELATIVE. ! 976: ld_counter 0000000C RELATIVE. ! 977: ld_device_table_base_adr 00000034 RELATIVE. ! 978: ld_mailboxp 0000001C RELATIVE. ! 979: ld_message 00000040 RELATIVE. ! 980: ld_message4 00000044 RELATIVE. ! 981: ld_nexus 0000002C RELATIVE. ! 982: ld_nexus_array_base 00000024 RELATIVE. ! 983: ld_nexus_index 00000028 RELATIVE. ! 984: ld_pad 00000048 RELATIVE. ! 985: ld_phase_flag 00000030 RELATIVE. ! 986: ld_sched_mlbx_base_adr 00000018 RELATIVE. ! 987: ld_scratch 00000038 RELATIVE. ! 988: ld_scsi_id 00000020 RELATIVE. ! 989: ld_size 0000004C RELATIVE. ! 990: ld_status 00000008 RELATIVE. ! 991: ld_unused 0000003C RELATIVE. ! 992: ld_zeroes 00000004 RELATIVE. ! 993: ld_AbortCode 00000000 RELATIVE.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.