root/drivers/scsi/53c8xx_d.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


   1 u32 SCRIPT[] = {
   2 /*
   3 
   4 
   5 ; NCR 53c810 driver, main script
   6 ; Sponsored by 
   7 ;       iX Multiuser Multitasking Magazine
   8 ;       hm@ix.de
   9 ;
  10 ; Copyright 1993, 1994, 1995 Drew Eckhardt
  11 ;      Visionary Computing 
  12 ;      (Unix and Linux consulting and custom programming)
  13 ;      drew@PoohSticks.ORG
  14 ;      +1 (303) 786-7975
  15 ;
  16 ; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
  17 ;
  18 ; PRE-ALPHA
  19 ;
  20 ; For more information, please consult 
  21 ;
  22 ; NCR 53C810
  23 ; PCI-SCSI I/O Processor
  24 ; Data Manual
  25 ;
  26 ; NCR 53C710 
  27 ; SCSI I/O Processor
  28 ; Programmers Guide
  29 ;
  30 ; NCR Microelectronics
  31 ; 1635 Aeroplaza Drive
  32 ; Colorado Springs, CO 80916
  33 ; 1+ (719) 578-3400
  34 ;
  35 ; Toll free literature number
  36 ; +1 (800) 334-5454
  37 ;
  38 ; IMPORTANT : This code is self modifying due to the limitations of 
  39 ;       the NCR53c7,8xx series chips.  Persons debugging this code with
  40 ;       the remote debugger should take this into account, and NOT set
  41 ;       breakpoints in modified instructions.
  42 ;
  43 ; Design:
  44 ; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard 
  45 ; microcontroller using a simple instruction set.   
  46 ;
  47 ; So, to minimize the effects of interrupt latency, and to maximize 
  48 ; throughput, this driver offloads the practical maximum amount 
  49 ; of processing to the SCSI chip while still maintaining a common
  50 ; structure.
  51 ;
  52 ; Where tradeoffs were needed between efficiency on the older
  53 ; chips and the newer NCR53c800 series, the NCR53c800 series 
  54 ; was chosen.
  55 ;
  56 ; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
  57 ; automate SCSI transfers without host processor intervention, this 
  58 ; isn't the case with the NCR53c710 and newer chips which allow 
  59 ;
  60 ; - reads and writes to the internal registers from within the SCSI
  61 ;       scripts, allowing the SCSI SCRIPTS(tm) code to save processor
  62 ;       state so that multiple threads of execution are possible, and also
  63 ;       provide an ALU for loop control, etc.
  64 ; 
  65 ; - table indirect addressing for some instructions. This allows 
  66 ;       pointers to be located relative to the DSA ((Data Structure
  67 ;       Address) register.
  68 ;
  69 ; These features make it possible to implement a mailbox style interface,
  70 ; where the same piece of code is run to handle I/O for multiple threads
  71 ; at once minimizing our need to relocate code.  Since the NCR53c700/
  72 ; NCR53c800 series have a unique combination of features, making a 
  73 ; a standard ingoing/outgoing mailbox system, costly, I've modified it.
  74 ;
  75 ; - Mailboxes are a mixture of code and data.  This lets us greatly
  76 ;       simplify the NCR53c810 code and do things that would otherwise
  77 ;       not be possible.
  78 ;
  79 ; The saved data pointer is now implemented as follows :
  80 ;
  81 ;       Control flow has been architected such that if control reaches
  82 ;       munge_save_data_pointer, on a restore pointers message or 
  83 ;       reconnection, a jump to the address formerly in the TEMP register
  84 ;       will allow the SCSI command to resume execution.
  85 ;
  86 
  87 ;
  88 ; Note : the DSA structures must be aligned on 32 bit boundaries,
  89 ; since the source and destination of MOVE MEMORY instructions 
  90 ; must share the same alignment and this is the alignment of the
  91 ; NCR registers.
  92 ;
  93 
  94 ABSOLUTE dsa_temp_lun = 0               ; Patch to lun for current dsa
  95 ABSOLUTE dsa_temp_next = 0              ; Patch to dsa next for current dsa
  96 ABSOLUTE dsa_temp_addr_next = 0         ; Patch to address of dsa next address 
  97                                         ;       for current dsa
  98 ABSOLUTE dsa_temp_sync = 0              ; Patch to address of per-target
  99                                         ;       sync routine
 100 ABSOLUTE dsa_temp_target = 0            ; Patch to id for current dsa
 101 ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
 102                                         ;       saved data pointer
 103 ABSOLUTE dsa_temp_addr_residual = 0     ; Patch to address of per-command
 104                                         ;       current residual code
 105 ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
 106                                         ; saved residual code
 107 ABSOLUTE dsa_temp_addr_new_value = 0    ; Address of value for JUMP operand
 108 ABSOLUTE dsa_temp_addr_array_value = 0  ; Address to copy to
 109 ABSOLUTE dsa_temp_addr_dsa_value = 0    ; Address of this DSA value
 110 
 111 ;
 112 ; Once a device has initiated reselection, we need to compare it 
 113 ; against the singly linked list of commands which have disconnected
 114 ; and are pending reselection.  These commands are maintained in 
 115 ; an unordered singly linked list of DSA structures, through the
 116 ; DSA pointers at their 'centers' headed by the reconnect_dsa_head
 117 ; pointer.
 118 ; 
 119 ; To avoid complications in removing commands from the list,
 120 ; I minimize the amount of expensive (at eight operations per
 121 ; addition @ 500-600ns each) pointer operations which must
 122 ; be done in the NCR driver by precomputing them on the 
 123 ; host processor during dsa structure generation.
 124 ;
 125 ; The fixed-up per DSA code knows how to recognize the nexus
 126 ; associated with the corresponding SCSI command, and modifies
 127 ; the source and destination pointers for the MOVE MEMORY 
 128 ; instruction which is executed when reselected_ok is called
 129 ; to remove the command from the list.  Similarly, DSA is 
 130 ; loaded with the address of the next DSA structure and
 131 ; reselected_check_next is called if a failure occurs.
 132 ;
 133 ; Perhaps more conscisely, the net effect of the mess is 
 134 ;
 135 ; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, 
 136 ;     src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
 137 ;       src = &dsa->next;
 138 ;       if (target_id == dsa->id && target_lun == dsa->lun) {
 139 ;               *dest = *src;
 140 ;               break;
 141 ;         }     
 142 ; }
 143 ;
 144 ; if (!dsa)
 145 ;           error (int_err_unexpected_reselect);
 146 ; else  
 147 ;     longjmp (dsa->jump_resume, 0);
 148 ;
 149 ;       
 150 
 151 
 152 ; Define DSA structure used for mailboxes
 153 ENTRY dsa_code_template
 154 dsa_code_template:
 155 ENTRY dsa_code_begin
 156 dsa_code_begin:
 157         MOVE dmode_memory_to_ncr TO DMODE
 158 
 159 at 0x00000000 : */      0x78380000,0x00000000,
 160 /*
 161         MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
 162 
 163 at 0x00000002 : */      0xc0000004,0x00000000,0x00000000,
 164 /*
 165         MOVE dmode_memory_to_memory TO DMODE
 166 
 167 at 0x00000005 : */      0x78380000,0x00000000,
 168 /*
 169         CALL scratch_to_dsa
 170 
 171 at 0x00000007 : */      0x88080000,0x00000960,
 172 /*
 173         CALL select
 174 
 175 at 0x00000009 : */      0x88080000,0x000001fc,
 176 /*
 177 ; Handle the phase mismatch which may have resulted from the 
 178 ; MOVE FROM dsa_msgout if we returned here.  The CLEAR ATN 
 179 ; may or may not be necessary, and we should update script_asm.pl
 180 ; to handle multiple pieces.
 181     CLEAR ATN
 182 
 183 at 0x0000000b : */      0x60000008,0x00000000,
 184 /*
 185     CLEAR ACK
 186 
 187 at 0x0000000d : */      0x60000040,0x00000000,
 188 /*
 189 
 190 ; Replace second operand with address of JUMP instruction dest operand
 191 ; in schedule table for this DSA.  Becomes dsa_jump_dest in 53c7,8xx.c.
 192 ENTRY dsa_code_fix_jump
 193 dsa_code_fix_jump:
 194         MOVE MEMORY 4, NOP_insn, 0
 195 
 196 at 0x0000000f : */      0xc0000004,0x00000000,0x00000000,
 197 /*
 198         JUMP select_done
 199 
 200 at 0x00000012 : */      0x80080000,0x00000224,
 201 /*
 202 
 203 ; wrong_dsa loads the DSA register with the value of the dsa_next
 204 ; field.
 205 ;
 206 wrong_dsa:
 207 ;               Patch the MOVE MEMORY INSTRUCTION such that 
 208 ;               the destination address is the address of the OLD 
 209 ;               next pointer.
 210 ;
 211         MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 8
 212 
 213 at 0x00000014 : */      0xc0000004,0x00000000,0x00000758,
 214 /*
 215         MOVE dmode_memory_to_ncr TO DMODE       
 216 
 217 at 0x00000017 : */      0x78380000,0x00000000,
 218 /*
 219 ;
 220 ;       Move the _contents_ of the next pointer into the DSA register as 
 221 ;       the next I_T_L or I_T_L_Q tupple to check against the established
 222 ;       nexus.
 223 ;
 224         MOVE MEMORY 4, dsa_temp_next, addr_scratch
 225 
 226 at 0x00000019 : */      0xc0000004,0x00000000,0x00000000,
 227 /*
 228         MOVE dmode_memory_to_memory TO DMODE
 229 
 230 at 0x0000001c : */      0x78380000,0x00000000,
 231 /*
 232         CALL scratch_to_dsa
 233 
 234 at 0x0000001e : */      0x88080000,0x00000960,
 235 /*
 236         JUMP reselected_check_next
 237 
 238 at 0x00000020 : */      0x80080000,0x000006a4,
 239 /*
 240 
 241 ABSOLUTE dsa_save_data_pointer = 0
 242 ENTRY dsa_code_save_data_pointer
 243 dsa_code_save_data_pointer:
 244         MOVE dmode_ncr_to_memory TO DMODE
 245 
 246 at 0x00000022 : */      0x78380000,0x00000000,
 247 /*
 248         MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer
 249 
 250 at 0x00000024 : */      0xc0000004,0x00000000,0x00000000,
 251 /*
 252         MOVE dmode_memory_to_memory TO DMODE
 253 
 254 at 0x00000027 : */      0x78380000,0x00000000,
 255 /*
 256 ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
 257         MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
 258 
 259 at 0x00000029 : */      0xc0000018,0x00000000,0x00000000,
 260 /*
 261         CLEAR ACK
 262 
 263 at 0x0000002c : */      0x60000040,0x00000000,
 264 /*
 265 
 266 
 267 
 268         RETURN
 269 
 270 at 0x0000002e : */      0x90080000,0x00000000,
 271 /*
 272 ABSOLUTE dsa_restore_pointers = 0
 273 ENTRY dsa_code_restore_pointers
 274 dsa_code_restore_pointers:
 275         MOVE dmode_memory_to_ncr TO DMODE
 276 
 277 at 0x00000030 : */      0x78380000,0x00000000,
 278 /*
 279         MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp
 280 
 281 at 0x00000032 : */      0xc0000004,0x00000000,0x00000000,
 282 /*
 283         MOVE dmode_memory_to_memory TO DMODE
 284 
 285 at 0x00000035 : */      0x78380000,0x00000000,
 286 /*
 287 ; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
 288         MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
 289 
 290 at 0x00000037 : */      0xc0000018,0x00000000,0x00000000,
 291 /*
 292         CLEAR ACK
 293 
 294 at 0x0000003a : */      0x60000040,0x00000000,
 295 /*
 296 
 297 
 298 
 299         RETURN
 300 
 301 at 0x0000003c : */      0x90080000,0x00000000,
 302 /*
 303 
 304 ABSOLUTE dsa_check_reselect = 0
 305 ; dsa_check_reselect determines whether or not the current target and
 306 ; lun match the current DSA
 307 ENTRY dsa_code_check_reselect
 308 dsa_code_check_reselect:
 309         MOVE SSID TO SFBR               ; SSID contains 3 bit target ID
 310 
 311 at 0x0000003e : */      0x720a0000,0x00000000,
 312 /*
 313 ; FIXME : we need to accomodate bit fielded and binary here for '7xx/'8xx chips
 314         JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8
 315 
 316 at 0x00000040 : */      0x8084f800,0x00ffff48,
 317 /*
 318 ;
 319 ; Hack - move to scratch first, since SFBR is not writeable
 320 ;       via the CPU and hence a MOVE MEMORY instruction.
 321 ;
 322         MOVE dmode_memory_to_ncr TO DMODE
 323 
 324 at 0x00000042 : */      0x78380000,0x00000000,
 325 /*
 326         MOVE MEMORY 1, reselected_identify, addr_scratch
 327 
 328 at 0x00000044 : */      0xc0000001,0x00000000,0x00000000,
 329 /*
 330         MOVE dmode_memory_to_memory TO DMODE
 331 
 332 at 0x00000047 : */      0x78380000,0x00000000,
 333 /*
 334         MOVE SCRATCH0 TO SFBR
 335 
 336 at 0x00000049 : */      0x72340000,0x00000000,
 337 /*
 338 ; FIXME : we need to accomodate bit fielded and binary here for '7xx/'8xx chips
 339         JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
 340 
 341 at 0x0000004b : */      0x8084f800,0x00ffff1c,
 342 /*
 343 ;               Patch the MOVE MEMORY INSTRUCTION such that
 344 ;               the source address is the address of this dsa's
 345 ;               next pointer.
 346         MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 4
 347 
 348 at 0x0000004d : */      0xc0000004,0x00000000,0x00000754,
 349 /*
 350         CALL reselected_ok
 351 
 352 at 0x00000050 : */      0x88080000,0x00000750,
 353 /*
 354         CALL dsa_temp_sync      
 355 
 356 at 0x00000052 : */      0x88080000,0x00000000,
 357 /*
 358 ; Release ACK on the IDENTIFY message _after_ we've set the synchronous 
 359 ; transfer parameters! 
 360         CLEAR ACK
 361 
 362 at 0x00000054 : */      0x60000040,0x00000000,
 363 /*
 364 ; Implicitly restore pointers on reselection, so a RETURN
 365 ; will transfer control back to the right spot.
 366         CALL REL (dsa_code_restore_pointers)
 367 
 368 at 0x00000056 : */      0x88880000,0x00ffff60,
 369 /*
 370         RETURN
 371 
 372 at 0x00000058 : */      0x90080000,0x00000000,
 373 /*
 374 ENTRY dsa_zero
 375 dsa_zero:
 376 ENTRY dsa_code_template_end
 377 dsa_code_template_end:
 378 
 379 ; Perform sanity check for dsa_fields_start == dsa_code_template_end - 
 380 ; dsa_zero, puke.
 381 
 382 ABSOLUTE dsa_fields_start =  0  ; Sanity marker
 383                                 ;       pad 48 bytes (fix this RSN)
 384 ABSOLUTE dsa_next = 48          ; len 4 Next DSA
 385                                 ; del 4 Previous DSA address
 386 ABSOLUTE dsa_cmnd = 56          ; len 4 Scsi_Cmnd * for this thread.
 387 ABSOLUTE dsa_select = 60        ; len 4 Device ID, Period, Offset for 
 388                                 ;       table indirect select
 389 ABSOLUTE dsa_msgout = 64        ; len 8 table indirect move parameter for 
 390                                 ;       select message
 391 ABSOLUTE dsa_cmdout = 72        ; len 8 table indirect move parameter for 
 392                                 ;       command
 393 ABSOLUTE dsa_dataout = 80       ; len 4 code pointer for dataout
 394 ABSOLUTE dsa_datain = 84        ; len 4 code pointer for datain
 395 ABSOLUTE dsa_msgin = 88         ; len 8 table indirect move for msgin
 396 ABSOLUTE dsa_status = 96        ; len 8 table indirect move for status byte
 397 ABSOLUTE dsa_msgout_other = 104 ; len 8 table indirect for normal message out
 398                                 ; (Synchronous transfer negotiation, etc).
 399 ABSOLUTE dsa_end = 112
 400 
 401 ABSOLUTE schedule = 0           ; Array of JUMP dsa_begin or JUMP (next),
 402                                 ; terminated by a call to JUMP wait_reselect
 403 
 404 ; Linked lists of DSA structures
 405 ABSOLUTE reconnect_dsa_head = 0 ; Link list of DSAs which can reconnect
 406 ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable contataining
 407                                 ; address of reconnect_dsa_head
 408 
 409 ; These select the source and destination of a MOVE MEMORY instruction
 410 ABSOLUTE dmode_memory_to_memory = 0x0
 411 ABSOLUTE dmode_memory_to_ncr = 0x0
 412 ABSOLUTE dmode_ncr_to_memory = 0x0
 413 
 414 ABSOLUTE addr_scratch = 0x0
 415 ABSOLUTE addr_temp = 0x0
 416 
 417 
 418 ; Interrupts - 
 419 ; MSB indicates type
 420 ; 0     handle error condition
 421 ; 1     handle message 
 422 ; 2     handle normal condition
 423 ; 3     debugging interrupt
 424 ; 4     testing interrupt 
 425 ; Next byte indicates specific error
 426 
 427 ; XXX not yet implemented, I'm not sure if I want to - 
 428 ; Next byte indicates the routine the error occurred in
 429 ; The LSB indicates the specific place the error occurred
 430  
 431 ABSOLUTE int_err_unexpected_phase = 0x00000000  ; Unexpected phase encountered
 432 ABSOLUTE int_err_selected = 0x00010000          ; SELECTED (nee RESELECTED)
 433 ABSOLUTE int_err_unexpected_reselect = 0x00020000 
 434 ABSOLUTE int_err_check_condition = 0x00030000   
 435 ABSOLUTE int_err_no_phase = 0x00040000
 436 ABSOLUTE int_msg_wdtr = 0x01000000              ; WDTR message received
 437 ABSOLUTE int_msg_sdtr = 0x01010000              ; SDTR received
 438 ABSOLUTE int_msg_1 = 0x01020000                 ; single byte special message
 439                                                 ; received
 440 
 441 ABSOLUTE int_norm_select_complete = 0x02000000  ; Select complete, reprogram
 442                                                 ; registers.
 443 ABSOLUTE int_norm_reselect_complete = 0x02010000        ; Nexus established
 444 ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
 445 ABSOLUTE int_norm_disconnected = 0x02030000     ; Disconnected 
 446 ABSOLUTE int_norm_aborted =0x02040000           ; Aborted *dsa
 447 ABSOLUTE int_norm_reset = 0x02050000            ; Generated BUS reset.
 448 ABSOLUTE int_debug_break = 0x03000000           ; Break point
 449 
 450 ABSOLUTE int_debug_panic = 0x030b0000           ; Panic driver
 451 
 452 
 453 ABSOLUTE int_test_1 = 0x04000000                ; Test 1 complete
 454 ABSOLUTE int_test_2 = 0x04010000                ; Test 2 complete
 455 ABSOLUTE int_test_3 = 0x04020000                ; Test 3 complete
 456 
 457 
 458 ; These should start with 0x05000000, with low bits incrementing for 
 459 ; each one.
 460 
 461 
 462                                                 
 463 ABSOLUTE NCR53c7xx_msg_abort = 0        ; Pointer to abort message
 464 ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
 465 ABSOLUTE NCR53c7xx_zero = 0             ; long with zero in it, use for source
 466 ABSOLUTE NCR53c7xx_sink = 0             ; long to dump worthless data in
 467 ABSOLUTE NOP_insn = 0                   ; NOP instruction
 468 
 469 ; Pointer to message, potentially multi-byte
 470 ABSOLUTE msg_buf = 0
 471 
 472 ; Pointer to holding area for reselection information
 473 ABSOLUTE reselected_identify = 0
 474 ABSOLUTE reselected_tag = 0
 475 
 476 ; Request sense command pointer, it's a 6 byte command, should
 477 ; be constant for all commands since we always want 16 bytes of 
 478 ; sense and we don't need to change any fields as we did under 
 479 ; SCSI-I when we actually cared about the LUN field.
 480 ;EXTERNAL NCR53c7xx_sense               ; Request sense command
 481 
 482 
 483 ; dsa_schedule  
 484 ; PURPOSE : after a DISCONNECT message has been received, and pointers
 485 ;       saved, insert the current DSA structure at the head of the 
 486 ;       disconnected queue and fall through to the scheduler.
 487 ;
 488 ; CALLS : OK
 489 ;
 490 ; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
 491 ;       of disconnected commands
 492 ;
 493 ; MODIFIES : SCRATCH, reconnect_dsa_head
 494 ; 
 495 ; EXITS : always passes control to schedule
 496 
 497 ENTRY dsa_schedule
 498 dsa_schedule:
 499 
 500 
 501 
 502 
 503 ;
 504 ; Calculate the address of the next pointer within the DSA 
 505 ; structure of the command that is currently disconnecting
 506 ;
 507     CALL dsa_to_scratch
 508 
 509 at 0x0000005a : */      0x88080000,0x00000918,
 510 /*
 511     MOVE SCRATCH0 + dsa_next TO SCRATCH0
 512 
 513 at 0x0000005c : */      0x7e343000,0x00000000,
 514 /*
 515     MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
 516 
 517 at 0x0000005e : */      0x7f350000,0x00000000,
 518 /*
 519     MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
 520 
 521 at 0x00000060 : */      0x7f360000,0x00000000,
 522 /*
 523     MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
 524 
 525 at 0x00000062 : */      0x7f370000,0x00000000,
 526 /*
 527 
 528 ; Point the next field of this DSA structure at the current disconnected 
 529 ; list
 530     MOVE dmode_ncr_to_memory TO DMODE
 531 
 532 at 0x00000064 : */      0x78380000,0x00000000,
 533 /*
 534     MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
 535 
 536 at 0x00000066 : */      0xc0000004,0x00000000,0x000001b4,
 537 /*
 538     MOVE dmode_memory_to_memory TO DMODE
 539 
 540 at 0x00000069 : */      0x78380000,0x00000000,
 541 /*
 542 dsa_schedule_insert:
 543     MOVE MEMORY 4, reconnect_dsa_head, 0 
 544 
 545 at 0x0000006b : */      0xc0000004,0x00000000,0x00000000,
 546 /*
 547 
 548 ; And update the head pointer.
 549     CALL dsa_to_scratch
 550 
 551 at 0x0000006e : */      0x88080000,0x00000918,
 552 /*
 553     MOVE dmode_ncr_to_memory TO DMODE   
 554 
 555 at 0x00000070 : */      0x78380000,0x00000000,
 556 /*
 557     MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
 558 
 559 at 0x00000072 : */      0xc0000004,0x00000000,0x00000000,
 560 /*
 561     MOVE dmode_memory_to_memory TO DMODE
 562 
 563 at 0x00000075 : */      0x78380000,0x00000000,
 564 /*
 565 
 566 
 567     MOVE SCNTL2 & 0x7f TO SCNTL2
 568 
 569 at 0x00000077 : */      0x7c027f00,0x00000000,
 570 /*
 571     CLEAR ACK
 572 
 573 at 0x00000079 : */      0x60000040,0x00000000,
 574 /*
 575 
 576     WAIT DISCONNECT
 577 
 578 at 0x0000007b : */      0x48000000,0x00000000,
 579 /*
 580 
 581 
 582 
 583 
 584 
 585 
 586     JUMP schedule
 587 
 588 at 0x0000007d : */      0x80080000,0x00000000,
 589 /*
 590 
 591 
 592 ;
 593 ; select
 594 ;
 595 ; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
 596 ;       On success, the current DSA structure is removed from the issue 
 597 ;       queue.  Usually, this is entered as a fall-through from schedule,
 598 ;       although the contingent allegiance handling code will write
 599 ;       the select entry address to the DSP to restart a command as a 
 600 ;       REQUEST SENSE.  A message is sent (usually IDENTIFY, although
 601 ;       additional SDTR or WDTR messages may be sent).  COMMAND OUT
 602 ;       is handled.
 603 ;
 604 ; INPUTS : DSA - SCSI command, issue_dsa_head
 605 ;
 606 ; CALLS : NOT OK
 607 ;
 608 ; MODIFIES : SCRATCH, issue_dsa_head
 609 ;
 610 ; EXITS : on reselection or selection, go to select_failed
 611 ;       otherwise, RETURN so control is passed back to 
 612 ;       dsa_begin.
 613 ;
 614 
 615 ENTRY select
 616 select:
 617 
 618 
 619 
 620 
 621 
 622 
 623 
 624 
 625 
 626 
 627 
 628 
 629     CLEAR TARGET
 630 
 631 at 0x0000007f : */      0x60000200,0x00000000,
 632 /*
 633 
 634 ; XXX
 635 ;
 636 ; In effect, SELECTION operations are backgrounded, with execution
 637 ; continuing until code which waits for REQ or a fatal interrupt is 
 638 ; encountered.
 639 ;
 640 ; So, for more performance, we could overlap the code which removes 
 641 ; the command from the NCRs issue queue with the selection, but 
 642 ; at this point I don't want to deal with the error recovery.
 643 ;
 644 
 645 
 646     SELECT ATN FROM dsa_select, select_failed
 647 
 648 at 0x00000081 : */      0x4300003c,0x00000794,
 649 /*
 650     JUMP select_msgout, WHEN MSG_OUT
 651 
 652 at 0x00000083 : */      0x860b0000,0x00000214,
 653 /*
 654 ENTRY select_msgout
 655 select_msgout:
 656     MOVE FROM dsa_msgout, WHEN MSG_OUT
 657 
 658 at 0x00000085 : */      0x1e000000,0x00000040,
 659 /*
 660 
 661 
 662 
 663 
 664 
 665 
 666 
 667 
 668 
 669 
 670    RETURN
 671 
 672 at 0x00000087 : */      0x90080000,0x00000000,
 673 /*
 674 
 675 ; 
 676 ; select_done
 677 ; 
 678 ; PURPOSE: continue on to normal data transfer; called as the exit 
 679 ;       point from dsa_begin.
 680 ;
 681 ; INPUTS: dsa
 682 ;
 683 ; CALLS: OK
 684 ;
 685 ;
 686 
 687 select_done:
 688 
 689 
 690 
 691 
 692 
 693 
 694 
 695 ; After a successful selection, we should get either a CMD phase or 
 696 ; some transfer request negotiation message.
 697 
 698     JUMP cmdout, WHEN CMD
 699 
 700 at 0x00000089 : */      0x820b0000,0x00000244,
 701 /*
 702     INT int_err_unexpected_phase, WHEN NOT MSG_IN 
 703 
 704 at 0x0000008b : */      0x9f030000,0x00000000,
 705 /*
 706 
 707 select_msg_in:
 708     CALL msg_in, WHEN MSG_IN
 709 
 710 at 0x0000008d : */      0x8f0b0000,0x00000404,
 711 /*
 712     JUMP select_msg_in, WHEN MSG_IN
 713 
 714 at 0x0000008f : */      0x870b0000,0x00000234,
 715 /*
 716 
 717 cmdout:
 718     INT int_err_unexpected_phase, WHEN NOT CMD
 719 
 720 at 0x00000091 : */      0x9a030000,0x00000000,
 721 /*
 722 
 723 
 724 
 725 ENTRY cmdout_cmdout
 726 cmdout_cmdout:
 727 
 728     MOVE FROM dsa_cmdout, WHEN CMD
 729 
 730 at 0x00000093 : */      0x1a000000,0x00000048,
 731 /*
 732 
 733 
 734 
 735 
 736 ;
 737 ; data_transfer  
 738 ; other_out
 739 ; other_in
 740 ; other_transfer
 741 ;
 742 ; PURPOSE : handle the main data transfer for a SCSI command in 
 743 ;       several parts.  In the first part, data_transfer, DATA_IN
 744 ;       and DATA_OUT phases are allowed, with the user provided
 745 ;       code (usually dynamically generated based on the scatter/gather
 746 ;       list associated with a SCSI command) called to handle these 
 747 ;       phases.
 748 ;
 749 ;       After control has passed to one of the user provided 
 750 ;       DATA_IN or DATA_OUT routines, back calls are made to 
 751 ;       other_tranfer_in or other_transfer_out to handle non-DATA IN
 752 ;       and DATA OUT phases respectively, with the state of the active
 753 ;       data pointer being preserved in TEMP.
 754 ;
 755 ;       On completion, the user code passes control to other_transfer
 756 ;       which causes DATA_IN and DATA_OUT to result in unexpected_phase
 757 ;       interrupts so that data overruns may be trapped.
 758 ;
 759 ; INPUTS : DSA - SCSI command
 760 ;
 761 ; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
 762 ;       other_transfer
 763 ;
 764 ; MODIFIES : SCRATCH
 765 ;
 766 ; EXITS : if STATUS IN is detected, signifying command completion,
 767 ;       the NCR jumps to command_complete.  If MSG IN occurs, a 
 768 ;       CALL is made to msg_in.  Otherwise, other_transfer runs in 
 769 ;       an infinite loop.
 770 ;       
 771 
 772 ENTRY data_transfer
 773 data_transfer:
 774     JUMP cmdout_cmdout, WHEN CMD
 775 
 776 at 0x00000095 : */      0x820b0000,0x0000024c,
 777 /*
 778     CALL msg_in, WHEN MSG_IN
 779 
 780 at 0x00000097 : */      0x8f0b0000,0x00000404,
 781 /*
 782     INT int_err_unexpected_phase, WHEN MSG_OUT
 783 
 784 at 0x00000099 : */      0x9e0b0000,0x00000000,
 785 /*
 786     JUMP do_dataout, WHEN DATA_OUT
 787 
 788 at 0x0000009b : */      0x800b0000,0x0000028c,
 789 /*
 790     JUMP do_datain, WHEN DATA_IN
 791 
 792 at 0x0000009d : */      0x810b0000,0x000002e4,
 793 /*
 794     JUMP command_complete, WHEN STATUS
 795 
 796 at 0x0000009f : */      0x830b0000,0x0000060c,
 797 /*
 798     JUMP data_transfer
 799 
 800 at 0x000000a1 : */      0x80080000,0x00000254,
 801 /*
 802 ENTRY end_data_transfer
 803 end_data_transfer:
 804 
 805 ;
 806 ; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain 
 807 ; should be fixed up whenever the nexus changes so it can point to the 
 808 ; correct routine for that command.
 809 ;
 810 
 811 
 812 ; Nasty jump to dsa->dataout
 813 do_dataout:
 814     CALL dsa_to_scratch
 815 
 816 at 0x000000a3 : */      0x88080000,0x00000918,
 817 /*
 818     MOVE SCRATCH0 + dsa_dataout TO SCRATCH0     
 819 
 820 at 0x000000a5 : */      0x7e345000,0x00000000,
 821 /*
 822     MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
 823 
 824 at 0x000000a7 : */      0x7f350000,0x00000000,
 825 /*
 826     MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
 827 
 828 at 0x000000a9 : */      0x7f360000,0x00000000,
 829 /*
 830     MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
 831 
 832 at 0x000000ab : */      0x7f370000,0x00000000,
 833 /*
 834     MOVE dmode_ncr_to_memory TO DMODE
 835 
 836 at 0x000000ad : */      0x78380000,0x00000000,
 837 /*
 838     MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
 839 
 840 at 0x000000af : */      0xc0000004,0x00000000,0x000002d4,
 841 /*
 842     MOVE dmode_memory_to_memory TO DMODE
 843 
 844 at 0x000000b2 : */      0x78380000,0x00000000,
 845 /*
 846 dataout_to_jump:
 847     MOVE MEMORY 4, 0, dataout_jump + 4 
 848 
 849 at 0x000000b4 : */      0xc0000004,0x00000000,0x000002e0,
 850 /*
 851 dataout_jump:
 852     JUMP 0
 853 
 854 at 0x000000b7 : */      0x80080000,0x00000000,
 855 /*
 856 
 857 ; Nasty jump to dsa->dsain
 858 do_datain:
 859     CALL dsa_to_scratch
 860 
 861 at 0x000000b9 : */      0x88080000,0x00000918,
 862 /*
 863     MOVE SCRATCH0 + dsa_datain TO SCRATCH0      
 864 
 865 at 0x000000bb : */      0x7e345400,0x00000000,
 866 /*
 867     MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
 868 
 869 at 0x000000bd : */      0x7f350000,0x00000000,
 870 /*
 871     MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
 872 
 873 at 0x000000bf : */      0x7f360000,0x00000000,
 874 /*
 875     MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
 876 
 877 at 0x000000c1 : */      0x7f370000,0x00000000,
 878 /*
 879     MOVE dmode_ncr_to_memory TO DMODE
 880 
 881 at 0x000000c3 : */      0x78380000,0x00000000,
 882 /*
 883     MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
 884 
 885 at 0x000000c5 : */      0xc0000004,0x00000000,0x0000032c,
 886 /*
 887     MOVE dmode_memory_to_memory TO DMODE                
 888 
 889 at 0x000000c8 : */      0x78380000,0x00000000,
 890 /*
 891 ENTRY datain_to_jump
 892 datain_to_jump:
 893     MOVE MEMORY 4, 0, datain_jump + 4
 894 
 895 at 0x000000ca : */      0xc0000004,0x00000000,0x00000338,
 896 /*
 897 
 898 
 899 
 900 datain_jump:
 901     JUMP 0
 902 
 903 at 0x000000cd : */      0x80080000,0x00000000,
 904 /*
 905 
 906 
 907 
 908 ; Note that other_out and other_in loop until a non-data phase
 909 ; is discoverred, so we only execute return statements when we
 910 ; can go on to the next data phase block move statement.
 911 
 912 ENTRY other_out
 913 other_out:
 914 
 915 
 916 
 917     INT int_err_unexpected_phase, WHEN CMD
 918 
 919 at 0x000000cf : */      0x9a0b0000,0x00000000,
 920 /*
 921     JUMP msg_in_restart, WHEN MSG_IN 
 922 
 923 at 0x000000d1 : */      0x870b0000,0x000003e4,
 924 /*
 925     INT int_err_unexpected_phase, WHEN MSG_OUT
 926 
 927 at 0x000000d3 : */      0x9e0b0000,0x00000000,
 928 /*
 929     INT int_err_unexpected_phase, WHEN DATA_IN
 930 
 931 at 0x000000d5 : */      0x990b0000,0x00000000,
 932 /*
 933     JUMP command_complete, WHEN STATUS
 934 
 935 at 0x000000d7 : */      0x830b0000,0x0000060c,
 936 /*
 937     JUMP other_out, WHEN NOT DATA_OUT
 938 
 939 at 0x000000d9 : */      0x80030000,0x0000033c,
 940 /*
 941     RETURN
 942 
 943 at 0x000000db : */      0x90080000,0x00000000,
 944 /*
 945 
 946 ENTRY other_in
 947 other_in:
 948 
 949 
 950 
 951     INT int_err_unexpected_phase, WHEN CMD
 952 
 953 at 0x000000dd : */      0x9a0b0000,0x00000000,
 954 /*
 955     JUMP msg_in_restart, WHEN MSG_IN 
 956 
 957 at 0x000000df : */      0x870b0000,0x000003e4,
 958 /*
 959     INT int_err_unexpected_phase, WHEN MSG_OUT
 960 
 961 at 0x000000e1 : */      0x9e0b0000,0x00000000,
 962 /*
 963     INT int_err_unexpected_phase, WHEN DATA_OUT
 964 
 965 at 0x000000e3 : */      0x980b0000,0x00000000,
 966 /*
 967     JUMP command_complete, WHEN STATUS
 968 
 969 at 0x000000e5 : */      0x830b0000,0x0000060c,
 970 /*
 971     JUMP other_in, WHEN NOT DATA_IN
 972 
 973 at 0x000000e7 : */      0x81030000,0x00000374,
 974 /*
 975     RETURN
 976 
 977 at 0x000000e9 : */      0x90080000,0x00000000,
 978 /*
 979 
 980 
 981 ENTRY other_transfer
 982 other_transfer:
 983     INT int_err_unexpected_phase, WHEN CMD
 984 
 985 at 0x000000eb : */      0x9a0b0000,0x00000000,
 986 /*
 987     CALL msg_in, WHEN MSG_IN
 988 
 989 at 0x000000ed : */      0x8f0b0000,0x00000404,
 990 /*
 991     INT int_err_unexpected_phase, WHEN MSG_OUT
 992 
 993 at 0x000000ef : */      0x9e0b0000,0x00000000,
 994 /*
 995     INT int_err_unexpected_phase, WHEN DATA_OUT
 996 
 997 at 0x000000f1 : */      0x980b0000,0x00000000,
 998 /*
 999     INT int_err_unexpected_phase, WHEN DATA_IN
1000 
1001 at 0x000000f3 : */      0x990b0000,0x00000000,
1002 /*
1003     JUMP command_complete, WHEN STATUS
1004 
1005 at 0x000000f5 : */      0x830b0000,0x0000060c,
1006 /*
1007     JUMP other_transfer
1008 
1009 at 0x000000f7 : */      0x80080000,0x000003ac,
1010 /*
1011 
1012 ;
1013 ; msg_in_restart
1014 ; msg_in
1015 ; munge_msg
1016 ;
1017 ; PURPOSE : process messages from a target.  msg_in is called when the 
1018 ;       caller hasn't read the first byte of the message.  munge_message
1019 ;       is called when the caller has read the first byte of the message,
1020 ;       and left it in SFBR.  msg_in_restart is called when the caller 
1021 ;       hasnt read the first byte of the message, and wishes RETURN
1022 ;       to transfer control back to the address of the conditional
1023 ;       CALL instruction rather than to the instruction after it.
1024 ;
1025 ;       Various int_* interrupts are generated when the host system
1026 ;       needs to intervene, as is the case with SDTR, WDTR, and
1027 ;       INITIATE RECOVERY messages.
1028 ;
1029 ;       When the host system handles one of these interrupts,
1030 ;       it can respond by reentering at reject_message, 
1031 ;       which rejects the message and returns control to
1032 ;       the caller of msg_in or munge_msg, accept_message
1033 ;       which clears ACK and returns control, or reply_message
1034 ;       which sends the message pointed to by the DSA 
1035 ;       msgout_other table indirect field.
1036 ;
1037 ;       DISCONNECT messages are handled by moving the command
1038 ;       to the reconnect_dsa_queue.
1039 ;
1040 ; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
1041 ;       only)
1042 ;
1043 ; CALLS : NO.  The TEMP register isn't backed up to allow nested calls.
1044 ;
1045 ; MODIFIES : SCRATCH, DSA on DISCONNECT
1046 ;
1047 ; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
1048 ;       and normal return from message handlers running under
1049 ;       Linux, control is returned to the caller.  Receipt
1050 ;       of DISCONNECT messages pass control to dsa_schedule.
1051 ;
1052 ENTRY msg_in_restart
1053 msg_in_restart:
1054 ; XXX - hackish
1055 ;
1056 ; Since it's easier to debug changes to the statically 
1057 ; compiled code, rather than the dynamically generated 
1058 ; stuff, such as
1059 ;
1060 ;       MOVE x, y, WHEN data_phase
1061 ;       CALL other_z, WHEN NOT data_phase
1062 ;       MOVE x, y, WHEN data_phase
1063 ;
1064 ; I'd like to have certain routines (notably the message handler)
1065 ; restart on the conditional call rather than the next instruction.
1066 ;
1067 ; So, subtract 8 from the return address
1068 
1069     MOVE TEMP0 + 0xf8 TO TEMP0
1070 
1071 at 0x000000f9 : */      0x7e1cf800,0x00000000,
1072 /*
1073     MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
1074 
1075 at 0x000000fb : */      0x7f1dff00,0x00000000,
1076 /*
1077     MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
1078 
1079 at 0x000000fd : */      0x7f1eff00,0x00000000,
1080 /*
1081     MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
1082 
1083 at 0x000000ff : */      0x7f1fff00,0x00000000,
1084 /*
1085 
1086 ENTRY msg_in
1087 msg_in:
1088     MOVE 1, msg_buf, WHEN MSG_IN
1089 
1090 at 0x00000101 : */      0x0f000001,0x00000000,
1091 /*
1092 
1093 munge_msg:
1094     JUMP munge_extended, IF 0x01                ; EXTENDED MESSAGE
1095 
1096 at 0x00000103 : */      0x800c0001,0x00000524,
1097 /*
1098     JUMP munge_2, IF 0x20, AND MASK 0xdf        ; two byte message
1099 
1100 at 0x00000105 : */      0x800cdf20,0x0000044c,
1101 /*
1102 ;
1103 ; XXX - I've seen a handful of broken SCSI devices which fail to issue
1104 ;       a SAVE POINTERS message before disconnecting in the middle of 
1105 ;       a transfer, assuming that the DATA POINTER will be implicitly 
1106 ;       restored.  
1107 ;
1108 ; Historically, I've often done an implicit save when the DISCONNECT
1109 ; message is processed.  We may want to consider having the option of 
1110 ; doing that here. 
1111 ;
1112     JUMP munge_save_data_pointer, IF 0x02       ; SAVE DATA POINTER
1113 
1114 at 0x00000107 : */      0x800c0002,0x00000454,
1115 /*
1116     JUMP munge_restore_pointers, IF 0x03        ; RESTORE POINTERS 
1117 
1118 at 0x00000109 : */      0x800c0003,0x000004b8,
1119 /*
1120     JUMP munge_disconnect, IF 0x04              ; DISCONNECT
1121 
1122 at 0x0000010b : */      0x800c0004,0x0000051c,
1123 /*
1124     INT int_msg_1, IF 0x07                      ; MESSAGE REJECT
1125 
1126 at 0x0000010d : */      0x980c0007,0x01020000,
1127 /*
1128     INT int_msg_1, IF 0x0f                      ; INITIATE RECOVERY
1129 
1130 at 0x0000010f : */      0x980c000f,0x01020000,
1131 /*
1132 
1133 
1134 
1135     JUMP reject_message
1136 
1137 at 0x00000111 : */      0x80080000,0x000005b4,
1138 /*
1139 
1140 munge_2:
1141     JUMP reject_message
1142 
1143 at 0x00000113 : */      0x80080000,0x000005b4,
1144 /*
1145 ;
1146 ; The SCSI standard allows targets to recover from transient 
1147 ; error conditions by backing up the data pointer with a 
1148 ; RESTORE POINTERS message.  
1149 ;       
1150 ; So, we must save and restore the _residual_ code as well as 
1151 ; the current instruction pointer.  Because of this messiness,
1152 ; it is simpler to put dynamic code in the dsa for this and to
1153 ; just do a simple jump down there. 
1154 ;
1155 
1156 munge_save_data_pointer:
1157     MOVE DSA0 + dsa_save_data_pointer TO SFBR
1158 
1159 at 0x00000115 : */      0x76100000,0x00000000,
1160 /*
1161     MOVE SFBR TO SCRATCH0
1162 
1163 at 0x00000117 : */      0x6a340000,0x00000000,
1164 /*
1165     MOVE DSA1 + 0xff TO SFBR WITH CARRY
1166 
1167 at 0x00000119 : */      0x7711ff00,0x00000000,
1168 /*
1169     MOVE SFBR TO SCRATCH1
1170 
1171 at 0x0000011b : */      0x6a350000,0x00000000,
1172 /*
1173     MOVE DSA2 + 0xff TO SFBR WITH CARRY 
1174 
1175 at 0x0000011d : */      0x7712ff00,0x00000000,
1176 /*
1177     MOVE SFBR TO SCRATCH2
1178 
1179 at 0x0000011f : */      0x6a360000,0x00000000,
1180 /*
1181     MOVE DSA3 + 0xff TO SFBR WITH CARRY
1182 
1183 at 0x00000121 : */      0x7713ff00,0x00000000,
1184 /*
1185     MOVE SFBR TO SCRATCH3
1186 
1187 at 0x00000123 : */      0x6a370000,0x00000000,
1188 /*
1189 
1190     MOVE dmode_ncr_to_memory TO DMODE
1191 
1192 at 0x00000125 : */      0x78380000,0x00000000,
1193 /*
1194     MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
1195 
1196 at 0x00000127 : */      0xc0000004,0x00000000,0x000004b4,
1197 /*
1198     MOVE dmode_memory_to_memory TO DMODE
1199 
1200 at 0x0000012a : */      0x78380000,0x00000000,
1201 /*
1202 jump_dsa_save:
1203     JUMP 0
1204 
1205 at 0x0000012c : */      0x80080000,0x00000000,
1206 /*
1207 
1208 munge_restore_pointers:
1209     MOVE DSA0 + dsa_restore_pointers TO SFBR
1210 
1211 at 0x0000012e : */      0x76100000,0x00000000,
1212 /*
1213     MOVE SFBR TO SCRATCH0
1214 
1215 at 0x00000130 : */      0x6a340000,0x00000000,
1216 /*
1217     MOVE DSA1 + 0xff TO SFBR WITH CARRY
1218 
1219 at 0x00000132 : */      0x7711ff00,0x00000000,
1220 /*
1221     MOVE SFBR TO SCRATCH1
1222 
1223 at 0x00000134 : */      0x6a350000,0x00000000,
1224 /*
1225     MOVE DSA2 + 0xff TO SFBR WITH CARRY
1226 
1227 at 0x00000136 : */      0x7712ff00,0x00000000,
1228 /*
1229     MOVE SFBR TO SCRATCH2
1230 
1231 at 0x00000138 : */      0x6a360000,0x00000000,
1232 /*
1233     MOVE DSA3 + 0xff TO SFBR WITH CARRY
1234 
1235 at 0x0000013a : */      0x7713ff00,0x00000000,
1236 /*
1237     MOVE SFBR TO SCRATCH3
1238 
1239 at 0x0000013c : */      0x6a370000,0x00000000,
1240 /*
1241 
1242     MOVE dmode_ncr_to_memory TO DMODE
1243 
1244 at 0x0000013e : */      0x78380000,0x00000000,
1245 /*
1246     MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
1247 
1248 at 0x00000140 : */      0xc0000004,0x00000000,0x00000518,
1249 /*
1250     MOVE dmode_memory_to_memory TO DMODE
1251 
1252 at 0x00000143 : */      0x78380000,0x00000000,
1253 /*
1254 jump_dsa_restore:
1255     JUMP 0
1256 
1257 at 0x00000145 : */      0x80080000,0x00000000,
1258 /*
1259 
1260 
1261 munge_disconnect:
1262 
1263 
1264 
1265 
1266 
1267 
1268 
1269 
1270 
1271  
1272 
1273 
1274 
1275 
1276 
1277 
1278     JUMP dsa_schedule
1279 
1280 at 0x00000147 : */      0x80080000,0x00000168,
1281 /*
1282 
1283 
1284 
1285 
1286 
1287 munge_extended:
1288     CLEAR ACK
1289 
1290 at 0x00000149 : */      0x60000040,0x00000000,
1291 /*
1292     INT int_err_unexpected_phase, WHEN NOT MSG_IN
1293 
1294 at 0x0000014b : */      0x9f030000,0x00000000,
1295 /*
1296     MOVE 1, msg_buf + 1, WHEN MSG_IN
1297 
1298 at 0x0000014d : */      0x0f000001,0x00000001,
1299 /*
1300     JUMP munge_extended_2, IF 0x02
1301 
1302 at 0x0000014f : */      0x800c0002,0x00000554,
1303 /*
1304     JUMP munge_extended_3, IF 0x03 
1305 
1306 at 0x00000151 : */      0x800c0003,0x00000584,
1307 /*
1308     JUMP reject_message
1309 
1310 at 0x00000153 : */      0x80080000,0x000005b4,
1311 /*
1312 
1313 munge_extended_2:
1314     CLEAR ACK
1315 
1316 at 0x00000155 : */      0x60000040,0x00000000,
1317 /*
1318     MOVE 1, msg_buf + 2, WHEN MSG_IN
1319 
1320 at 0x00000157 : */      0x0f000001,0x00000002,
1321 /*
1322     JUMP reject_message, IF NOT 0x02    ; Must be WDTR
1323 
1324 at 0x00000159 : */      0x80040002,0x000005b4,
1325 /*
1326     CLEAR ACK
1327 
1328 at 0x0000015b : */      0x60000040,0x00000000,
1329 /*
1330     MOVE 1, msg_buf + 3, WHEN MSG_IN
1331 
1332 at 0x0000015d : */      0x0f000001,0x00000003,
1333 /*
1334     INT int_msg_wdtr
1335 
1336 at 0x0000015f : */      0x98080000,0x01000000,
1337 /*
1338 
1339 munge_extended_3:
1340     CLEAR ACK
1341 
1342 at 0x00000161 : */      0x60000040,0x00000000,
1343 /*
1344     MOVE 1, msg_buf + 2, WHEN MSG_IN
1345 
1346 at 0x00000163 : */      0x0f000001,0x00000002,
1347 /*
1348     JUMP reject_message, IF NOT 0x01    ; Must be SDTR
1349 
1350 at 0x00000165 : */      0x80040001,0x000005b4,
1351 /*
1352     CLEAR ACK
1353 
1354 at 0x00000167 : */      0x60000040,0x00000000,
1355 /*
1356     MOVE 2, msg_buf + 3, WHEN MSG_IN
1357 
1358 at 0x00000169 : */      0x0f000002,0x00000003,
1359 /*
1360     INT int_msg_sdtr
1361 
1362 at 0x0000016b : */      0x98080000,0x01010000,
1363 /*
1364 
1365 ENTRY reject_message
1366 reject_message:
1367     SET ATN
1368 
1369 at 0x0000016d : */      0x58000008,0x00000000,
1370 /*
1371     CLEAR ACK
1372 
1373 at 0x0000016f : */      0x60000040,0x00000000,
1374 /*
1375     MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
1376 
1377 at 0x00000171 : */      0x0e000001,0x00000000,
1378 /*
1379     RETURN
1380 
1381 at 0x00000173 : */      0x90080000,0x00000000,
1382 /*
1383 
1384 ENTRY accept_message
1385 accept_message:
1386     CLEAR ATN
1387 
1388 at 0x00000175 : */      0x60000008,0x00000000,
1389 /*
1390     CLEAR ACK
1391 
1392 at 0x00000177 : */      0x60000040,0x00000000,
1393 /*
1394     RETURN
1395 
1396 at 0x00000179 : */      0x90080000,0x00000000,
1397 /*
1398 
1399 ENTRY respond_message
1400 respond_message:
1401     SET ATN
1402 
1403 at 0x0000017b : */      0x58000008,0x00000000,
1404 /*
1405     CLEAR ACK
1406 
1407 at 0x0000017d : */      0x60000040,0x00000000,
1408 /*
1409     MOVE FROM dsa_msgout_other, WHEN MSG_OUT
1410 
1411 at 0x0000017f : */      0x1e000000,0x00000068,
1412 /*
1413     RETURN
1414 
1415 at 0x00000181 : */      0x90080000,0x00000000,
1416 /*
1417 
1418 ;
1419 ; command_complete
1420 ;
1421 ; PURPOSE : handle command termination when STATUS IN is detected by reading
1422 ;       a status byte followed by a command termination message. 
1423 ;
1424 ;       Normal termination results in an INTFLY instruction, and 
1425 ;       the host system can pick out which command terminated by 
1426 ;       examining the MESSAGE and STATUS buffers of all currently 
1427 ;       executing commands;
1428 ;
1429 ;       Abnormal (CHECK_CONDITION) termination results in an
1430 ;       int_err_check_condition interrupt so that a REQUEST SENSE
1431 ;       command can be issued out-of-order so that no other command
1432 ;       clears the contingent allegiance condition.
1433 ;       
1434 ;
1435 ; INPUTS : DSA - command        
1436 ;
1437 ; CALLS : OK
1438 ;
1439 ; EXITS : On successful termination, control is passed to schedule.
1440 ;       On abnormal termination, the user will usually modify the 
1441 ;       DSA fields and corresponding buffers and return control
1442 ;       to select.
1443 ;
1444 
1445 ENTRY command_complete
1446 command_complete:
1447     MOVE FROM dsa_status, WHEN STATUS
1448 
1449 at 0x00000183 : */      0x1b000000,0x00000060,
1450 /*
1451 
1452     MOVE SFBR TO SCRATCH0               ; Save status
1453 
1454 at 0x00000185 : */      0x6a340000,0x00000000,
1455 /*
1456 
1457 ENTRY command_complete_msgin
1458 command_complete_msgin:
1459     MOVE FROM dsa_msgin, WHEN MSG_IN
1460 
1461 at 0x00000187 : */      0x1f000000,0x00000058,
1462 /*
1463 ; Indicate that we should be expecting a disconnect
1464     MOVE SCNTL2 & 0x7f TO SCNTL2
1465 
1466 at 0x00000189 : */      0x7c027f00,0x00000000,
1467 /*
1468     CLEAR ACK
1469 
1470 at 0x0000018b : */      0x60000040,0x00000000,
1471 /*
1472 
1473     WAIT DISCONNECT
1474 
1475 at 0x0000018d : */      0x48000000,0x00000000,
1476 /*
1477 
1478 ;
1479 ; The SCSI specification states that when a UNIT ATTENTION condition
1480 ; is pending, as indicated by a CHECK CONDITION status message,
1481 ; the target shall revert to asynchronous transfers.  Since
1482 ; synchronous transfers parameters are maintained on a per INITIATOR/TARGET 
1483 ; basis, and returning control to our scheduler could work on a command
1484 ; running on another lun on that target using the old parameters, we must
1485 ; interrupt the host processor to get them changed, or change them ourselves.
1486 ;
1487 ; Once SCSI-II tagged queueing is implemented, things will be even more
1488 ; hairy, since contingent allegiance conditions exist on a per-target/lun
1489 ; basis, and issuing a new command with a different tag would clear it.
1490 ; In these cases, we must interrupt the host processor to get a request 
1491 ; added to the HEAD of the queue with the request sense command, or we
1492 ; must automatically issue the request sense command.
1493 
1494 
1495 
1496 
1497 
1498     INTFLY
1499 
1500 at 0x0000018f : */      0x98180000,0x00000000,
1501 /*
1502 
1503 
1504 
1505 
1506 
1507     JUMP schedule
1508 
1509 at 0x00000191 : */      0x80080000,0x00000000,
1510 /*
1511 command_failed:
1512     INT int_err_check_condition
1513 
1514 at 0x00000193 : */      0x98080000,0x00030000,
1515 /*
1516 
1517 
1518 
1519 
1520 ;
1521 ; wait_reselect
1522 ;
1523 ; PURPOSE : This is essentially the idle routine, where control lands
1524 ;       when there are no new processes to schedule.  wait_reselect
1525 ;       waits for reselection, selection, and new commands.
1526 ;
1527 ;       When a successful reselection occurs, with the aid 
1528 ;       of fixed up code in each DSA, wait_reselect walks the 
1529 ;       reconnect_dsa_queue, asking each dsa if the target ID
1530 ;       and LUN match its.
1531 ;
1532 ;       If a match is found, a call is made back to reselected_ok,
1533 ;       which through the miracles of self modifying code, extracts
1534 ;       the found DSA from the reconnect_dsa_queue and then 
1535 ;       returns control to the DSAs thread of execution.
1536 ;
1537 ; INPUTS : NONE
1538 ;
1539 ; CALLS : OK
1540 ;
1541 ; MODIFIES : DSA,
1542 ;
1543 ; EXITS : On successful reselection, control is returned to the 
1544 ;       DSA which called reselected_ok.  If the WAIT RESELECT
1545 ;       was interrupted by a new commands arrival signaled by 
1546 ;       SIG_P, control is passed to schedule.  If the NCR is 
1547 ;       selected, the host system is interrupted with an 
1548 ;       int_err_selected which is usually responded to by
1549 ;       setting DSP to the target_abort address.
1550 
1551 ENTRY wait_reselect
1552 wait_reselect:
1553 
1554 
1555 
1556 
1557 
1558 
1559     WAIT RESELECT wait_reselect_failed
1560 
1561 at 0x00000195 : */      0x50000000,0x0000076c,
1562 /*
1563 
1564 reselected:
1565 
1566 
1567 
1568     CLEAR TARGET
1569 
1570 at 0x00000197 : */      0x60000200,0x00000000,
1571 /*
1572     MOVE dmode_memory_to_memory TO DMODE
1573 
1574 at 0x00000199 : */      0x78380000,0x00000000,
1575 /*
1576     ; Read all data needed to reestablish the nexus - 
1577     MOVE 1, reselected_identify, WHEN MSG_IN
1578 
1579 at 0x0000019b : */      0x0f000001,0x00000000,
1580 /*
1581     ; We used to CLEAR ACK here.
1582 
1583 
1584 
1585 
1586 
1587     ; Point DSA at the current head of the disconnected queue.
1588     MOVE dmode_memory_to_ncr  TO DMODE
1589 
1590 at 0x0000019d : */      0x78380000,0x00000000,
1591 /*
1592     MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
1593 
1594 at 0x0000019f : */      0xc0000004,0x00000000,0x00000000,
1595 /*
1596     MOVE dmode_memory_to_memory TO DMODE
1597 
1598 at 0x000001a2 : */      0x78380000,0x00000000,
1599 /*
1600     CALL scratch_to_dsa
1601 
1602 at 0x000001a4 : */      0x88080000,0x00000960,
1603 /*
1604 
1605     ; Fix the update-next pointer so that the reconnect_dsa_head
1606     ; pointer is the one that will be updated if this DSA is a hit 
1607     ; and we remove it from the queue.
1608 
1609     MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok + 8
1610 
1611 at 0x000001a6 : */      0xc0000004,0x00000000,0x00000758,
1612 /*
1613 
1614 ENTRY reselected_check_next
1615 reselected_check_next:
1616 
1617 
1618 
1619     ; Check for a NULL pointer.
1620     MOVE DSA0 TO SFBR
1621 
1622 at 0x000001a9 : */      0x72100000,0x00000000,
1623 /*
1624     JUMP reselected_not_end, IF NOT 0
1625 
1626 at 0x000001ab : */      0x80040000,0x000006ec,
1627 /*
1628     MOVE DSA1 TO SFBR
1629 
1630 at 0x000001ad : */      0x72110000,0x00000000,
1631 /*
1632     JUMP reselected_not_end, IF NOT 0
1633 
1634 at 0x000001af : */      0x80040000,0x000006ec,
1635 /*
1636     MOVE DSA2 TO SFBR
1637 
1638 at 0x000001b1 : */      0x72120000,0x00000000,
1639 /*
1640     JUMP reselected_not_end, IF NOT 0
1641 
1642 at 0x000001b3 : */      0x80040000,0x000006ec,
1643 /*
1644     MOVE DSA3 TO SFBR
1645 
1646 at 0x000001b5 : */      0x72130000,0x00000000,
1647 /*
1648     JUMP reselected_not_end, IF NOT 0
1649 
1650 at 0x000001b7 : */      0x80040000,0x000006ec,
1651 /*
1652     INT int_err_unexpected_reselect
1653 
1654 at 0x000001b9 : */      0x98080000,0x00020000,
1655 /*
1656 
1657 reselected_not_end:
1658     ;
1659     ; XXX the ALU is only eight bits wide, and the assembler
1660     ; wont do the dirt work for us.  As long as dsa_check_reselect
1661     ; is negative, we need to sign extend with 1 bits to the full
1662     ; 32 bit width of the address.
1663     ;
1664     ; A potential work around would be to have a known alignment 
1665     ; of the DSA structure such that the base address plus 
1666     ; dsa_check_reselect doesn't require carrying from bytes 
1667     ; higher than the LSB.
1668     ;
1669 
1670     MOVE DSA0 TO SFBR
1671 
1672 at 0x000001bb : */      0x72100000,0x00000000,
1673 /*
1674     MOVE SFBR + dsa_check_reselect TO SCRATCH0
1675 
1676 at 0x000001bd : */      0x6e340000,0x00000000,
1677 /*
1678     MOVE DSA1 TO SFBR
1679 
1680 at 0x000001bf : */      0x72110000,0x00000000,
1681 /*
1682     MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
1683 
1684 at 0x000001c1 : */      0x6f35ff00,0x00000000,
1685 /*
1686     MOVE DSA2 TO SFBR
1687 
1688 at 0x000001c3 : */      0x72120000,0x00000000,
1689 /*
1690     MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
1691 
1692 at 0x000001c5 : */      0x6f36ff00,0x00000000,
1693 /*
1694     MOVE DSA3 TO SFBR
1695 
1696 at 0x000001c7 : */      0x72130000,0x00000000,
1697 /*
1698     MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
1699 
1700 at 0x000001c9 : */      0x6f37ff00,0x00000000,
1701 /*
1702 
1703     MOVE dmode_ncr_to_memory TO DMODE
1704 
1705 at 0x000001cb : */      0x78380000,0x00000000,
1706 /*
1707     MOVE MEMORY 4, addr_scratch, reselected_check + 4
1708 
1709 at 0x000001cd : */      0xc0000004,0x00000000,0x0000074c,
1710 /*
1711     MOVE dmode_memory_to_memory TO DMODE
1712 
1713 at 0x000001d0 : */      0x78380000,0x00000000,
1714 /*
1715 reselected_check:
1716     JUMP 0
1717 
1718 at 0x000001d2 : */      0x80080000,0x00000000,
1719 /*
1720 
1721 
1722 ;
1723 ;
1724 ENTRY reselected_ok
1725 reselected_ok:
1726     MOVE MEMORY 4, 0, 0                         ; Patched : first word
1727 
1728 at 0x000001d4 : */      0xc0000004,0x00000000,0x00000000,
1729 /*
1730                                                 ;       is address of 
1731                                                 ;       successful dsa_next
1732                                                 ; Second word is last 
1733                                                 ;       unsuccessful dsa_next,
1734                                                 ;       starting with 
1735                                                 ;       dsa_reconnect_head
1736     ; We used to CLEAR ACK here.
1737 
1738 
1739 
1740 
1741 
1742 
1743     RETURN                                      ; Return control to where
1744 
1745 at 0x000001d7 : */      0x90080000,0x00000000,
1746 /*
1747 
1748 
1749 
1750 
1751 selected:
1752     INT int_err_selected;
1753 
1754 at 0x000001d9 : */      0x98080000,0x00010000,
1755 /*
1756 
1757 ;
1758 ; A select or reselect failure can be caused by one of two conditions : 
1759 ; 1.  SIG_P was set.  This will be the case if the user has written
1760 ;       a new value to a previously NULL head of the issue queue.
1761 ;
1762 ; 2.  The NCR53c810 was selected or reselected by another device.
1763 ; 
1764 
1765 wait_reselect_failed:
1766 
1767 
1768 
1769     MOVE SIST0 & 0x20 TO SFBR
1770 
1771 at 0x000001db : */      0x74422000,0x00000000,
1772 /*
1773     JUMP selected, IF 0x20
1774 
1775 at 0x000001dd : */      0x800c0020,0x00000764,
1776 /*
1777 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1778     MOVE CTEST2 & 0x40 TO SFBR  
1779 
1780 at 0x000001df : */      0x741a4000,0x00000000,
1781 /*
1782     JUMP schedule, IF 0x40
1783 
1784 at 0x000001e1 : */      0x800c0040,0x00000000,
1785 /*
1786 ; FIXME : Something bogus happened, and we shouldn't fail silently.
1787 
1788 
1789 
1790     INT int_debug_panic
1791 
1792 at 0x000001e3 : */      0x98080000,0x030b0000,
1793 /*
1794 
1795 
1796 
1797 select_failed:
1798 
1799 
1800 
1801 ; Otherwise, mask the selected and reselected bits off SIST0
1802     MOVE SIST0 & 0x30 TO SFBR
1803 
1804 at 0x000001e5 : */      0x74423000,0x00000000,
1805 /*
1806     JUMP selected, IF 0x20
1807 
1808 at 0x000001e7 : */      0x800c0020,0x00000764,
1809 /*
1810     JUMP reselected, IF 0x10 
1811 
1812 at 0x000001e9 : */      0x800c0010,0x0000065c,
1813 /*
1814 ; If SIGP is set, the user just gave us another command, and
1815 ; we should restart or return to the scheduler.
1816 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1817     MOVE CTEST2 & 0x40 TO SFBR  
1818 
1819 at 0x000001eb : */      0x741a4000,0x00000000,
1820 /*
1821     JUMP select, IF 0x40
1822 
1823 at 0x000001ed : */      0x800c0040,0x000001fc,
1824 /*
1825 ; FIXME : Something bogus happened, and we shouldn't fail silently.
1826 
1827 
1828 
1829     INT int_debug_panic
1830 
1831 at 0x000001ef : */      0x98080000,0x030b0000,
1832 /*
1833 
1834 
1835 ;
1836 ; test_1
1837 ; test_2
1838 ;
1839 ; PURPOSE : run some verification tests on the NCR.  test_1
1840 ;       copies test_src to test_dest and interrupts the host
1841 ;       processor, testing for cache coherency and interrupt
1842 ;       problems in the processes.
1843 ;
1844 ;       test_2 runs a command with offsets relative to the 
1845 ;       DSA on entry, and is useful for miscellaneous experimentation.
1846 ;
1847 
1848 ; Verify that interrupts are working correctly and that we don't 
1849 ; have a cache invalidation problem.
1850 
1851 ABSOLUTE test_src = 0, test_dest = 0
1852 ENTRY test_1
1853 test_1:
1854     MOVE MEMORY 4, test_src, test_dest
1855 
1856 at 0x000001f1 : */      0xc0000004,0x00000000,0x00000000,
1857 /*
1858     INT int_test_1
1859 
1860 at 0x000001f4 : */      0x98080000,0x04000000,
1861 /*
1862 
1863 ;
1864 ; Run arbitrary commands, with test code establishing a DSA
1865 ;
1866  
1867 ENTRY test_2
1868 test_2:
1869     CLEAR TARGET
1870 
1871 at 0x000001f6 : */      0x60000200,0x00000000,
1872 /*
1873     SELECT ATN FROM 0, test_2_fail
1874 
1875 at 0x000001f8 : */      0x43000000,0x00000830,
1876 /*
1877     JUMP test_2_msgout, WHEN MSG_OUT
1878 
1879 at 0x000001fa : */      0x860b0000,0x000007f0,
1880 /*
1881 ENTRY test_2_msgout
1882 test_2_msgout:
1883     MOVE FROM 8, WHEN MSG_OUT
1884 
1885 at 0x000001fc : */      0x1e000000,0x00000008,
1886 /*
1887     MOVE FROM 16, WHEN CMD 
1888 
1889 at 0x000001fe : */      0x1a000000,0x00000010,
1890 /*
1891     MOVE FROM 24, WHEN DATA_IN
1892 
1893 at 0x00000200 : */      0x19000000,0x00000018,
1894 /*
1895     MOVE FROM 32, WHEN STATUS
1896 
1897 at 0x00000202 : */      0x1b000000,0x00000020,
1898 /*
1899     MOVE FROM 40, WHEN MSG_IN
1900 
1901 at 0x00000204 : */      0x1f000000,0x00000028,
1902 /*
1903     MOVE SCNTL2 & 0x7f TO SCNTL2
1904 
1905 at 0x00000206 : */      0x7c027f00,0x00000000,
1906 /*
1907     CLEAR ACK
1908 
1909 at 0x00000208 : */      0x60000040,0x00000000,
1910 /*
1911     WAIT DISCONNECT
1912 
1913 at 0x0000020a : */      0x48000000,0x00000000,
1914 /*
1915 test_2_fail:
1916     INT int_test_2
1917 
1918 at 0x0000020c : */      0x98080000,0x04010000,
1919 /*
1920 
1921 ENTRY debug_break
1922 debug_break:
1923     INT int_debug_break
1924 
1925 at 0x0000020e : */      0x98080000,0x03000000,
1926 /*
1927 
1928 ;
1929 ; initiator_abort
1930 ; target_abort
1931 ;
1932 ; PURPOSE : Abort the currently established nexus from with initiator
1933 ;       or target mode.
1934 ;
1935 ;  
1936 
1937 ENTRY target_abort
1938 target_abort:
1939     SET TARGET
1940 
1941 at 0x00000210 : */      0x58000200,0x00000000,
1942 /*
1943     DISCONNECT
1944 
1945 at 0x00000212 : */      0x48000000,0x00000000,
1946 /*
1947     CLEAR TARGET
1948 
1949 at 0x00000214 : */      0x60000200,0x00000000,
1950 /*
1951     JUMP schedule
1952 
1953 at 0x00000216 : */      0x80080000,0x00000000,
1954 /*
1955     
1956 ENTRY initiator_abort
1957 initiator_abort:
1958     SET ATN
1959 
1960 at 0x00000218 : */      0x58000008,0x00000000,
1961 /*
1962 ;
1963 ; The SCSI-I specification says that targets may go into MSG out at 
1964 ; their leisure upon receipt of the ATN single.  On all versions of the 
1965 ; specification, we can't change phases until REQ transitions true->false, 
1966 ; so we need to sink/source one byte of data to allow the transition.
1967 ;
1968 ; For the sake of safety, we'll only source one byte of data in all 
1969 ; cases, but to accomodate the SCSI-I dain bramage, we'll sink an  
1970 ; arbitrary number of bytes.
1971     JUMP spew_cmd, WHEN CMD
1972 
1973 at 0x0000021a : */      0x820b0000,0x00000898,
1974 /*
1975     JUMP eat_msgin, WHEN MSG_IN
1976 
1977 at 0x0000021c : */      0x870b0000,0x000008a8,
1978 /*
1979     JUMP eat_datain, WHEN DATA_IN
1980 
1981 at 0x0000021e : */      0x810b0000,0x000008d8,
1982 /*
1983     JUMP eat_status, WHEN STATUS
1984 
1985 at 0x00000220 : */      0x830b0000,0x000008c0,
1986 /*
1987     JUMP spew_dataout, WHEN DATA_OUT
1988 
1989 at 0x00000222 : */      0x800b0000,0x000008f0,
1990 /*
1991     JUMP sated
1992 
1993 at 0x00000224 : */      0x80080000,0x000008f8,
1994 /*
1995 spew_cmd:
1996     MOVE 1, NCR53c7xx_zero, WHEN CMD
1997 
1998 at 0x00000226 : */      0x0a000001,0x00000000,
1999 /*
2000     JUMP sated
2001 
2002 at 0x00000228 : */      0x80080000,0x000008f8,
2003 /*
2004 eat_msgin:
2005     MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
2006 
2007 at 0x0000022a : */      0x0f000001,0x00000000,
2008 /*
2009     JUMP eat_msgin, WHEN MSG_IN
2010 
2011 at 0x0000022c : */      0x870b0000,0x000008a8,
2012 /*
2013     JUMP sated
2014 
2015 at 0x0000022e : */      0x80080000,0x000008f8,
2016 /*
2017 eat_status:
2018     MOVE 1, NCR53c7xx_sink, WHEN STATUS
2019 
2020 at 0x00000230 : */      0x0b000001,0x00000000,
2021 /*
2022     JUMP eat_status, WHEN STATUS
2023 
2024 at 0x00000232 : */      0x830b0000,0x000008c0,
2025 /*
2026     JUMP sated
2027 
2028 at 0x00000234 : */      0x80080000,0x000008f8,
2029 /*
2030 eat_datain:
2031     MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
2032 
2033 at 0x00000236 : */      0x09000001,0x00000000,
2034 /*
2035     JUMP eat_datain, WHEN DATA_IN
2036 
2037 at 0x00000238 : */      0x810b0000,0x000008d8,
2038 /*
2039     JUMP sated
2040 
2041 at 0x0000023a : */      0x80080000,0x000008f8,
2042 /*
2043 spew_dataout:
2044     MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
2045 
2046 at 0x0000023c : */      0x08000001,0x00000000,
2047 /*
2048 sated:
2049     MOVE SCNTL2 & 0x7f TO SCNTL2
2050 
2051 at 0x0000023e : */      0x7c027f00,0x00000000,
2052 /*
2053     MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
2054 
2055 at 0x00000240 : */      0x0e000001,0x00000000,
2056 /*
2057     WAIT DISCONNECT
2058 
2059 at 0x00000242 : */      0x48000000,0x00000000,
2060 /*
2061     INT int_norm_aborted
2062 
2063 at 0x00000244 : */      0x98080000,0x02040000,
2064 /*
2065 
2066 ;
2067 ; dsa_to_scratch
2068 ; scratch_to_dsa
2069 ;
2070 ; PURPOSE :
2071 ;       The NCR chips cannot do a move memory instruction with the DSA register 
2072 ;       as the source or destination.  So, we provide a couple of subroutines
2073 ;       that let us switch between the DSA register and scratch register.
2074 ;
2075 ;       Memory moves to/from the DSPS  register also don't work, but we 
2076 ;       don't use them.
2077 ;
2078 ;
2079 
2080  
2081 dsa_to_scratch:
2082     MOVE DSA0 TO SFBR
2083 
2084 at 0x00000246 : */      0x72100000,0x00000000,
2085 /*
2086     MOVE SFBR TO SCRATCH0
2087 
2088 at 0x00000248 : */      0x6a340000,0x00000000,
2089 /*
2090     MOVE DSA1 TO SFBR
2091 
2092 at 0x0000024a : */      0x72110000,0x00000000,
2093 /*
2094     MOVE SFBR TO SCRATCH1
2095 
2096 at 0x0000024c : */      0x6a350000,0x00000000,
2097 /*
2098     MOVE DSA2 TO SFBR
2099 
2100 at 0x0000024e : */      0x72120000,0x00000000,
2101 /*
2102     MOVE SFBR TO SCRATCH2
2103 
2104 at 0x00000250 : */      0x6a360000,0x00000000,
2105 /*
2106     MOVE DSA3 TO SFBR
2107 
2108 at 0x00000252 : */      0x72130000,0x00000000,
2109 /*
2110     MOVE SFBR TO SCRATCH3
2111 
2112 at 0x00000254 : */      0x6a370000,0x00000000,
2113 /*
2114     RETURN
2115 
2116 at 0x00000256 : */      0x90080000,0x00000000,
2117 /*
2118 
2119 scratch_to_dsa:
2120     MOVE SCRATCH0 TO SFBR
2121 
2122 at 0x00000258 : */      0x72340000,0x00000000,
2123 /*
2124     MOVE SFBR TO DSA0
2125 
2126 at 0x0000025a : */      0x6a100000,0x00000000,
2127 /*
2128     MOVE SCRATCH1 TO SFBR
2129 
2130 at 0x0000025c : */      0x72350000,0x00000000,
2131 /*
2132     MOVE SFBR TO DSA1
2133 
2134 at 0x0000025e : */      0x6a110000,0x00000000,
2135 /*
2136     MOVE SCRATCH2 TO SFBR
2137 
2138 at 0x00000260 : */      0x72360000,0x00000000,
2139 /*
2140     MOVE SFBR TO DSA2
2141 
2142 at 0x00000262 : */      0x6a120000,0x00000000,
2143 /*
2144     MOVE SCRATCH3 TO SFBR
2145 
2146 at 0x00000264 : */      0x72370000,0x00000000,
2147 /*
2148     MOVE SFBR TO DSA3
2149 
2150 at 0x00000266 : */      0x6a130000,0x00000000,
2151 /*
2152     RETURN
2153 
2154 at 0x00000268 : */      0x90080000,0x00000000,
2155 };
2156 
2157 #define A_NCR53c7xx_msg_abort   0x00000000
2158 u32 A_NCR53c7xx_msg_abort_used[] = {
2159         0x00000241,
2160 };
2161 
2162 #define A_NCR53c7xx_msg_reject  0x00000000
2163 u32 A_NCR53c7xx_msg_reject_used[] = {
2164         0x00000172,
2165 };
2166 
2167 #define A_NCR53c7xx_sink        0x00000000
2168 u32 A_NCR53c7xx_sink_used[] = {
2169         0x0000022b,
2170         0x00000231,
2171         0x00000237,
2172 };
2173 
2174 #define A_NCR53c7xx_zero        0x00000000
2175 u32 A_NCR53c7xx_zero_used[] = {
2176         0x00000227,
2177         0x0000023d,
2178 };
2179 
2180 #define A_NOP_insn      0x00000000
2181 u32 A_NOP_insn_used[] = {
2182         0x00000010,
2183 };
2184 
2185 #define A_addr_reconnect_dsa_head       0x00000000
2186 u32 A_addr_reconnect_dsa_head_used[] = {
2187         0x000001a7,
2188 };
2189 
2190 #define A_addr_scratch  0x00000000
2191 u32 A_addr_scratch_used[] = {
2192         0x00000004,
2193         0x0000001b,
2194         0x00000046,
2195         0x00000067,
2196         0x00000073,
2197         0x000000b0,
2198         0x000000c6,
2199         0x00000128,
2200         0x00000141,
2201         0x000001a1,
2202         0x000001ce,
2203 };
2204 
2205 #define A_addr_temp     0x00000000
2206 u32 A_addr_temp_used[] = {
2207         0x00000025,
2208         0x00000034,
2209 };
2210 
2211 #define A_dmode_memory_to_memory        0x00000000
2212 u32 A_dmode_memory_to_memory_used[] = {
2213         0x00000005,
2214         0x0000001c,
2215         0x00000027,
2216         0x00000035,
2217         0x00000047,
2218         0x00000069,
2219         0x00000075,
2220         0x000000b2,
2221         0x000000c8,
2222         0x0000012a,
2223         0x00000143,
2224         0x00000199,
2225         0x000001a2,
2226         0x000001d0,
2227 };
2228 
2229 #define A_dmode_memory_to_ncr   0x00000000
2230 u32 A_dmode_memory_to_ncr_used[] = {
2231         0x00000000,
2232         0x00000017,
2233         0x00000030,
2234         0x00000042,
2235         0x0000019d,
2236 };
2237 
2238 #define A_dmode_ncr_to_memory   0x00000000
2239 u32 A_dmode_ncr_to_memory_used[] = {
2240         0x00000022,
2241         0x00000064,
2242         0x00000070,
2243         0x000000ad,
2244         0x000000c3,
2245         0x00000125,
2246         0x0000013e,
2247         0x000001cb,
2248 };
2249 
2250 #define A_dsa_check_reselect    0x00000000
2251 u32 A_dsa_check_reselect_used[] = {
2252         0x000001bd,
2253 };
2254 
2255 #define A_dsa_cmdout    0x00000048
2256 u32 A_dsa_cmdout_used[] = {
2257         0x00000094,
2258 };
2259 
2260 #define A_dsa_cmnd      0x00000038
2261 u32 A_dsa_cmnd_used[] = {
2262 };
2263 
2264 #define A_dsa_datain    0x00000054
2265 u32 A_dsa_datain_used[] = {
2266         0x000000bb,
2267 };
2268 
2269 #define A_dsa_dataout   0x00000050
2270 u32 A_dsa_dataout_used[] = {
2271         0x000000a5,
2272 };
2273 
2274 #define A_dsa_end       0x00000070
2275 u32 A_dsa_end_used[] = {
2276 };
2277 
2278 #define A_dsa_fields_start      0x00000000
2279 u32 A_dsa_fields_start_used[] = {
2280 };
2281 
2282 #define A_dsa_msgin     0x00000058
2283 u32 A_dsa_msgin_used[] = {
2284         0x00000188,
2285 };
2286 
2287 #define A_dsa_msgout    0x00000040
2288 u32 A_dsa_msgout_used[] = {
2289         0x00000086,
2290 };
2291 
2292 #define A_dsa_msgout_other      0x00000068
2293 u32 A_dsa_msgout_other_used[] = {
2294         0x00000180,
2295 };
2296 
2297 #define A_dsa_next      0x00000030
2298 u32 A_dsa_next_used[] = {
2299         0x0000005c,
2300 };
2301 
2302 #define A_dsa_restore_pointers  0x00000000
2303 u32 A_dsa_restore_pointers_used[] = {
2304         0x0000012e,
2305 };
2306 
2307 #define A_dsa_save_data_pointer 0x00000000
2308 u32 A_dsa_save_data_pointer_used[] = {
2309         0x00000115,
2310 };
2311 
2312 #define A_dsa_select    0x0000003c
2313 u32 A_dsa_select_used[] = {
2314         0x00000081,
2315 };
2316 
2317 #define A_dsa_status    0x00000060
2318 u32 A_dsa_status_used[] = {
2319         0x00000184,
2320 };
2321 
2322 #define A_dsa_temp_addr_array_value     0x00000000
2323 u32 A_dsa_temp_addr_array_value_used[] = {
2324 };
2325 
2326 #define A_dsa_temp_addr_dsa_value       0x00000000
2327 u32 A_dsa_temp_addr_dsa_value_used[] = {
2328         0x00000003,
2329 };
2330 
2331 #define A_dsa_temp_addr_new_value       0x00000000
2332 u32 A_dsa_temp_addr_new_value_used[] = {
2333 };
2334 
2335 #define A_dsa_temp_addr_next    0x00000000
2336 u32 A_dsa_temp_addr_next_used[] = {
2337         0x00000015,
2338         0x0000004e,
2339 };
2340 
2341 #define A_dsa_temp_addr_residual        0x00000000
2342 u32 A_dsa_temp_addr_residual_used[] = {
2343         0x0000002a,
2344         0x00000039,
2345 };
2346 
2347 #define A_dsa_temp_addr_saved_pointer   0x00000000
2348 u32 A_dsa_temp_addr_saved_pointer_used[] = {
2349         0x00000026,
2350         0x00000033,
2351 };
2352 
2353 #define A_dsa_temp_addr_saved_residual  0x00000000
2354 u32 A_dsa_temp_addr_saved_residual_used[] = {
2355         0x0000002b,
2356         0x00000038,
2357 };
2358 
2359 #define A_dsa_temp_lun  0x00000000
2360 u32 A_dsa_temp_lun_used[] = {
2361         0x0000004b,
2362 };
2363 
2364 #define A_dsa_temp_next 0x00000000
2365 u32 A_dsa_temp_next_used[] = {
2366         0x0000001a,
2367 };
2368 
2369 #define A_dsa_temp_sync 0x00000000
2370 u32 A_dsa_temp_sync_used[] = {
2371         0x00000053,
2372 };
2373 
2374 #define A_dsa_temp_target       0x00000000
2375 u32 A_dsa_temp_target_used[] = {
2376         0x00000040,
2377 };
2378 
2379 #define A_int_debug_break       0x03000000
2380 u32 A_int_debug_break_used[] = {
2381         0x0000020f,
2382 };
2383 
2384 #define A_int_debug_panic       0x030b0000
2385 u32 A_int_debug_panic_used[] = {
2386         0x000001e4,
2387         0x000001f0,
2388 };
2389 
2390 #define A_int_err_check_condition       0x00030000
2391 u32 A_int_err_check_condition_used[] = {
2392         0x00000194,
2393 };
2394 
2395 #define A_int_err_no_phase      0x00040000
2396 u32 A_int_err_no_phase_used[] = {
2397 };
2398 
2399 #define A_int_err_selected      0x00010000
2400 u32 A_int_err_selected_used[] = {
2401         0x000001da,
2402 };
2403 
2404 #define A_int_err_unexpected_phase      0x00000000
2405 u32 A_int_err_unexpected_phase_used[] = {
2406         0x0000008c,
2407         0x00000092,
2408         0x0000009a,
2409         0x000000d0,
2410         0x000000d4,
2411         0x000000d6,
2412         0x000000de,
2413         0x000000e2,
2414         0x000000e4,
2415         0x000000ec,
2416         0x000000f0,
2417         0x000000f2,
2418         0x000000f4,
2419         0x0000014c,
2420 };
2421 
2422 #define A_int_err_unexpected_reselect   0x00020000
2423 u32 A_int_err_unexpected_reselect_used[] = {
2424         0x000001ba,
2425 };
2426 
2427 #define A_int_msg_1     0x01020000
2428 u32 A_int_msg_1_used[] = {
2429         0x0000010e,
2430         0x00000110,
2431 };
2432 
2433 #define A_int_msg_sdtr  0x01010000
2434 u32 A_int_msg_sdtr_used[] = {
2435         0x0000016c,
2436 };
2437 
2438 #define A_int_msg_wdtr  0x01000000
2439 u32 A_int_msg_wdtr_used[] = {
2440         0x00000160,
2441 };
2442 
2443 #define A_int_norm_aborted      0x02040000
2444 u32 A_int_norm_aborted_used[] = {
2445         0x00000245,
2446 };
2447 
2448 #define A_int_norm_command_complete     0x02020000
2449 u32 A_int_norm_command_complete_used[] = {
2450 };
2451 
2452 #define A_int_norm_disconnected 0x02030000
2453 u32 A_int_norm_disconnected_used[] = {
2454 };
2455 
2456 #define A_int_norm_reselect_complete    0x02010000
2457 u32 A_int_norm_reselect_complete_used[] = {
2458 };
2459 
2460 #define A_int_norm_reset        0x02050000
2461 u32 A_int_norm_reset_used[] = {
2462 };
2463 
2464 #define A_int_norm_select_complete      0x02000000
2465 u32 A_int_norm_select_complete_used[] = {
2466 };
2467 
2468 #define A_int_test_1    0x04000000
2469 u32 A_int_test_1_used[] = {
2470         0x000001f5,
2471 };
2472 
2473 #define A_int_test_2    0x04010000
2474 u32 A_int_test_2_used[] = {
2475         0x0000020d,
2476 };
2477 
2478 #define A_int_test_3    0x04020000
2479 u32 A_int_test_3_used[] = {
2480 };
2481 
2482 #define A_msg_buf       0x00000000
2483 u32 A_msg_buf_used[] = {
2484         0x00000102,
2485         0x0000014e,
2486         0x00000158,
2487         0x0000015e,
2488         0x00000164,
2489         0x0000016a,
2490 };
2491 
2492 #define A_reconnect_dsa_head    0x00000000
2493 u32 A_reconnect_dsa_head_used[] = {
2494         0x0000006c,
2495         0x00000074,
2496         0x000001a0,
2497 };
2498 
2499 #define A_reselected_identify   0x00000000
2500 u32 A_reselected_identify_used[] = {
2501         0x00000045,
2502         0x0000019c,
2503 };
2504 
2505 #define A_reselected_tag        0x00000000
2506 u32 A_reselected_tag_used[] = {
2507 };
2508 
2509 #define A_schedule      0x00000000
2510 u32 A_schedule_used[] = {
2511         0x0000007e,
2512         0x00000192,
2513         0x000001e2,
2514         0x00000217,
2515 };
2516 
2517 #define A_test_dest     0x00000000
2518 u32 A_test_dest_used[] = {
2519         0x000001f3,
2520 };
2521 
2522 #define A_test_src      0x00000000
2523 u32 A_test_src_used[] = {
2524         0x000001f2,
2525 };
2526 
2527 #define Ent_accept_message      0x000005d4
2528 #define Ent_cmdout_cmdout       0x0000024c
2529 #define Ent_command_complete    0x0000060c
2530 #define Ent_command_complete_msgin      0x0000061c
2531 #define Ent_data_transfer       0x00000254
2532 #define Ent_datain_to_jump      0x00000328
2533 #define Ent_debug_break 0x00000838
2534 #define Ent_dsa_code_begin      0x00000000
2535 #define Ent_dsa_code_check_reselect     0x000000f8
2536 #define Ent_dsa_code_fix_jump   0x0000003c
2537 #define Ent_dsa_code_restore_pointers   0x000000c0
2538 #define Ent_dsa_code_save_data_pointer  0x00000088
2539 #define Ent_dsa_code_template   0x00000000
2540 #define Ent_dsa_code_template_end       0x00000168
2541 #define Ent_dsa_schedule        0x00000168
2542 #define Ent_dsa_zero    0x00000168
2543 #define Ent_end_data_transfer   0x0000028c
2544 #define Ent_initiator_abort     0x00000860
2545 #define Ent_msg_in      0x00000404
2546 #define Ent_msg_in_restart      0x000003e4
2547 #define Ent_other_in    0x00000374
2548 #define Ent_other_out   0x0000033c
2549 #define Ent_other_transfer      0x000003ac
2550 #define Ent_reject_message      0x000005b4
2551 #define Ent_reselected_check_next       0x000006a4
2552 #define Ent_reselected_ok       0x00000750
2553 #define Ent_respond_message     0x000005ec
2554 #define Ent_select      0x000001fc
2555 #define Ent_select_msgout       0x00000214
2556 #define Ent_target_abort        0x00000840
2557 #define Ent_test_1      0x000007c4
2558 #define Ent_test_2      0x000007d8
2559 #define Ent_test_2_msgout       0x000007f0
2560 #define Ent_wait_reselect       0x00000654
2561 u32 LABELPATCHES[] = {
2562         0x00000008,
2563         0x0000000a,
2564         0x00000013,
2565         0x00000016,
2566         0x0000001f,
2567         0x00000021,
2568         0x0000004f,
2569         0x00000051,
2570         0x0000005b,
2571         0x00000068,
2572         0x0000006f,
2573         0x00000082,
2574         0x00000084,
2575         0x0000008a,
2576         0x0000008e,
2577         0x00000090,
2578         0x00000096,
2579         0x00000098,
2580         0x0000009c,
2581         0x0000009e,
2582         0x000000a0,
2583         0x000000a2,
2584         0x000000a4,
2585         0x000000b1,
2586         0x000000b6,
2587         0x000000ba,
2588         0x000000c7,
2589         0x000000cc,
2590         0x000000d2,
2591         0x000000d8,
2592         0x000000da,
2593         0x000000e0,
2594         0x000000e6,
2595         0x000000e8,
2596         0x000000ee,
2597         0x000000f6,
2598         0x000000f8,
2599         0x00000104,
2600         0x00000106,
2601         0x00000108,
2602         0x0000010a,
2603         0x0000010c,
2604         0x00000112,
2605         0x00000114,
2606         0x00000129,
2607         0x00000142,
2608         0x00000148,
2609         0x00000150,
2610         0x00000152,
2611         0x00000154,
2612         0x0000015a,
2613         0x00000166,
2614         0x00000196,
2615         0x000001a5,
2616         0x000001a8,
2617         0x000001ac,
2618         0x000001b0,
2619         0x000001b4,
2620         0x000001b8,
2621         0x000001cf,
2622         0x000001de,
2623         0x000001e8,
2624         0x000001ea,
2625         0x000001ee,
2626         0x000001f9,
2627         0x000001fb,
2628         0x0000021b,
2629         0x0000021d,
2630         0x0000021f,
2631         0x00000221,
2632         0x00000223,
2633         0x00000225,
2634         0x00000229,
2635         0x0000022d,
2636         0x0000022f,
2637         0x00000233,
2638         0x00000235,
2639         0x00000239,
2640         0x0000023b,
2641 };
2642 
2643 struct {
2644         u32     offset;
2645         void            *address;
2646 } EXTERNAL_PATCHES[] = {
2647 };
2648 
2649 u32 INSTRUCTIONS        = 297;
2650 u32 PATCHES     = 79;
2651 u32 EXTERNAL_PATCHES_LEN        = 0;

/* [previous][next][first][last][top][bottom][index][help] */