1 ;;+++2001-10-06 2 ;; Copyright (C) 2001, Mike Rieker, Beverly, MA USA 3 ;; 4 ;; This program is free software; you can redistribute it and/or modify 5 ;; it under the terms of the GNU General Public License as published by 6 ;; the Free Software Foundation; version 2 of the License. 7 ;; 8 ;; This program is distributed in the hope that it will be useful, 9 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 10 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 ;; GNU General Public License for more details. 12 ;; 13 ;; You should have received a copy of the GNU General Public License 14 ;; along with this program; if not, write to the Free Software 15 ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 ;;---2001-10-06 17 18 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19 ; Copyright 2000,2001,2002 OZONE ENTERPRISES, BEVERLY, MA ; 20 ; ; 21 ; SCRIPTS for 53C875 chip ; 22 ; ; 23 ; Under normal conditions, this script is always running. It looks for new ; 24 ; requests to process and old targets re-connecting. Although there is code ; 25 ; to handle the case of a requestor connecting, the host CPU has the control ; 26 ; registers set up to disable a response from the chip. ; 27 ; ; 28 ; In the absense of errors, to get things going, the host CPU queues requests ; 29 ; to the scsi_id_table[scsi_id].queue_head and sets the SIGP bit in the ISTAT ; 30 ; reg. This chip then signals completion of the request by doing an INTFLY ; 31 ; instruction, then this chip processes any other requests it finds in a ; 32 ; queue. ; 33 ; ; 34 ; If an error occurrs, this chip halts and the host CPU gets an interrupt. ; 35 ; The host CPU will attempt to recover the condition and restart the chip. ; 36 ; The host CPU may decide the best recovery is to software reset this chip ; 37 ; and perform a SCSI reset, at which point it will re-load this code and re- ; 38 ; start this chip. ; 39 ; ; 40 ; Interrupts occur during these normal conditions and operation continues ; 41 ; 1) A target wants to disconnect in the middle of a transfer (like a disk ; 42 ; head seeking to a new track in a long transfer). The host CPU adjusts ; 43 ; the CHMOV/MOVE instructions and restarts this chip. ; 44 ; 2) An I/O completes. This chip does an INTFLY and continues processing ; 45 ; another request without host CPU intervention. ; 46 ; 3) A select times out. The host CPU removes all requests for this ; 47 ; scsi_id and restarts this chip. ; 48 ; Interrupts that occur for any other condition are considered fatal and ; 49 ; cause a reset of the chip and the scsi bus. ; 50 ; ; 51 ; Command tag queuing not yet supported ; 52 ; ; 53 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 54 ; 55 ARCH 875 ; chip is an 53C875 56 ; 57 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 58 ; 59 ; List of entrypoints that the host can start us at 60 ; 61 ENTRY scsi_id_table ; address of the scsi-id queue head table 62 ENTRY disconnecting ; jump here if unexpected disconnect interrupt 63 ENTRY select_timedout ; jump here after 'SELECT' timeout interrupt 64 ENTRY startup ; initialization 65 ENTRY transfer_data_done ; the list of rp_datamovs JUMP's here when done 66 ENTRY transfer_data_mismatch ; re-enter here if phase mismatch during data transfer 67 ; 68 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 69 ; 70 ; Transfer requested negotiation options 71 ; 72 ABSOLUTE REQ_ACK_OFFSET = 16 ; can send up to 16 unacknowleged data at a time 73 ABSOLUTE XFER_PERIOD_FACT = 12 ; 12=50ns (20MHz) 74 ; 75 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 76 ; 77 ; Scsi id table entry definitions 78 ; 79 ; There is one entry per possible scsi id. These are stored in the internal RAM. 80 ; The table must be aligned on a 256-byte boundary. Each element can have up to 81 ; 16 bytes. 82 ; 83 ; se_queue_head[32]: pointer to first request in queue (must be longword aligned) 84 ; <00:01> : 00 - queue is empty 85 ; 01 - new request queued 86 ; 10 - request is in progress 87 ; se_select: the next 4 bytes compose this and are used for the SELECT instruction 88 ; se0_zeroes[8]: zeroes required for SELECT instruction 89 ; se1_sxfer[8]: negotiated value (default startup value 0x00) 90 ; se2_scsi_id[8]: corresponding scsi_id for SELECT instruction 91 ; se3_scntl3[8]: negotiated value (default startup value 0x55) 92 ; se_saved_dsp[32]: save pointers' rp_datamov_pa value 93 ; <00> = 0 : no data has been transferred since save 94 ; <00> = 1 : data has been transferred since save 95 ; se_saved_dbc[32]: save pointers' contents of 0(rp_datamov_pa) 96 ; 97 ABSOLUTE se_queue_head = 0 98 ABSOLUTE se_select = 4 99 ABSOLUTE se0_zeroes = se_select + 0 100 ABSOLUTE se1_sxfer = se_select + 1 101 ABSOLUTE se2_scsi_id = se_select + 2 102 ABSOLUTE se3_scntl3 = se_select + 3 103 ABSOLUTE se_saved_dsp = 8 104 ABSOLUTE se_saved_dbc = 12 105 ; 106 ; Initialization value for longword at offset 4 107 ; 108 ABSOLUTE INIT_SCNTL3 = 0x55 109 ABSOLUTE INIT_SXFER = 0x00 110 ABSOLUTE INIT_SELECT = (INIT_SXFER << 8) | (INIT_SCNTL3 << 24) 111 ; 112 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 113 ; 114 ; Request packet definitions. There is one per outstanding I/O request. These 115 ; are stored in the host CPU's general memory. 116 ; 117 ; rp_this_va[32]: host's virtual address of this packet 118 ; rp_next_pa[32]: pointer to next request in queue 119 ; (0 if end of queue, else address with low bit set) 120 ; rp_datamov_pa[32]: pointer to data transfer CHMOV's 121 ; rp0_flags[8]: flag bits: 122 ; <0> : 0=have already done identify message 123 ; 1=have yet to do identify message (this is the initial state) 124 ; <1> : 0=don't do width negotiation 125 ; 1=do width negotiation 126 ; <2> : 0=don't do synchronous negotiation 127 ; 1=do sync negotiation 128 ; <3> : 0=disconnect not allowed 129 ; 1=disconnect allowed 130 ; <4> : 0=haven't received status yet 131 ; 1=status byte has been received 132 ; <5> : 0=request still pending 133 ; 1=request completed 134 ; <6> : 0=don't allow target to disconnect 135 ; 1=allow target to disconnect 136 ; rp1_abort[8]: 0=host wants request executed as is 137 ; else=host wants request aborted asap (set RP_FLAG_DONE and unhook abort complete) 138 ; rp2_status[8]: final scsi status byte 139 ; rp3_cmdlen[8]: number of bytes in command (1..??) 140 ; rp_command[??]: command bytes 141 ; 142 ABSOLUTE rp_this_va = 0 143 ABSOLUTE rp_next_pa = 4 144 ABSOLUTE rp_datamov_pa = 8 145 ABSOLUTE rp0_flags = 12 146 ABSOLUTE RP_FLAG_NEEDTOIDENT = 0x01 147 ABSOLUTE RP_FLAG_NEGWIDTH = 0x02 148 ABSOLUTE RP_FLAG_NEGSYNCH = 0x04 149 ABSOLUTE RP_FLAG_GOTSTATUS = 0x08 150 ABSOLUTE RP_FLAG_DONE = 0x10 151 ABSOLUTE RP_FLAG_ABORTED = 0x20 152 ABSOLUTE RP_FLAG_DISCONNECT = 0x40 153 ABSOLUTE rp1_abort = 13 154 ABSOLUTE RP_ABORT_BUFFEROVF = 1 ; this is the only one of these codes set by the SCRIPTS 155 ABSOLUTE rp2_status = 14 156 ABSOLUTE rp3_cmdlen = 15 157 ABSOLUTE rp_command = 16 158 ; 159 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 160 ; 161 ; Scratch registers 162 ; 163 ; scsi_id_entry = SCRATCHG ; scsi_id_table entry 164 ; request_packetv = SCRATCHH ; host virt address of request being processed 165 ; (only valid when SCRATCHJ1 = 1) 166 ; (... or for INT 0x69) 167 ; request_packet = SCRATCHI ; base address of request being processed 168 ; state = SCRATCHJ0 ; current state (for diag purposes only) 169 ; doing_data_xfer = SCRATCHJ1 ; used to inform host CPU when we expect that an exception might occur 170 ; scsi_index = SCRATCHJ2 ; scsi index being processed 171 ; next_scsi_index = SCRATCHJ3 ; next scsi index to be processed 172 ; 173 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 174 ; 175 ; State values kept in SCRATCHJ0 176 ; 177 ABSOLUTE STATE_IDLE = 0 178 ABSOLUTE STATE_GETTING_MESSAGE = 1 179 ABSOLUTE STATE_GETTING_STATUS = 2 180 ABSOLUTE STATE_MESSAGE_OUT = 3 181 ABSOLUTE STATE_CHECKING_TARGET = 4 182 ABSOLUTE STATE_SELECTED = 5 183 ABSOLUTE STATE_SELECTING = 6 184 ABSOLUTE STATE_SENDING_COMMAND = 7 185 ABSOLUTE STATE_TRANSFERRING_DATA = 8 186 ABSOLUTE STATE_WAITING_FOR_RESELECT = 9 187 ABSOLUTE STATE_ABORTING = 10 188 ABSOLUTE STATE_REQ_COMPLETE = 11 189 ; 190 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 191 ; 192 ; Flags that go in SCRATCHJ1. The host cpu driver uses these values when it 193 ; gets an interrupt to see if it should do anything special to process it. 194 ; 195 ABSOLUTE SCRATCHJ1_CHMOVS = 1 196 ABSOLUTE SCRATCHJ1_SELECT = 2 197 ; 198 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 199 ; 200 ; Internal memory 201 ; 202 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 203 ; 204 ; SCSI id table - this is assumed by the host CPU to be at the very beginning 205 ; of the internal memory. It is assumed by this SCRIPT processor to be on a 206 ; 256-byte boundary. 207 ; 208 00000000: 00000000 55000000 scsi_id_table: CHMOV 0, INIT_SELECT | ( 0 << 16), WHEN DATA_OUT 209 00000008: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 210 00000010: 00000000 55010000 CHMOV 0, INIT_SELECT | ( 1 << 16), WHEN DATA_OUT 211 00000018: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 212 00000020: 00000000 55020000 CHMOV 0, INIT_SELECT | ( 2 << 16), WHEN DATA_OUT 213 00000028: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 214 00000030: 00000000 55030000 CHMOV 0, INIT_SELECT | ( 3 << 16), WHEN DATA_OUT 215 00000038: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 216 00000040: 00000000 55040000 CHMOV 0, INIT_SELECT | ( 4 << 16), WHEN DATA_OUT 217 00000048: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 218 00000050: 00000000 55050000 CHMOV 0, INIT_SELECT | ( 5 << 16), WHEN DATA_OUT 219 00000058: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 220 00000060: 00000000 55060000 CHMOV 0, INIT_SELECT | ( 6 << 16), WHEN DATA_OUT 221 00000068: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 222 00000070: 00000000 55070000 CHMOV 0, INIT_SELECT | ( 7 << 16), WHEN DATA_OUT 223 00000078: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 224 00000080: 00000000 55080000 CHMOV 0, INIT_SELECT | ( 8 << 16), WHEN DATA_OUT 225 00000088: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 226 00000090: 00000000 55090000 CHMOV 0, INIT_SELECT | ( 9 << 16), WHEN DATA_OUT 227 00000098: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 228 000000A0: 00000000 550A0000 CHMOV 0, INIT_SELECT | (10 << 16), WHEN DATA_OUT 229 000000A8: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 230 000000B0: 00000000 550B0000 CHMOV 0, INIT_SELECT | (11 << 16), WHEN DATA_OUT 231 000000B8: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 232 000000C0: 00000000 550C0000 CHMOV 0, INIT_SELECT | (12 << 16), WHEN DATA_OUT 233 000000C8: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 234 000000D0: 00000000 550D0000 CHMOV 0, INIT_SELECT | (13 << 16), WHEN DATA_OUT 235 000000D8: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 236 000000E0: 00000000 550E0000 CHMOV 0, INIT_SELECT | (14 << 16), WHEN DATA_OUT 237 000000E8: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 238 000000F0: 00000000 550F0000 CHMOV 0, INIT_SELECT | (15 << 16), WHEN DATA_OUT 239 000000F8: 00000000 00000000 CHMOV 0, 0, WHEN DATA_OUT 240 ; 241 ; Misc variables 242 ; 243 00000100: 00000000 00000000 scsi_id_entry: CHMOV 0, scsi_id_table, WHEN DATA_OUT ; points to current scsi_id's entry in scsi_id_table 244 ; (copy of SCRATCHG so it can be easily LOADed into the DSA) 245 ; 246 00000108: 00000000 00000000 request_packet: CHMOV 0, 0, WHEN DATA_OUT ; points to current request packet being worked on 247 ; low 2 bits are always clear in this version 248 ; (copy of SCRATCHI so it can be easily LOADed into the DSA) 249 ; 250 00000110: 00000000 00000000 msg_buf: CHMOV 0, 0, WHEN DATA_OUT ; 8-byte temp message-in or -out buffer 251 ; 252 ; Predefined messages 253 ; 254 00000118: 000006C0 00000000 ident_abort_task_msg: CHMOV 0x06C0, 0, WHEN DATA_OUT ; IDENTIFY, ABORT TASK (0xC0, 0x06) 255 00000120: 00000006 00000000 abort_task: CHMOV 0x06, 0, WHEN DATA_OUT ; ABORT TASK (0x06) 256 00000128: 00000007 00000000 message_reject: CHMOV 0x07, 0, WHEN DATA_OUT ; MESSAGE REJECT (0x07) 257 00000130: 00000008 00000000 noop_message: CHMOV 0x08, 0, WHEN DATA_OUT ; NO-OP (0x08) 258 259 ; the 'message_ident_*' messages have their first byte modified depending on the 260 ; setting of rp0_flags<6>. 1=allow target to disconnect, 0=don't allow it. 261 00000138: 030201C0 00000001 message_ident_width: CHMOV 0x0201C0, 1, WHEN STATUS 262 ; IDENTIFY AND ALLOW DISCONNECT (0xC0), 263 ; NEGOTIATE WIDE DATA TRANSFER (0x01,0x02,0x03,1) 264 265 00000140: 010301C0 0000100C message_ident_synch: CHMOV 0x0301C0, XFER_PERIOD_FACT+(REQ_ACK_OFFSET<<8), WHEN DATA_IN 266 ; IDENTIFY AND ALLOW DISCONNECT (0xC0), 267 ; NEGOTIATE SYNCHRONOUS TRANSFER (0x01,0x03,0x01,XFER_PERIOD_FACT,REQ_ACK_OFFSET) 268 ; 269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 270 ; 271 ; This is the initial start entrypoint 272 ; 273 00000148: startup: 274 00000148: 787D0000 00000000 MOVE 0 TO SCRATCHJ1 ; we are not doing anything special 275 ; - so if host gets an interrupt (other than INTFLY), 276 ; it should consider it a fatal error 277 00000150: 787F0000 00000000 MOVE 0 TO SCRATCHJ3 ; start looking at device 0 278 00000158: E1700004 00000104 LOAD SCRATCHG0, 4, scsi_id_entry+4 ; set scsi_id_table entry pointer 279 ; 280 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 281 ; 282 ; See if there is any new request to start (or any old requests that are to be aborted) 283 ; 284 ; New requests will have the low bit set in scsi_id_table[scsi_id].queue_head 285 ; When the queue is empty, scsi_id_table[scsi_id].queue_head will be zero 286 ; When the request is in progress, scsi_id_table[scsi_id].queue_head will be non-zero with two low bits = 10 287 ; 288 00000160: select_timedout: 289 00000160: mainloop: 290 00000160: 787C0000 00000000 MOVE STATE_IDLE TO SCRATCHJ0 ; we aren't doing anything 291 00000168: 7C14DF00 00000000 MOVE ISTAT & 0xDF TO ISTAT ; about to scan loop, so clear SIGP flag bit 292 ; if host queues something while we're scanning, 293 ; ... it will set this bit again and we won't 294 ; ... hang in the WAIT RESELECT instruction 295 00000170: 7834F000 00000000 MOVE 0xF0 TO SCRATCHA0 ; max of 16 devices to scan 296 00000178: new_req_scanloop: 297 00000178: 727F0000 00000000 MOVE SCRATCHJ3 TO SFBR ; get which device to scan for 298 00000180: 6A7E0000 00000000 MOVE SFBR TO SCRATCHJ2 299 00000188: 7E7F0100 00000000 MOVE SCRATCHJ3 + 1 TO SCRATCHJ3 ; set up id of next device to check 300 00000190: 7C7F0F00 00000000 MOVE SCRATCHJ3 & 15 TO SCRATCHJ3 301 00000198: 88880000 00000830 CALL REL (get_request_packet) ; point to first request packet queued to device 302 000001A0: 808C0000 00000028 JUMP REL (check_next_scsi_id), IF 0 ; on to next device if nothing queued 303 000001A8: 808C0001 00000108 JUMP REL (got_new_req), IF 1 ; break out if we got something new 304 000001B0: E1100004 00000108 LOAD DSA0, 4, request_packet ; see if there is an old request ... 305 000001B8: F1350001 0000000D LOAD SCRATCHA1, 1, DSAREL (rp1_abort) ; ... that host CPU wants us to abort 306 000001C0: 72350000 00000000 MOVE SCRATCHA1 TO SFBR 307 000001C8: 80840000 000000C0 JUMP REL (abort_request_inprog), IF NOT 0 308 000001D0: check_next_scsi_id: 309 000001D0: 7E340100 00000000 MOVE SCRATCHA0 + 1 TO SCRATCHA0 ; nothing to do there, try next device 310 000001D8: 80A00000 FFFFFF98 JUMP REL (new_req_scanloop), IF NOT CARRY 311 ; 312 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 313 ; 314 ; Check for some target trying to reselect 315 ; Presumably, it is ready for data or status transfer 316 ; 317 000001E0: check_reselect: 318 000001E0: 787D0000 00000000 MOVE 0 TO SCRATCHJ1 ; (no longer doing the SELECT instruction) 319 000001E8: 54000000 00000078 WAIT RESELECT REL (check_select) ; wait for reselection 320 ; - this will jump to 'check_select' if either ISTAT is set 321 ; (meaning there are new requests to process) or some dumbell is 322 ; trying to select me 323 ; 324 ; Something is trying to re-select, resume processing the target 325 ; 326 000001F0: 720A0000 00000000 MOVE SSID TO SFBR ; see who is calling us 327 000001F8: 808C7F00 00000018 JUMP REL (bad_reselect_scsi_id), IF 0 AND MASK 0x7F ; bad if the 'valid' bit is not set 328 00000200: 6C7E0F00 00000000 MOVE SFBR & 0x0F TO SCRATCHJ2 ; save the scsi id in the scsi_index scratch register 329 330 00000208: 88880000 000007C0 CALL REL (get_request_packet) ; set request_packet = first queue entry for the scsi_index 331 00000210: 808C0002 00000028 JUMP REL (reselected), IF 2 ; jump if an old request is in progress on the target 332 ; if we don't have an old request, we have no 333 ; idea why this target is trying to re-connect! 334 00000218: bad_reselect_scsi_id: 335 00000218: 88880000 00000890 CALL REL (set_atn) ; reselect from unknown source, tell target we have something to tell it 336 00000220: 78020000 00000000 MOVE 0x00 TO SCNTL2 ; we expect a disconnect 337 00000228: 0E000001 00000120 MOVE 1, abort_task, WHEN MSG_OUT ; tell it to abort what it is trying to do 338 00000230: 48000000 00000000 WAIT DISCONNECT ; wait for target to disconnect from scsi bus 339 00000238: 80880000 FFFFFF20 JUMP REL (mainloop) ; go find something else to do 340 ; 341 ; Target just reselected 342 ; 343 ; Registers: 344 ; 345 ; SCRATCHG (scsi_id_entry) = points to the scsi_id_table entry for the device 346 ; SCRATCHI (request_packet) = points to the old request packet (low bits are clear) 347 ; SCRATCHJ2 (scsi_index) = scsi-id of device that reselected 348 ; DSA = scsi_id_entry 349 ; 350 00000240: reselected: 351 00000240: 88880000 00000830 CALL REL (restore_pointers) 352 00000248: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry 353 ; 354 ; Set up previously negotiated width and speed then see what target wants 355 ; 356 00000250: set_connect_params: 357 00000250: F1030001 00000007 LOAD SCNTL3, 1, DSAREL (se3_scntl3) 358 00000258: F1050001 00000005 LOAD SXFER, 1, DSAREL (se1_sxfer) 359 00000260: 80880000 000000B8 JUMP REL (check_target_state) 360 ; 361 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 362 ; 363 ; Not being reselected, maybe some idiot is trying to select me 364 ; Supposedly this should never happen as the host CPU has disabled selection as a target 365 ; 366 00000268: check_select: 367 00000268: 54000000 FFFFFEF0 WAIT SELECT REL (mainloop) ; see if someone is trying to select me 368 ; - this will jump to 'mainloop' if either ISTAT is set 369 ; (meaning there are new requests to process) or some target 370 ; is trying to reselect me 371 00000270: 06000001 00000120 MOVE 1, abort_task, WITH MSG_OUT 372 00000278: 48000000 00000000 DISCONNECT 373 00000280: 60000200 00000000 CLEAR TARGET 374 00000288: 80880000 FFFFFED0 JUMP REL (mainloop) 375 ; 376 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 377 ; 378 ; The host CPU has asked that a request in progress is to be aborted 379 ; So we tell the target to abort the task and post the request as completed 380 ; 381 00000290: abort_request_inprog: 382 00000290: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry 383 00000298: 47000004 FFFFFF40 SELECT ATN FROM se_select, REL (check_reselect) ; select the target and set previously negotiated width and speed 384 ; - a jump to check_reselect is made if either someone is trying to 385 ; reselect me or if the host CPU sets the SIGP bit 386 ; - if this select times out, the host CPU will abort all requests 387 ; queued to the device anyway before restarting me 388 000002A0: 78020000 00000000 MOVE 0x00 TO SCNTL2 ; we expect a disconnect 389 000002A8: 0E000002 00000118 MOVE 2, ident_abort_task_msg, WHEN MSG_OUT ; ... after we tell it to F0A9+4 390 000002B0: 80880000 000003E0 JUMP REL (abort_request_markit) 391 ; 392 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 393 ; 394 ; New request found, try to select the device. If another target tries to 395 ; reselect us in the mean time, forget about this for now and go process it. 396 ; 397 ; Registers: 398 ; 399 ; SCRATCHG (scsi_id_entry) = points to the scsi_id_table entry for the device 400 ; SCRATCHI (request_packet) = points to the new request packet (low bits are clear) 401 ; SCRATCHJ2 (scsi_index) = scsi-id of device that has a new request 402 ; 403 000002B8: got_new_req: 404 000002B8: E1100004 00000108 LOAD DSA0, 4, request_packet ; see if host CPU wants this request aborted 405 000002C0: F1350001 0000000D LOAD SCRATCHA1, 1, DSAREL (rp1_abort) 406 000002C8: 72350000 00000000 MOVE SCRATCHA1 TO SFBR 407 000002D0: 80840000 000003E0 JUMP REL (req_complete_ab), IF NOT 0 ; if so, go post it as completed 408 000002D8: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry 409 000002E0: 787C0600 00000000 MOVE STATE_SELECTING TO SCRATCHJ0 ; set the state to 'SELECTING' 410 000002E8: 787D0200 00000000 MOVE SCRATCHJ1_SELECT TO SCRATCHJ1 ; tell host CPU that this is THE select so it knows to do recovery 411 000002F0: 47000004 FFFFFEE8 SELECT ATN FROM se_select, REL (check_reselect) ; select the target and set previously negotiated width and speed 412 ; a jump is made to 'check_reselect' if someone is trying to (re)select 413 ; - note that SIGP is probably still clear so the WAIT instructions should 414 ; do their job. If SIGP was set by the host in the mean time, this idiot 415 ; computer skips the WAIT instructions and thus we should end up right 416 ; back here very quickly only to do it all over again (but hopefully with 417 ; SIGP cleared) 418 ; if this times out, host CPU will jump to 'select_timedout' 419 ; - the host aborts all requests from the queue first, however 420 ; - it also clears SCRATCHJ1 for us 421 ; - the jump goes back to clear SIGP and re-scan for more requests to start 422 000002F8: 787D0000 00000000 MOVE 0 TO SCRATCHJ1 ; (no longer doing the SELECT instruction) 423 ; 424 ; We have selected the target, mark the queue entry as being 'in progress' by clearing se_queue_head <00> and setting <01> 425 ; Also, clear the low bit in queue_head entry so we won't think we need to select again 426 ; 427 00000300: 787C0500 00000000 MOVE STATE_SELECTED TO SCRATCHJ0 ; set the state to 'SELECTED' 428 00000308: 72780200 00000000 MOVE SCRATCHI0 | 0x02 TO SFBR ; bit <00> is already clear, so just set bit <01> 429 00000310: F2080001 00000000 STORE NOFLUSH SFBR, 1, DSAREL (se_queue_head) ; store the request_packet pointer with appropriate low bits 430 ; 431 ; Save the initial data pointer 432 ; 433 00000318: 88880000 00000718 CALL REL (save_data_pointer) 434 ; 435 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 436 ; 437 ; Now see what target wants to do - it tells us by what phase it is in 438 ; 439 ; Registers: 440 ; 441 ; SCRATCHJ2 (scsi_index) = the scsi-id of the device we are processing 442 ; SCRATCHG (scsi_id_entry) = points to entry in the scsi_id_table that we are processing 443 ; SCRATCHI (request_packet) = points to the request packet for the device 444 ; 445 00000320: check_target_state: 446 00000320: 787C0400 00000000 MOVE STATE_CHECKING_TARGET TO SCRATCHJ0 ; set state to 'checking target' 447 00000328: 868B0000 00000030 JUMP REL (transfer_message_out), WHEN MSG_OUT ; now see what the target wants to do 448 ; ?? - it seems that we get the 'select timeout' interrupt 449 ; ?? here instead of at the SELECT instruction above! 450 ; ?? so the host CPU is going to have to deal with that! 451 ; ?? - also got an 'unexpected disconnect' here so we have 452 ; ?? the host CPU jump to 'disconnecting' label below 453 00000330: 828A0000 00000268 JUMP REL (transfer_command), IF CMD 454 00000338: 818A0000 000002C0 JUMP REL (transfer_data_in), IF DATA_IN 455 00000340: 808A0000 000002B8 JUMP REL (transfer_data_out), IF DATA_OUT 456 00000348: 838A0000 00000378 JUMP REL (transfer_status), IF STATUS 457 00000350: 878A0000 000003B8 JUMP REL (transfer_message_in), IF MSG_IN 458 00000358: 98080000 000000A1 INT 0xA1 ; don't know what to do - target has gone nuts 459 ; 460 ; Target is ready to accept a message from us 461 ; We generally have three messages to send it (in this order): 462 ; 1) Identify (always) 463 ; 2) Negotiate width (optional) 464 ; 3) Negotiate speed (optional) 465 ; 466 00000360: transfer_message_out: 467 00000360: 787C0300 00000000 MOVE STATE_MESSAGE_OUT TO SCRATCHJ0 ; set up new state 468 00000368: E1100004 00000108 LOAD DSA0, 4, request_packet ; see what messages we have yet to send 469 00000370: F1340001 0000000C LOAD SCRATCHA0, 1, DSAREL (rp0_flags) 470 00000378: 72340000 00000000 MOVE SCRATCHA0 TO SFBR 471 00000380: 808CF801 00000030 JUMP REL (send_message_ident), IF RP_FLAG_NEEDTOIDENT AND MASK 0xFF - (RP_FLAG_NEGSYNCH | RP_FLAG_NEGWIDTH | RP_FLAG_NEEDTOIDENT) 472 00000388: 808CFC02 00000098 JUMP REL (send_message_width), IF RP_FLAG_NEGWIDTH AND MASK 0xFF - ( RP_FLAG_NEGWIDTH | RP_FLAG_NEEDTOIDENT) 473 00000390: 808CFC03 00000058 JUMP REL (send_message_ident_width), IF RP_FLAG_NEGWIDTH | RP_FLAG_NEEDTOIDENT AND MASK 0xFF - ( RP_FLAG_NEGWIDTH | RP_FLAG_NEEDTOIDENT) 474 00000398: 808CF804 00000168 JUMP REL (send_message_synch), IF RP_FLAG_NEGSYNCH AND MASK 0xFF - (RP_FLAG_NEGSYNCH | RP_FLAG_NEGWIDTH | RP_FLAG_NEEDTOIDENT) 475 000003A0: 808CF805 00000128 JUMP REL (send_message_ident_synch), IF RP_FLAG_NEGSYNCH | RP_FLAG_NEEDTOIDENT AND MASK 0xFF - (RP_FLAG_NEGSYNCH | RP_FLAG_NEGWIDTH | RP_FLAG_NEEDTOIDENT) 476 477 000003A8: 0E000001 00000130 MOVE 1, noop_message, WHEN MSG_OUT ; we have nothing to send, so send a noop (this also clears the ATN bit) 478 000003B0: 80880000 FFFFFF68 JUMP REL (check_target_state) 479 480 000003B8: send_message_ident: 481 000003B8: 6C08FE00 00000000 MOVE SFBR & 0xFF - RP_FLAG_NEEDTOIDENT TO SFBR ; clear flag bit 482 000003C0: F2080001 0000000C STORE NOFLUSH SFBR, 1, DSAREL (rp0_flags) 483 000003C8: 6C084000 00000000 MOVE SFBR & 0x40 TO SFBR ; get 'allow disconnects' flag bit 484 000003D0: 6A088000 00000000 MOVE SFBR | 0x80 TO SFBR ; make the 'identify' message code 485 000003D8: E2080001 00000138 STORE NOFLUSH SFBR, 1, message_ident_width ; store in message to be sent 486 000003E0: 0E000001 00000138 MOVE 1, message_ident_width, WHEN MSG_OUT ; send ident message (this also clears the ATN bit) 487 000003E8: 80880000 FFFFFF30 JUMP REL (check_target_state) 488 489 000003F0: send_message_ident_width: 490 000003F0: 6C08FC00 00000000 MOVE SFBR & 0xFF - (RP_FLAG_NEEDTOIDENT | RP_FLAG_NEGWIDTH) TO SFBR ; clear flag bits 491 000003F8: F2080001 0000000C STORE NOFLUSH SFBR, 1, DSAREL (rp0_flags) 492 00000400: 6C084000 00000000 MOVE SFBR & 0x40 TO SFBR ; get 'allow disconnects' flag bit 493 00000408: 6A088000 00000000 MOVE SFBR | 0x80 TO SFBR ; make the 'identify' message code 494 00000410: E2080001 00000138 STORE NOFLUSH SFBR, 1, message_ident_width ; store in message to be sent 495 00000418: 0E000005 00000138 MOVE 5, message_ident_width, WHEN MSG_OUT ; send ident and width messages (this also clears the ATN bit) 496 00000420: 80880000 00000018 JUMP REL (proc_width_reply) 497 498 00000428: send_message_width: 499 00000428: 6C08FD00 00000000 MOVE SFBR & 0xFF - RP_FLAG_NEGWIDTH TO SFBR ; clear flag bit 500 00000430: F2080001 0000000C STORE NOFLUSH SFBR, 1, DSAREL (rp0_flags) 501 00000438: 0E000004 00000139 MOVE 4, message_ident_width+1, WHEN MSG_OUT ; send width message (this also clears the ATN bit) 502 503 proc_width_reply: 504 00000440: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN ; read the reply, byte-by-byte 505 00000448: 80840001 00000488 JUMP REL (bad_nego_mess), IF NOT 0x01 ; - it must be an extended message 506 00000450: 60000040 00000000 CLEAR ACK 507 00000458: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN 508 00000460: 80840002 00000478 JUMP REL (bad_nego_mess_reject), IF NOT 0x02 ; - it must have length 2 509 00000468: 60000040 00000000 CLEAR ACK 510 00000470: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN 511 00000478: 80840003 00000460 JUMP REL (bad_nego_mess_reject), IF NOT 0x03 ; - it must be a 'wide data transfer' message 512 00000480: 60000040 00000000 CLEAR ACK 513 00000488: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN ; ok, get the resultant width (either 8 or 16 bits) 514 00000490: 88880000 000006D0 CALL REL (save_transfer_width) ; save it in memory 515 00000498: E1100004 00000108 LOAD DSA0, 4, request_packet ; see if we have to send synchronous negotiation message, too 516 000004A0: F1340001 0000000C LOAD SCRATCHA0, 1, DSAREL (rp0_flags) 517 000004A8: 72340000 00000000 MOVE SCRATCHA0 TO SFBR 518 000004B0: 808CFB00 00000008 JUMP REL (proc_width_reply_clear_ack), IF 0 AND MASK 0xFF - RP_FLAG_NEGSYNCH 519 000004B8: 58000008 00000000 SET ATN ; need to do synch negotiation, tell target we have another message 520 proc_width_reply_clear_ack: 521 000004C0: 60000040 00000000 CLEAR ACK ; anyway, clear ack to indicate we got all the incoming message 522 000004C8: 80880000 FFFFFD80 JUMP REL (set_connect_params) ; set up new width 523 524 000004D0: send_message_ident_synch: 525 000004D0: 6C08FA00 00000000 MOVE SFBR & 0xFF - (RP_FLAG_NEEDTOIDENT | RP_FLAG_NEGSYNCH) TO SFBR ; clear flag bits 526 000004D8: F2080001 0000000C STORE NOFLUSH SFBR, 1, DSAREL (rp0_flags) 527 000004E0: 6C084000 00000000 MOVE SFBR & 0x40 TO SFBR ; get 'allow disconnects' flag bit 528 000004E8: 6A088000 00000000 MOVE SFBR | 0x80 TO SFBR ; make the 'identify' message code 529 000004F0: E2080001 00000138 STORE NOFLUSH SFBR, 1, message_ident_width ; store in message to be sent 530 000004F8: 0E000006 00000140 MOVE 6, message_ident_synch, WHEN MSG_OUT ; send ident and synch messages (this also clears the ATN bit) 531 00000500: 80880000 00000018 JUMP REL (proc_synch_reply) 532 533 00000508: send_message_synch: 534 00000508: 6C08FB00 00000000 MOVE SFBR & 0xFF - RP_FLAG_NEGSYNCH TO SFBR ; clear flag bit 535 00000510: F2080001 0000000C STORE NOFLUSH SFBR, 1, DSAREL (rp0_flags) 536 00000518: 0E000005 00000141 MOVE 5, message_ident_synch+1, WHEN MSG_OUT ; send synch message (this also clears the ATN bit) 537 538 proc_synch_reply: 539 00000520: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN ; read the reply, byte-by-byte 540 00000528: 80840001 000003A8 JUMP REL (bad_nego_mess), IF NOT 0x01 ; - it must be an extended message 541 00000530: 60000040 00000000 CLEAR ACK 542 00000538: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN 543 00000540: 80840003 00000398 JUMP REL (bad_nego_mess_reject), IF NOT 0x03 ; - it must have length 3 544 00000548: 60000040 00000000 CLEAR ACK 545 00000550: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN 546 00000558: 80840001 00000380 JUMP REL (bad_nego_mess_reject), IF NOT 0x01 ; - it must be a 'synchronous data transfer' message 547 00000560: 60000040 00000000 CLEAR ACK 548 00000568: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN ; ok, get the resultant tranfer period factor 549 00000570: 88880000 00000628 CALL REL (save_transfer_period) ; save it in memory 550 00000578: 60000040 00000000 CLEAR ACK 551 00000580: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN ; get the resultant req/ack offset 552 00000588: 88880000 00000688 CALL REL (save_req_ack_offset) ; save it in memory 553 00000590: 60000040 00000000 CLEAR ACK ; clear ack to indicate we got all the incoming message 554 00000598: 80880000 FFFFFCB0 JUMP REL (set_connect_params) ; set up new speed 555 ; 556 ; Target is ready to accept the command from us 557 ; 558 000005A0: transfer_command: 559 000005A0: 787C0700 00000000 MOVE STATE_SENDING_COMMAND TO SCRATCHJ0 ; set state 'sending command' 560 000005A8: E1100004 00000108 LOAD DSA0, 4, request_packet ; point to the request packet 561 000005B0: F1370001 0000000F LOAD SCRATCHA3, 1, DSAREL (rp3_cmdlen) ; get length of command 562 000005B8: 72370000 00000000 MOVE SCRATCHA3 TO SFBR 563 000005C0: E2080001 000005F0 STORE NOFLUSH SFBR, 1, command_move+0 ; store in the 'command_move' instruction 564 000005C8: 7E101000 00000000 MOVE DSA0 + rp_command TO DSA0 ; point to the command bytes 565 000005D0: 7F110000 00000000 MOVE DSA1 + 0 TO DSA1 WITH CARRY 566 000005D8: 7F120000 00000000 MOVE DSA2 + 0 TO DSA2 WITH CARRY 567 000005E0: 7F130000 00000000 MOVE DSA3 + 0 TO DSA3 WITH CARRY 568 000005E8: E0100004 000005F4 STORE DSA0, 4, command_move+4 569 000005F0: command_move: 570 000005F0: 0A000000 00000000 MOVE 0, 0, WHEN CMD ; transfer the command bytes to the target 571 000005F8: 80880000 FFFFFD20 JUMP REL (check_target_state) ; now see what target wants to do 572 ; 573 ; Target is ready to transfer data 574 ; 575 00000600: transfer_data_in: 576 00000600: transfer_data_out: 577 00000600: 787C0800 00000000 MOVE STATE_TRANSFERRING_DATA TO SCRATCHJ0 ; set state 'transferring data' 578 00000608: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry ; remember pointer is about to be moved 579 00000610: F1340001 00000008 LOAD SCRATCHA0, 1, DSAREL (se_saved_dsp) ; ... by setting se_saved_dsp<00> 580 00000618: 7A340100 00000000 MOVE SCRATCHA0 | 0x01 TO SCRATCHA0 ; ... so restore_pointers knows it has work to do 581 00000620: F2340001 00000008 STORE NOFLUSH SCRATCHA0, 1, DSAREL (se_saved_dsp) 582 00000628: E1100004 00000108 LOAD DSA0, 4, request_packet ; point to the request packet 583 00000630: F11C0004 00000008 LOAD TEMP0, 4, DSAREL (rp_datamov_pa) ; get where the CHMOV's are 584 00000638: F1740004 00000000 LOAD SCRATCHH0, 4, DSAREL (rp_this_va) ; get virt address of request packet (for host CPU in case of interrupt) 585 00000640: 787D0100 00000000 MOVE SCRATCHJ1_CHMOVS TO SCRATCHJ1 ; set the 'CHMOV in progress' flag 586 00000648: 90080000 00000000 RETURN ; execute the CHMOV's (jumps to address in TEMP) 587 ; code will jump to 'transfer_data_done' if it gets to the end ok 588 ; otherwise, if a phase mismatch occurrs, the host cpu will modify 589 ; the 'rp_datamov_pa' pointer accordingly then jump to 590 ; 'transfer_data_mismatch' 591 ; 592 00000650: transfer_data_done2: 593 00000650: F21C0004 00000008 STORE NOFLUSH TEMP0, 4, DSAREL (rp_datamov_pa) ; set rp_datamov_pa = transfer_no_data 594 00000658: transfer_data_mismatch: 595 00000658: 787D0000 00000000 MOVE 0 TO SCRATCHJ1 ; clear the 'CHMOV in progress' flag 596 00000660: 80880000 FFFFFCB8 JUMP REL (check_target_state) ; go see what target wants now 597 ; 598 00000668: transfer_data_done: 599 00000668: 88880000 FFFFFFE0 CALL REL (transfer_data_done2) ; set TEMP = transfer_no_data and jump 600 00000670: transfer_no_data: 601 00000670: 88880000 00000438 CALL REL (set_atn) ; target has/wants more data but there isn't any (room) left 602 00000678: 78020000 00000000 MOVE 0x00 TO SCNTL2 ; - we expect a disconnect 603 00000680: 0E000001 00000120 MOVE 1, abort_task, WHEN MSG_OUT ; - send it a nasty message 604 00000688: 78350100 00000000 MOVE RP_ABORT_BUFFEROVF TO SCRATCHA1 ; set up abort code 605 00000690: F2350001 0000000D STORE NOFLUSH SCRATCHA1, 1, DSAREL (rp1_abort) 606 00000698: abort_request_markit: 607 00000698: F1340001 0000000C LOAD SCRATCHA0, 1, DSAREL (rp0_flags) ; tell the host we sent the target an 'abort task' message 608 000006A0: 7A342000 00000000 MOVE SCRATCHA0 | RP_FLAG_ABORTED TO SCRATCHA0 609 000006A8: F2340001 0000000C STORE NOFLUSH SCRATCHA0, 1, DSAREL (rp0_flags) 610 000006B0: 48000000 00000000 WAIT DISCONNECT ; target responds by disconnecting 611 000006B8: req_complete_ab: 612 000006B8: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry ; go mark the request complete and tell host CPU 613 000006C0: 80880000 000002A0 JUMP REL (req_complete2) 614 ; 615 ; Target has status byte ready for us 616 ; 617 000006C8: transfer_status: 618 000006C8: 787C0200 00000000 MOVE STATE_GETTING_STATUS TO SCRATCHJ0 ; set state 'getting status' 619 000006D0: 0B000001 00000110 MOVE 1, msg_buf, WHEN STATUS ; read the status byte 620 000006D8: 6A360000 00000000 MOVE SFBR TO SCRATCHA2 621 000006E0: E1100004 00000108 LOAD DSA0, 4, request_packet ; store in request packet struct 622 000006E8: F2360001 0000000E STORE NOFLUSH SCRATCHA2, 1, DSAREL (rp2_status) 623 000006F0: F1340001 0000000C LOAD SCRATCHA0, 1, DSAREL (rp0_flags) ; ... and say that we got it 624 000006F8: 7A340800 00000000 MOVE SCRATCHA0 | RP_FLAG_GOTSTATUS TO SCRATCHA0 625 00000700: F0340001 0000000C STORE SCRATCHA0, 1, DSAREL (rp0_flags) 626 00000708: 80880000 FFFFFC10 JUMP REL (check_target_state) 627 ; 628 ; Target has an unsolicited message for us 629 ; 630 00000710: transfer_message_in: 631 00000710: 787C0100 00000000 MOVE STATE_GETTING_MESSAGE TO SCRATCHJ0 ; set state 'getting message' 632 00000718: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN ; see what the target wants 633 00000720: 808C0000 00000228 JUMP REL (req_complete), IF 0x00 ; 00 means the request is now complete 634 00000728: 808C0001 00000080 JUMP REL (got_extended_message), IF 0x01 ; check for 'extended' messages 635 00000730: 808C0002 00000040 JUMP REL (save_data_pointer_ack), IF 0x02 ; 02 means to save data transfer pointer 636 00000738: 808C0003 00000050 JUMP REL (restore_pointers_ack), IF 0x03 ; 03 means to restore transfer pointers 637 00000740: 808C0004 000001E0 JUMP REL (disconnecting), IF 0x04 ; 04 means it is disconnecting and will reselect us later 638 00000748: 808C0007 00000030 JUMP REL (ignore_message), IF 0x07 ; skip over reject's 639 00000750: 808C0008 00000028 JUMP REL (ignore_message), IF 0x08 ; skip over nop's 640 00000758: 808C7F80 00000020 JUMP REL (ignore_message), IF 0x80 AND MASK 0x7F ; ignore all identify messages from target 641 642 00000760: reject_message: 643 00000760: 88880000 00000348 CALL REL (set_atn) ; tell target we are rejecting its message 644 00000768: 0E000001 00000128 MOVE 1, message_reject, WHEN MSG_OUT ; send reject message, clear ATN 645 00000770: 80880000 FFFFFBA8 JUMP REL (check_target_state) 646 647 00000778: save_data_pointer_ack: 648 00000778: 88880000 000002B8 CALL REL (save_data_pointer) ; save current data pointer 649 00000780: ignore_message: 650 00000780: 60000040 00000000 CLEAR ACK ; acknowledge it 651 00000788: 80880000 FFFFFB90 JUMP REL (check_target_state) ; go see what target wants now 652 653 00000790: restore_pointers_ack: 654 00000790: 60000040 00000000 CLEAR ACK ; acknowledge it 655 00000798: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry ; go restore pointers 656 000007A0: 88880000 000002D0 CALL REL (restore_pointers) 657 000007A8: 80880000 FFFFFB70 JUMP REL (check_target_state) 658 659 000007B0: got_extended_message: 660 000007B0: 60000040 00000000 CLEAR ACK 661 000007B8: 0F000002 00000110 MOVE 2, msg_buf, WHEN MSG_IN ; get extended message length and code 662 000007C0: E1340002 00000110 LOAD SCRATCHA0, 2, msg_buf ; get length in A0, code in A1 663 000007C8: 72350000 00000000 MOVE SCRATCHA1 TO SFBR ; check out the code 664 000007D0: 808C0001 00000074 JUMP REL (got_sync_data_xfer_msg), IF 0x01 665 000007D8: 808C0003 00000008 JUMP REL (got_wide_data_xfer_msg), IF 0x03 666 000007E0: 80880000 FFFFFF78 JUMP REL (reject_message) 667 668 000007E8: got_wide_data_xfer_msg: 669 000007E8: 72340000 00000000 MOVE SCRATCHA0 TO SFBR ; make sure the length is 2 670 000007F0: 80840002 000000E8 JUMP REL (bad_nego_mess_reject), IF NOT 0x02 671 000007F8: 60000040 00000000 CLEAR ACK 672 00000800: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN ; get the requested width factor 673 00000808: 60000040 00000000 CLEAR ACK ; tell target we got the last byte of message 674 00000810: C1000008 00000138 00000110 MOVE MEMORY NOFLUSH 8, message_ident_width, msg_buf ; copy a template message 675 0000081C: 808C0000 00000008 JUMP REL (width_ok), IF 0 ; width 0 (8-bits) is ok as is 676 00000824: 78080100 00000000 MOVE 1 TO SFBR ; else, do width 1 (16-bits) 677 0000082C: width_ok: 678 0000082C: E2080001 00000114 STORE NOFLUSH SFBR, 1, msg_buf+4 ; save it in outgoing message buffer 679 00000834: 88880000 0000032C CALL REL (save_transfer_width) ; save negotiated width in scsi_id_table entry 680 0000083C: 0E000004 00000111 MOVE 4, msg_buf+1, WHEN MSG_OUT ; send reply message 681 00000844: 80880000 FFFFFA04 JUMP REL (set_connect_params) ; go set up new width 682 683 0000084C: got_sync_data_xfer_msg: 684 0000084C: 72340000 00000000 MOVE SCRATCHA0 to SFBR ; make sure the length is 3 685 00000854: 80840003 00000084 JUMP REL (bad_nego_mess_reject), IF NOT 0x03 686 0000085C: 60000040 00000000 CLEAR ACK 687 00000864: 0F000002 00000110 MOVE 2, msg_buf, WHEN MSG_IN ; get the transfer period factor and req/ack offset bytes 688 0000086C: 60000040 00000000 CLEAR ACK ; tell target we got the last bytes of message 689 00000874: E15D0001 00000111 LOAD SCRATCHB1, 1, msg_buf+1 ; save req/ack offset factor 690 0000087C: C1000008 00000140 00000110 MOVE MEMORY NOFLUSH 8, message_ident_synch, msg_buf ; set up a template message 691 00000888: 88880000 00000310 CALL REL (save_transfer_period) ; process negotiated speed setting 692 00000890: 72360000 00000000 MOVE SCRATCHA2 TO SFBR ; save it in reply message buffer 693 00000898: E2080001 00000114 STORE NOFLUSH SFBR, 1, msg_buf+4 694 000008A0: 725D0000 00000000 MOVE SCRATCHB1 TO SFBR ; get requested req/ack offset 695 000008A8: 88880000 00000368 CALL REL (save_req_ack_offset) ; process it 696 000008B0: 72360000 00000000 MOVE SCRATCHA2 TO SFBR ; save negotiated value in reply message 697 000008B8: 6A350000 00000000 MOVE SFBR TO SCRATCHA1 698 000008C0: E2350001 00000115 STORE NOFLUSH SCRATCHA1, 1, msg_buf+5 699 000008C8: 0E000005 00000111 MOVE 5, msg_buf+1, WHEN MSG_OUT ; send reply message 700 000008D0: 80880000 FFFFF978 JUMP REL (set_connect_params) ; go set up new speed 701 ; 702 ; Something was bad about the negotiation reply or request, send reject then set up async mode 703 ; 704 000008D8: bad_nego_mess: 705 000008D8: 808C0007 00000010 JUMP REL (bad_nego_mess_async), IF 0x07 ; maybe it is rejecting my request 706 000008E0: bad_nego_mess_reject: 707 000008E0: 88880000 000001C8 CALL REL (set_atn) ; something else bad with message, reject it 708 000008E8: 0E000001 00000128 MOVE 1, message_reject, WHEN MSG_OUT 709 000008F0: bad_nego_mess_async: 710 000008F0: 60000040 00000000 CLEAR ACK 711 000008F8: 78375500 00000000 MOVE INIT_SCNTL3 TO SCRATCHA3 ; set up async transfer mode 712 00000900: 78350000 00000000 MOVE INIT_SXFER TO SCRATCHA1 713 00000908: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry 714 00000910: F2370001 00000007 STORE NOFLUSH SCRATCHA3, 1, DSAREL (se3_scntl3) 715 00000918: F2350001 00000005 STORE NOFLUSH SCRATCHA1, 1, DSAREL (se1_sxfer) 716 00000920: 80880000 FFFFF928 JUMP REL (set_connect_params) 717 ; 718 ; Target is disconnecting, remember the state and go do something else in the mean time 719 ; 720 00000928: disconnecting: 721 00000928: 78020000 00000000 MOVE 0x00 TO SCNTL2 ; we expect a disconnect 722 00000930: 60000040 00000000 CLEAR ACK ; acknowledge it 723 00000938: 787C0900 00000000 MOVE STATE_WAITING_FOR_RESELECT TO SCRATCHJ0 ; remember we're waiting for a reselect from it 724 00000940: 48000000 00000000 WAIT DISCONNECT ; wait for target to disconnect from scsi bus 725 00000948: 80880000 FFFFF810 JUMP REL (mainloop) ; go find something else to do 726 ; 727 ; The request is complete - unlink it from queue and do an INTFLY to notify host CPU that a request just completed 728 ; 729 00000950: req_complete: 730 00000950: 78020000 00000000 MOVE 0x00 TO SCNTL2 ; we expect a disconnect 731 00000958: 60000040 00000000 CLEAR ACK ; acknowledge it 732 00000960: 48000000 00000000 WAIT DISCONNECT ; wait for target to disconnect from scsi bus 733 00000968: req_complete2: 734 00000968: 787C0B00 00000000 MOVE STATE_REQ_COMPLETE TO SCRATCHJ0 ; posting a request's completion 735 00000970: E1100004 00000108 LOAD DSA0, 4, request_packet 736 00000978: 7A141000 00000000 MOVE ISTAT | 0x10 TO ISTAT ; set the SEM bit to let host know were modifying queue and RP_FLAG_DONE 737 00000980: F1340004 00000004 LOAD SCRATCHA0, 4, DSAREL (rp_next_pa) ; find the next item in the list (it is either zero or has the low bit set) 738 00000988: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry 739 00000990: F2340004 00000000 STORE NOFLUSH SCRATCHA0, 4, DSAREL (se_queue_head) ; unlink request from queue 740 00000998: E1100004 00000108 LOAD DSA0, 4, request_packet 741 000009A0: F1340001 0000000C LOAD SCRATCHA0, 1, DSAREL (rp0_flags) ; flag the request as 'done' 742 000009A8: 7A341000 00000000 MOVE SCRATCHA0 | RP_FLAG_DONE TO SCRATCHA0 743 000009B0: F0340001 0000000C STORE SCRATCHA0, 1, DSAREL (rp0_flags) 744 000009B8: 7C14EF00 00000000 MOVE ISTAT & 0xEF TO ISTAT ; clear SEM bit to let host know were done with mods 745 000009C0: 98180000 00000000 INTFLY ; tell the host computer that a request completed 746 000009C8: 80880000 FFFFF790 JUMP REL (mainloop) ; go find something to do 747 ; 748 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 749 ; 750 ; Get pointer to first request packet queued to a scsi device 751 ; 752 ; Input: 753 ; 754 ; SCRATCHG = some entry of the scsi_id_table (not necessarily the one we want) 755 ; SCRATCHJ2 (scsi_index) = scsi id to get packet for 756 ; 757 ; Output: 758 ; 759 ; SCRATCHI (request_packet) = address of queued packet (with low bits cleared) 760 ; SCRATCHG (scsi_id_entry) = DSA = points to scsi_id_table entry 761 ; SBFR = 0 : nothing queued, device is idle 762 ; 1 : new request queued, needs to be started 763 ; 2 : old request in progress, waiting for reselect 764 ; 765 000009D0: get_request_packet: 766 ; 767 ; We point SCRATCHG and scsi_id_entry at the entry in the scsi_id_table 768 ; corresponding to the device in question. It is here that we assume 769 ; the scsi_id_table is on a 256-byte boundary so we don't have to worry 770 ; about adding and carry bits. 771 ; 772 000009D0: 727E0000 00000000 MOVE SCRATCHJ2 TO SFBR ; multiply scsi_index by 16 to get offset in scsi_id_table 773 000009D8: 6E700000 00000000 MOVE SFBR + 0 TO SCRATCHG0 ; (the '+ 0' hopefully clears carry bit for subsequent SHL's) 774 000009E0: 79700000 00000000 MOVE SCRATCHG0 SHL SCRATCHG0 775 000009E8: 79700000 00000000 MOVE SCRATCHG0 SHL SCRATCHG0 776 000009F0: 79700000 00000000 MOVE SCRATCHG0 SHL SCRATCHG0 777 000009F8: 79700000 00000000 MOVE SCRATCHG0 SHL SCRATCHG0 778 00000A00: E2700004 00000100 STORE NOFLUSH SCRATCHG0, 4, scsi_id_entry ; save it for easy loading into DSA 779 ; 780 ; We point SCRATCHI and request_packet at the top packet on the queue for 781 ; the device in question. SCRATCHI and request_packet have the low 2 bits 782 ; cleared. The low 2 bits are returned in SFBR for easy testing on return. 783 ; 784 00000A08: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry ; point the DSA at the scsi_id_table entry for the device 785 00000A10: F1780004 00000000 LOAD SCRATCHI0, 4, DSAREL (se_queue_head) ; load the scsi_id_table[scsi_index].queue_head entry into 'request_packet' 786 00000A18: 74780300 00000000 MOVE SCRATCHI0 & 0x03 TO SFBR ; save low 2 bits 787 00000A20: 7C78FC00 00000000 MOVE SCRATCHI0 & 0xFC TO SCRATCHI0 ; clear them in the pointer register 788 00000A28: E2780004 00000108 STORE NOFLUSH SCRATCHI0, 4, request_packet ; save it for easy loading into DSA later 789 ; 790 00000A30: 90080000 00000000 RETURN 791 ; 792 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 793 ; 794 ; Save data pointers 795 ; 796 00000A38: save_data_pointer: 797 00000A38: E1100004 00000108 LOAD DSA0, 4, request_packet ; get current pointer 798 00000A40: F1340004 00000008 LOAD SCRATCHA0, 4, DSAREL (rp_datamov_pa) ; get address of chmov 799 00000A48: F1100004 00000008 LOAD DSA0, 4, DSAREL (rp_datamov_pa) ; point to the chmov 800 00000A50: F15C0004 00000000 LOAD SCRATCHB0, 4, DSAREL (0) ; get move bytecount 801 00000A58: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry ; point to scsi_id_table entry 802 00000A60: F2340004 00000008 STORE NOFLUSH SCRATCHA0, 4, DSAREL (se_saved_dsp) ; save datapointer 803 00000A68: F25C0004 0000000C STORE NOFLUSH SCRATCHB0, 4, DSAREL (se_saved_dbc) 804 00000A70: 90080000 00000000 RETURN 805 ; 806 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 807 ; 808 ; Restore pointers to their last saved state 809 ; 810 00000A78: restore_pointers: 811 00000A78: F1340001 00000008 LOAD SCRATCHA0, 1, DSAREL (se_saved_dsp) ; see if restore required 812 00000A80: 7D340000 00000000 MOVE SCRATCHA0 SHR SCRATCHA0 813 00000A88: 90200000 00000000 RETURN, IF NOT CARRY ; (only if <00> is set) 814 00000A90: E1100004 00000108 LOAD DSA0, 4, request_packet ; point to request packet 815 00000A98: F1740004 00000000 LOAD SCRATCHH0, 4, DSAREL (rp_this_va) ; get its va for host CPU 816 00000AA0: 98080000 00000069 INT 0x69 ; have host CPU fix it 817 ; - it restores the whole rp_datachmovs list 818 ; - it restores rp_datamov_pa from se_saved_dsp 819 ; - it modifies that instr w/ se_saved_dnad 820 00000AA8: 90080000 00000000 RETURN 821 ; 822 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 823 ; 824 ; Set ATN and wait for target to enter MSG_OUT phase 825 ; 826 ; Output: 827 ; 828 ; target now in MSG_OUT phase 829 ; 830 ; Scratch: 831 ; 832 ; SFBR, msg_buf[0] 833 ; 834 00000AB0: set_atn: 835 00000AB0: 58000008 00000000 SET ATN ; tell target we have something to say 836 00000AB8: set_atn_clrack: 837 00000AB8: 60000040 00000000 CLEAR ACK ; in case last thing was a MSG_IN 838 00000AC0: set_atn_loop: 839 00000AC0: 960B0000 00000000 RETURN, WHEN MSG_OUT ; if target is in MSG_OUT, return to caller 840 00000AC8: 818B0000 00000028 JUMP REL (set_atn_data_in), WHEN DATA_IN ; if target is in DATA_IN, read (& ignore) a byte 841 00000AD0: 808B0000 00000030 JUMP REL (set_atn_data_out), WHEN DATA_OUT ; if target is in DATA_OUT, send it a null byte 842 00000AD8: 878B0000 00000048 JUMP REL (set_atn_msg_in), WHEN MSG_IN ; if target is in MSG_IN, read (& ignore) a byte 843 00000AE0: 828B0000 00000050 JUMP REL (set_atn_command), WHEN CMD ; if target is in CMD, send it a null byte 844 00000AE8: 838B0000 00000068 JUMP REL (set_atn_status), WHEN STATUS ; if target is in STATUS, read (& ignore) a byte 845 00000AF0: 98080000 000000A2 INT 0xA2 ; don't know what state target is in, barf 846 00000AF8: set_atn_data_in: 847 00000AF8: 09000001 00000110 MOVE 1, msg_buf, WHEN DATA_IN 848 00000B00: 80880000 FFFFFFB8 JUMP REL (set_atn_loop) 849 00000B08: set_atn_data_out: 850 00000B08: 78080000 00000000 MOVE 0 TO SFBR 851 00000B10: E0080001 00000110 STORE SFBR, 1, msg_buf 852 00000B18: 08000001 00000110 MOVE 1, msg_buf, WHEN DATA_OUT 853 00000B20: 80880000 FFFFFF98 JUMP REL (set_atn_loop) 854 00000B28: set_atn_msg_in: 855 00000B28: 0F000001 00000110 MOVE 1, msg_buf, WHEN MSG_IN 856 00000B30: 80880000 FFFFFF80 JUMP REL (set_atn_clrack) 857 00000B38: set_atn_command: 858 00000B38: 78080000 00000000 MOVE 0 TO SFBR 859 00000B40: E0080001 00000110 STORE SFBR, 1, msg_buf 860 00000B48: 0A000001 00000110 MOVE 1, msg_buf, WHEN COMMAND 861 00000B50: 80880000 FFFFFF68 JUMP REL (set_atn_loop) 862 00000B58: set_atn_status: 863 00000B58: 0B000001 00000110 MOVE 1, msg_buf, WHEN STATUS 864 00000B60: 80880000 FFFFFF58 JUMP REL (set_atn_loop) 865 ; 866 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 867 ; 868 ; Speed and width routines 869 ; 870 ; These routines take the results of negotiation messages and update the 871 ; se3_scntl3 and se1_sxfer locations accordingly 872 ; 873 ; scntl3 consists of the following bits: 874 ; 875 ; <7> = 0 : normal de-glitching 876 ; 1 : ultra synchronous de-glitching 877 ; this gets set only for 20MHz synchronous mode 878 ; <4:6> = SCF divider (sets synchronous receive rate = 80MHz/4/SCF) 879 ; 000 = /3 880 ; 001 = /1 881 ; 010 = /1.5 882 ; 011 = /2 883 ; 100 = /3 884 ; 101 = /4 885 ; <3> = 0 : 8-bit transfers 886 ; 1 : 16-bit transfers 887 ; <0:2> = CCF divider (sets asynchronous clock = 80MHz/CCF) (must not exceed 25MHz) 888 ; 101 = /4 889 ; 890 ; sxfer consists of these bits: 891 ; 892 ; <5:7> = TP (synchronous clock = 80MHz/SCF/TP) 893 ; 000 = /4 894 ; 001 = /5 895 ; 010 = /6 896 ; 011 = /7 897 ; 100 = /8 898 ; 101 = /9 899 ; 110 = /10 900 ; 111 = /11 901 ; <0:4> = req/ack offset 902 ; 0 = async 903 ; 904 ; These routines assume an 80MHz clock (or 40MHz with doubler enabled) 905 ; 906 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 907 ; 908 ; Save transfer width 909 ; 910 ; Input: 911 ; 912 ; SFBR = as defined in scsi standard for the negotiation value 913 ; 0: 8-bit transfers 914 ; 1: 16-bit transfers 915 ; 916 ; Output: 917 ; 918 ; se3_scntl3 = modified 919 ; DSA = scsi_id_entry 920 ; 921 ; Scratch: 922 ; 923 ; SCRATCHA3 924 ; 925 00000B68: save_transfer_width: 926 00000B68: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry 927 00000B70: F1370001 00000007 LOAD SCRATCHA3, 1, DSAREL (se3_scntl3) ; get what was in there before 928 00000B78: 7C37F700 00000000 MOVE SCRATCHA3 & 0xF7 TO SCRATCHA3 ; clear the 'wide' bit 929 00000B80: 808C0000 00000008 JUMP REL (save_transfer_width_ok), IF 0 930 00000B88: 7A370800 00000000 MOVE SCRATCHA3 | 0x08 TO SCRATCHA3 ; ok, set it then 931 00000B90: save_transfer_width_ok: 932 00000B90: F2370001 00000007 STORE NOFLUSH SCRATCHA3, 1, DSAREL (se3_scntl3) 933 00000B98: 90080000 00000000 RETURN 934 ; 935 ; This is the rate that synchronous transfers will happen at 936 ; 937 ; Input: 938 ; 939 ; SFBR = as defined in scsi standard for the negotiation value 940 ; ... 10=25ns period, 11=30.3ns, 12=50ns, 13=52nS, 14=56nS, 15=60nS, ... 941 ; 942 ; Output: 943 ; 944 ; se1_sxfer = modified accordingly 945 ; se3_scntl3 = modified accordingly 946 ; SCRATCHA2 = resultant negotiation value 947 ; DSA = scsi_id_entry 948 ; 949 ; Scratch: 950 ; 951 ; SFBR, SCRATCHA1, SCRATCHA3 952 ; 953 ; Note: 954 ; 955 ; requested we do giving SCF 956 ; <= 50ns (12) 20MHz /1 (001) 957 ; <=100ns (25) 10MHz /2 (011) 958 ; else..... 5MHz /4 (101) 959 ; 960 00000BA0: save_transfer_period: 961 00000BA0: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry 962 00000BA8: F1370001 00000007 LOAD SCRATCHA3, 1, DSAREL (se3_scntl3) ; get what's in se3_scntl3 963 00000BB0: 7C378F00 00000000 MOVE SCRATCHA3 & 0x8F TO SCRATCHA3 ; clear out the SCF bits 964 00000BB8: 7A375000 00000000 MOVE SCRATCHA3 | 0x50 TO SCRATCHA3 ; set SCF = 101 (/4) for 5MHz rate 965 00000BC0: 78363200 00000000 MOVE 50 TO SCRATCHA2 ; set up negotiation value for 5MHz 966 00000BC8: 6E08E600 00000000 MOVE SFBR + (0xFF - 25) TO SFBR ; sets carry iff sfbr > 25 967 00000BD0: 80A80000 00000030 JUMP REL (save_transfer_period_ok), IF CARRY 968 00000BD8: 7E37E000 00000000 MOVE SCRATCHA3 - 0x20 TO SCRATCHA3 ; set SCF = 011 (/2) for 10MHz rate 969 00000BE0: 78361900 00000000 MOVE 25 TO SCRATCHA2 ; set up negotiation value for 10MHz 970 00000BE8: 6E080D00 00000000 MOVE SFBR + 13 TO SFBR ; sets carry iff original sfbr > 12 971 00000BF0: 80A80000 00000010 JUMP REL (save_transfer_period_ok), IF CARRY 972 ; original SFBR <= 12 ... 973 00000BF8: 78360C00 00000000 MOVE 12 TO SCRATCHA2 ; set up negotiation value for 20MHz 974 00000C00: 7E37E000 00000000 MOVE SCRATCHA3 - 0x20 TO SCRATCHA3 ; set SCF = 101 (/4) for 5MHz rate 975 00000C08: save_transfer_period_ok: 976 00000C08: F2370001 00000007 STORE NOFLUSH SCRATCHA3, 1, DSAREL (se3_scntl3) 977 00000C10: 80880000 00000058 JUMP REL (check_ultra_enable) 978 ; 979 ; This is the maximum number of req's that can be sent out without having 980 ; received the corresponding ack's for a synchronous transfer. 981 ; 982 ; Zero means use asynchronous transfer (the default case) 983 ; 984 ; Input: 985 ; 986 ; SFBR = as defined in scsi standard for the negotiation value 987 ; range that this chip can handle: 0..16 988 ; 989 ; Output: 990 ; 991 ; se1_sxfer = modified accordingly 992 ; se3_scntl3 = modified accordingly 993 ; SCRATCHA2 = resultant negotiated value 994 ; DSA = points to scsi_id_table entry 995 ; 996 ; Scratch: 997 ; 998 ; SFBR, SCRATCHA1, SCRATCHA3 999 ; 1000 00000C18: save_req_ack_offset: 1001 00000C18: E1100004 00000100 LOAD DSA0, 4, scsi_id_entry 1002 00000C20: 6A360000 00000000 MOVE SFBR TO SCRATCHA2 ; assume sfbr value is ok as is 1003 00000C28: 6E08EF00 00000000 MOVE SFBR + (0xFF - 16) TO SFBR ; sets carry iff sfbr > 16 1004 00000C30: 80A00000 00000008 JUMP REL (save_req_ack_offset_ok), IF NOT CARRY 1005 00000C38: 78361000 00000000 MOVE 16 TO SCRATCHA2 ; if too big, just use 16 1006 00000C40: save_req_ack_offset_ok: 1007 00000C40: 72360000 00000000 MOVE SCRATCHA2 TO SFBR 1008 00000C48: F1350001 00000005 LOAD SCRATCHA1, 1, DSAREL (se1_sxfer) ; get what is there 1009 00000C50: 7C35E000 00000000 MOVE SCRATCHA1 & 0xE0 TO SCRATCHA1 ; save the existing rate info 1010 00000C58: 7AB50000 00000000 MOVE SCRATCHA1 | SFBR TO SCRATCHA1 ; put in the new offset info 1011 00000C60: F2350001 00000005 STORE NOFLUSH SCRATCHA1, 1, DSAREL (se1_sxfer) 1012 00000C68: F1370001 00000007 LOAD SCRATCHA3, 1, DSAREL (se3_scntl3) 1013 ; 1014 ; Set the ULTRA enable bit in SCNTL3 iff SXFER indicates max speed synchronous 1015 ; 1016 ; Input: 1017 ; 1018 ; SCRATCHA1 = se1_sxfer contents 1019 ; SCRATCHA3 = se3_scntl3 contents 1020 ; DSA = scsi_id_entry 1021 ; 1022 00000C70: check_ultra_enable: 1023 00000C70: 7C377F00 00000000 MOVE SCRATCHA3 & 0x7F TO SCRATCHA3 ; clear ultra enable 1024 00000C78: 72350000 00000000 MOVE SCRATCHA1 TO SFBR 1025 00000C80: 808CE000 00000018 JUMP REL (check_ultra_enable_ok), IF 0x00 AND MASK 0xE0 ; don't bother setting it if async mode 1026 00000C88: 72370000 00000000 MOVE SCRATCHA3 TO SFBR 1027 00000C90: 80848F10 00000008 JUMP REL (check_ultra_enable_ok), IF NOT 0x10 AND MASK 0x8F ; don't bother setting if not max speed 1028 00000C98: 7A378000 00000000 MOVE SCRATCHA3 | 0x80 TO SCRATCHA3 ; synchronous and max speed, set ultra enable bit 1029 00000CA0: check_ultra_enable_ok: 1030 00000CA0: F0370001 00000007 STORE SCRATCHA3, 1, DSAREL (se3_scntl3) 1031 00000CA8: 90080000 00000000 RETURN 1032 ; 1033 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1034 --SYMBOL---------------------------VALUE------TYPE------- INIT_SELECT 55000000 ABSOLUTE INIT_SXFER 00000000 ABSOLUTE INIT_SCNTL3 00000055 ABSOLUTE RP_ABORT_BUFFEROVF 00000001 ABSOLUTE RP_FLAG_DISCONNECT 00000040 ABSOLUTE RP_FLAG_ABORTED 00000020 ABSOLUTE RP_FLAG_DONE 00000010 ABSOLUTE RP_FLAG_GOTSTATUS 00000008 ABSOLUTE RP_FLAG_NEGSYNCH 00000004 ABSOLUTE RP_FLAG_NEGWIDTH 00000002 ABSOLUTE RP_FLAG_NEEDTOIDENT 00000001 ABSOLUTE rp0_flags 0000000C ABSOLUTE rp1_abort 0000000D ABSOLUTE rp2_status 0000000E ABSOLUTE rp3_cmdlen 0000000F ABSOLUTE rp_command 00000010 ABSOLUTE rp_datamov_pa 00000008 ABSOLUTE rp_next_pa 00000004 ABSOLUTE rp_this_va 00000000 ABSOLUTE REQ_ACK_OFFSET 00000010 ABSOLUTE SCRATCHJ1_SELECT 00000002 ABSOLUTE SCRATCHJ1_CHMOVS 00000001 ABSOLUTE STATE_ABORTING 0000000A ABSOLUTE STATE_CHECKING_TARGET 00000004 ABSOLUTE STATE_GETTING_STATUS 00000002 ABSOLUTE STATE_GETTING_MESSAGE 00000001 ABSOLUTE STATE_IDLE 00000000 ABSOLUTE STATE_MESSAGE_OUT 00000003 ABSOLUTE STATE_REQ_COMPLETE 0000000B ABSOLUTE STATE_SELECTED 00000005 ABSOLUTE STATE_SELECTING 00000006 ABSOLUTE STATE_SENDING_COMMAND 00000007 ABSOLUTE STATE_TRANSFERRING_DATA 00000008 ABSOLUTE STATE_WAITING_FOR_RESELECT 00000009 ABSOLUTE se0_zeroes 00000004 ABSOLUTE se1_sxfer 00000005 ABSOLUTE se2_scsi_id 00000006 ABSOLUTE se3_scntl3 00000007 ABSOLUTE se_queue_head 00000000 ABSOLUTE se_saved_dbc 0000000C ABSOLUTE se_saved_dsp 00000008 ABSOLUTE se_select 00000004 ABSOLUTE XFER_PERIOD_FACT 0000000C ABSOLUTE SCRIPT 00000000 CODE SEGMENT disconnecting 00000928 ENTRY scsi_id_table 00000000 ENTRY select_timedout 00000160 ENTRY startup 00000148 ENTRY transfer_data_mismatch 00000658 ENTRY transfer_data_done 00000668 ENTRY abort_request_markit 00000698 LABEL abort_request_inprog 00000290 LABEL abort_task 00000120 LABEL bad_nego_mess_async 000008F0 LABEL bad_nego_mess_reject 000008E0 LABEL bad_nego_mess 000008D8 LABEL bad_reselect_scsi_id 00000218 LABEL check_reselect 000001E0 LABEL check_next_scsi_id 000001D0 LABEL check_select 00000268 LABEL check_target_state 00000320 LABEL check_ultra_enable 00000C70 LABEL check_ultra_enable_ok 00000CA0 LABEL command_move 000005F0 LABEL got_extended_message 000007B0 LABEL got_new_req 000002B8 LABEL get_request_packet 000009D0 LABEL got_sync_data_xfer_msg 0000084C LABEL got_wide_data_xfer_msg 000007E8 LABEL ident_abort_task_msg 00000118 LABEL ignore_message 00000780 LABEL mainloop 00000160 LABEL message_ident_synch 00000140 LABEL message_ident_width 00000138 LABEL message_reject 00000128 LABEL msg_buf 00000110 LABEL new_req_scanloop 00000178 LABEL noop_message 00000130 LABEL proc_synch_reply 00000520 LABEL proc_width_reply_clear_ack 000004C0 LABEL proc_width_reply 00000440 LABEL reject_message 00000760 LABEL req_complete 00000950 LABEL req_complete2 00000968 LABEL req_complete_ab 000006B8 LABEL request_packet 00000108 LABEL reselected 00000240 LABEL restore_pointers 00000A78 LABEL restore_pointers_ack 00000790 LABEL save_data_pointer 00000A38 LABEL save_data_pointer_ack 00000778 LABEL save_req_ack_offset 00000C18 LABEL save_req_ack_offset_ok 00000C40 LABEL save_transfer_period 00000BA0 LABEL save_transfer_period_ok 00000C08 LABEL save_transfer_width 00000B68 LABEL save_transfer_width_ok 00000B90 LABEL scsi_id_entry 00000100 LABEL send_message_ident 000003B8 LABEL send_message_ident_synch 000004D0 LABEL send_message_ident_width 000003F0 LABEL send_message_synch 00000508 LABEL send_message_width 00000428 LABEL set_atn 00000AB0 LABEL set_atn_clrack 00000AB8 LABEL set_atn_command 00000B38 LABEL set_atn_data_in 00000AF8 LABEL set_atn_data_out 00000B08 LABEL set_atn_loop 00000AC0 LABEL set_atn_msg_in 00000B28 LABEL set_atn_status 00000B58 LABEL set_connect_params 00000250 LABEL transfer_data_done2 00000650 LABEL transfer_data_in 00000600 LABEL transfer_command 000005A0 LABEL transfer_data_out 00000600 LABEL transfer_message_in 00000710 LABEL transfer_message_out 00000360 LABEL transfer_no_data 00000670 LABEL transfer_status 000006C8 LABEL width_ok 0000082C LABEL