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 concisely, 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,0x00000980,
 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,0x00000980,
 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 accommodate 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 accommodate 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 containing
 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,0x00000938,
 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,0x00000938,
 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,0x000007a4,
 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_transfer_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,0x00000938,
 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,0x00000938,
 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 discovered, 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 ;       hasn't 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,0x00000980,
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 ; 3.  The bus was already busy since we were selected or reselected
1765 ;       before starting the command.
1766 
1767 wait_reselect_failed:
1768 
1769 
1770 
1771 ; Check selected bit.  
1772     MOVE SIST0 & 0x20 TO SFBR
1773 
1774 at 0x000001db : */      0x74422000,0x00000000,
1775 /*
1776     JUMP selected, IF 0x20
1777 
1778 at 0x000001dd : */      0x800c0020,0x00000764,
1779 /*
1780 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1781     MOVE CTEST2 & 0x40 TO SFBR  
1782 
1783 at 0x000001df : */      0x741a4000,0x00000000,
1784 /*
1785     JUMP schedule, IF 0x40
1786 
1787 at 0x000001e1 : */      0x800c0040,0x00000000,
1788 /*
1789 ; Check connected bit.  
1790 ; FIXME: this needs to change if we support target mode
1791     MOVE ISTAT & 0x08 TO SFBR
1792 
1793 at 0x000001e3 : */      0x74140800,0x00000000,
1794 /*
1795     JUMP reselected, IF 0x08
1796 
1797 at 0x000001e5 : */      0x800c0008,0x0000065c,
1798 /*
1799 ; FIXME : Something bogus happened, and we shouldn't fail silently.
1800 
1801 
1802 
1803     INT int_debug_panic
1804 
1805 at 0x000001e7 : */      0x98080000,0x030b0000,
1806 /*
1807 
1808 
1809 
1810 select_failed:
1811 
1812 
1813 
1814 ; Otherwise, mask the selected and reselected bits off SIST0
1815     MOVE SIST0 & 0x30 TO SFBR
1816 
1817 at 0x000001e9 : */      0x74423000,0x00000000,
1818 /*
1819     JUMP selected, IF 0x20
1820 
1821 at 0x000001eb : */      0x800c0020,0x00000764,
1822 /*
1823     JUMP reselected, IF 0x10 
1824 
1825 at 0x000001ed : */      0x800c0010,0x0000065c,
1826 /*
1827 ; If SIGP is set, the user just gave us another command, and
1828 ; we should restart or return to the scheduler.
1829 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
1830     MOVE CTEST2 & 0x40 TO SFBR  
1831 
1832 at 0x000001ef : */      0x741a4000,0x00000000,
1833 /*
1834     JUMP select, IF 0x40
1835 
1836 at 0x000001f1 : */      0x800c0040,0x000001fc,
1837 /*
1838 ; Check connected bit.  
1839 ; FIXME: this needs to change if we support target mode
1840 ; FIXME: is this really necessary? 
1841     MOVE ISTAT & 0x08 TO SFBR
1842 
1843 at 0x000001f3 : */      0x74140800,0x00000000,
1844 /*
1845     JUMP reselected, IF 0x08
1846 
1847 at 0x000001f5 : */      0x800c0008,0x0000065c,
1848 /*
1849 ; FIXME : Something bogus happened, and we shouldn't fail silently.
1850 
1851 
1852 
1853     INT int_debug_panic
1854 
1855 at 0x000001f7 : */      0x98080000,0x030b0000,
1856 /*
1857 
1858 
1859 ;
1860 ; test_1
1861 ; test_2
1862 ;
1863 ; PURPOSE : run some verification tests on the NCR.  test_1
1864 ;       copies test_src to test_dest and interrupts the host
1865 ;       processor, testing for cache coherency and interrupt
1866 ;       problems in the processes.
1867 ;
1868 ;       test_2 runs a command with offsets relative to the 
1869 ;       DSA on entry, and is useful for miscellaneous experimentation.
1870 ;
1871 
1872 ; Verify that interrupts are working correctly and that we don't 
1873 ; have a cache invalidation problem.
1874 
1875 ABSOLUTE test_src = 0, test_dest = 0
1876 ENTRY test_1
1877 test_1:
1878     MOVE MEMORY 4, test_src, test_dest
1879 
1880 at 0x000001f9 : */      0xc0000004,0x00000000,0x00000000,
1881 /*
1882     INT int_test_1
1883 
1884 at 0x000001fc : */      0x98080000,0x04000000,
1885 /*
1886 
1887 ;
1888 ; Run arbitrary commands, with test code establishing a DSA
1889 ;
1890  
1891 ENTRY test_2
1892 test_2:
1893     CLEAR TARGET
1894 
1895 at 0x000001fe : */      0x60000200,0x00000000,
1896 /*
1897     SELECT ATN FROM 0, test_2_fail
1898 
1899 at 0x00000200 : */      0x43000000,0x00000850,
1900 /*
1901     JUMP test_2_msgout, WHEN MSG_OUT
1902 
1903 at 0x00000202 : */      0x860b0000,0x00000810,
1904 /*
1905 ENTRY test_2_msgout
1906 test_2_msgout:
1907     MOVE FROM 8, WHEN MSG_OUT
1908 
1909 at 0x00000204 : */      0x1e000000,0x00000008,
1910 /*
1911     MOVE FROM 16, WHEN CMD 
1912 
1913 at 0x00000206 : */      0x1a000000,0x00000010,
1914 /*
1915     MOVE FROM 24, WHEN DATA_IN
1916 
1917 at 0x00000208 : */      0x19000000,0x00000018,
1918 /*
1919     MOVE FROM 32, WHEN STATUS
1920 
1921 at 0x0000020a : */      0x1b000000,0x00000020,
1922 /*
1923     MOVE FROM 40, WHEN MSG_IN
1924 
1925 at 0x0000020c : */      0x1f000000,0x00000028,
1926 /*
1927     MOVE SCNTL2 & 0x7f TO SCNTL2
1928 
1929 at 0x0000020e : */      0x7c027f00,0x00000000,
1930 /*
1931     CLEAR ACK
1932 
1933 at 0x00000210 : */      0x60000040,0x00000000,
1934 /*
1935     WAIT DISCONNECT
1936 
1937 at 0x00000212 : */      0x48000000,0x00000000,
1938 /*
1939 test_2_fail:
1940     INT int_test_2
1941 
1942 at 0x00000214 : */      0x98080000,0x04010000,
1943 /*
1944 
1945 ENTRY debug_break
1946 debug_break:
1947     INT int_debug_break
1948 
1949 at 0x00000216 : */      0x98080000,0x03000000,
1950 /*
1951 
1952 ;
1953 ; initiator_abort
1954 ; target_abort
1955 ;
1956 ; PURPOSE : Abort the currently established nexus from with initiator
1957 ;       or target mode.
1958 ;
1959 ;  
1960 
1961 ENTRY target_abort
1962 target_abort:
1963     SET TARGET
1964 
1965 at 0x00000218 : */      0x58000200,0x00000000,
1966 /*
1967     DISCONNECT
1968 
1969 at 0x0000021a : */      0x48000000,0x00000000,
1970 /*
1971     CLEAR TARGET
1972 
1973 at 0x0000021c : */      0x60000200,0x00000000,
1974 /*
1975     JUMP schedule
1976 
1977 at 0x0000021e : */      0x80080000,0x00000000,
1978 /*
1979     
1980 ENTRY initiator_abort
1981 initiator_abort:
1982     SET ATN
1983 
1984 at 0x00000220 : */      0x58000008,0x00000000,
1985 /*
1986 ;
1987 ; The SCSI-I specification says that targets may go into MSG out at 
1988 ; their leisure upon receipt of the ATN single.  On all versions of the 
1989 ; specification, we can't change phases until REQ transitions true->false, 
1990 ; so we need to sink/source one byte of data to allow the transition.
1991 ;
1992 ; For the sake of safety, we'll only source one byte of data in all 
1993 ; cases, but to accommodate the SCSI-I dain bramage, we'll sink an  
1994 ; arbitrary number of bytes.
1995     JUMP spew_cmd, WHEN CMD
1996 
1997 at 0x00000222 : */      0x820b0000,0x000008b8,
1998 /*
1999     JUMP eat_msgin, WHEN MSG_IN
2000 
2001 at 0x00000224 : */      0x870b0000,0x000008c8,
2002 /*
2003     JUMP eat_datain, WHEN DATA_IN
2004 
2005 at 0x00000226 : */      0x810b0000,0x000008f8,
2006 /*
2007     JUMP eat_status, WHEN STATUS
2008 
2009 at 0x00000228 : */      0x830b0000,0x000008e0,
2010 /*
2011     JUMP spew_dataout, WHEN DATA_OUT
2012 
2013 at 0x0000022a : */      0x800b0000,0x00000910,
2014 /*
2015     JUMP sated
2016 
2017 at 0x0000022c : */      0x80080000,0x00000918,
2018 /*
2019 spew_cmd:
2020     MOVE 1, NCR53c7xx_zero, WHEN CMD
2021 
2022 at 0x0000022e : */      0x0a000001,0x00000000,
2023 /*
2024     JUMP sated
2025 
2026 at 0x00000230 : */      0x80080000,0x00000918,
2027 /*
2028 eat_msgin:
2029     MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
2030 
2031 at 0x00000232 : */      0x0f000001,0x00000000,
2032 /*
2033     JUMP eat_msgin, WHEN MSG_IN
2034 
2035 at 0x00000234 : */      0x870b0000,0x000008c8,
2036 /*
2037     JUMP sated
2038 
2039 at 0x00000236 : */      0x80080000,0x00000918,
2040 /*
2041 eat_status:
2042     MOVE 1, NCR53c7xx_sink, WHEN STATUS
2043 
2044 at 0x00000238 : */      0x0b000001,0x00000000,
2045 /*
2046     JUMP eat_status, WHEN STATUS
2047 
2048 at 0x0000023a : */      0x830b0000,0x000008e0,
2049 /*
2050     JUMP sated
2051 
2052 at 0x0000023c : */      0x80080000,0x00000918,
2053 /*
2054 eat_datain:
2055     MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
2056 
2057 at 0x0000023e : */      0x09000001,0x00000000,
2058 /*
2059     JUMP eat_datain, WHEN DATA_IN
2060 
2061 at 0x00000240 : */      0x810b0000,0x000008f8,
2062 /*
2063     JUMP sated
2064 
2065 at 0x00000242 : */      0x80080000,0x00000918,
2066 /*
2067 spew_dataout:
2068     MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
2069 
2070 at 0x00000244 : */      0x08000001,0x00000000,
2071 /*
2072 sated:
2073     MOVE SCNTL2 & 0x7f TO SCNTL2
2074 
2075 at 0x00000246 : */      0x7c027f00,0x00000000,
2076 /*
2077     MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
2078 
2079 at 0x00000248 : */      0x0e000001,0x00000000,
2080 /*
2081     WAIT DISCONNECT
2082 
2083 at 0x0000024a : */      0x48000000,0x00000000,
2084 /*
2085     INT int_norm_aborted
2086 
2087 at 0x0000024c : */      0x98080000,0x02040000,
2088 /*
2089 
2090 ;
2091 ; dsa_to_scratch
2092 ; scratch_to_dsa
2093 ;
2094 ; PURPOSE :
2095 ;       The NCR chips cannot do a move memory instruction with the DSA register 
2096 ;       as the source or destination.  So, we provide a couple of subroutines
2097 ;       that let us switch between the DSA register and scratch register.
2098 ;
2099 ;       Memory moves to/from the DSPS  register also don't work, but we 
2100 ;       don't use them.
2101 ;
2102 ;
2103 
2104  
2105 dsa_to_scratch:
2106     MOVE DSA0 TO SFBR
2107 
2108 at 0x0000024e : */      0x72100000,0x00000000,
2109 /*
2110     MOVE SFBR TO SCRATCH0
2111 
2112 at 0x00000250 : */      0x6a340000,0x00000000,
2113 /*
2114     MOVE DSA1 TO SFBR
2115 
2116 at 0x00000252 : */      0x72110000,0x00000000,
2117 /*
2118     MOVE SFBR TO SCRATCH1
2119 
2120 at 0x00000254 : */      0x6a350000,0x00000000,
2121 /*
2122     MOVE DSA2 TO SFBR
2123 
2124 at 0x00000256 : */      0x72120000,0x00000000,
2125 /*
2126     MOVE SFBR TO SCRATCH2
2127 
2128 at 0x00000258 : */      0x6a360000,0x00000000,
2129 /*
2130     MOVE DSA3 TO SFBR
2131 
2132 at 0x0000025a : */      0x72130000,0x00000000,
2133 /*
2134     MOVE SFBR TO SCRATCH3
2135 
2136 at 0x0000025c : */      0x6a370000,0x00000000,
2137 /*
2138     RETURN
2139 
2140 at 0x0000025e : */      0x90080000,0x00000000,
2141 /*
2142 
2143 scratch_to_dsa:
2144     MOVE SCRATCH0 TO SFBR
2145 
2146 at 0x00000260 : */      0x72340000,0x00000000,
2147 /*
2148     MOVE SFBR TO DSA0
2149 
2150 at 0x00000262 : */      0x6a100000,0x00000000,
2151 /*
2152     MOVE SCRATCH1 TO SFBR
2153 
2154 at 0x00000264 : */      0x72350000,0x00000000,
2155 /*
2156     MOVE SFBR TO DSA1
2157 
2158 at 0x00000266 : */      0x6a110000,0x00000000,
2159 /*
2160     MOVE SCRATCH2 TO SFBR
2161 
2162 at 0x00000268 : */      0x72360000,0x00000000,
2163 /*
2164     MOVE SFBR TO DSA2
2165 
2166 at 0x0000026a : */      0x6a120000,0x00000000,
2167 /*
2168     MOVE SCRATCH3 TO SFBR
2169 
2170 at 0x0000026c : */      0x72370000,0x00000000,
2171 /*
2172     MOVE SFBR TO DSA3
2173 
2174 at 0x0000026e : */      0x6a130000,0x00000000,
2175 /*
2176     RETURN
2177 
2178 at 0x00000270 : */      0x90080000,0x00000000,
2179 };
2180 
2181 #define A_NCR53c7xx_msg_abort   0x00000000
2182 u32 A_NCR53c7xx_msg_abort_used[] = {
2183         0x00000249,
2184 };
2185 
2186 #define A_NCR53c7xx_msg_reject  0x00000000
2187 u32 A_NCR53c7xx_msg_reject_used[] = {
2188         0x00000172,
2189 };
2190 
2191 #define A_NCR53c7xx_sink        0x00000000
2192 u32 A_NCR53c7xx_sink_used[] = {
2193         0x00000233,
2194         0x00000239,
2195         0x0000023f,
2196 };
2197 
2198 #define A_NCR53c7xx_zero        0x00000000
2199 u32 A_NCR53c7xx_zero_used[] = {
2200         0x0000022f,
2201         0x00000245,
2202 };
2203 
2204 #define A_NOP_insn      0x00000000
2205 u32 A_NOP_insn_used[] = {
2206         0x00000010,
2207 };
2208 
2209 #define A_addr_reconnect_dsa_head       0x00000000
2210 u32 A_addr_reconnect_dsa_head_used[] = {
2211         0x000001a7,
2212 };
2213 
2214 #define A_addr_scratch  0x00000000
2215 u32 A_addr_scratch_used[] = {
2216         0x00000004,
2217         0x0000001b,
2218         0x00000046,
2219         0x00000067,
2220         0x00000073,
2221         0x000000b0,
2222         0x000000c6,
2223         0x00000128,
2224         0x00000141,
2225         0x000001a1,
2226         0x000001ce,
2227 };
2228 
2229 #define A_addr_temp     0x00000000
2230 u32 A_addr_temp_used[] = {
2231         0x00000025,
2232         0x00000034,
2233 };
2234 
2235 #define A_dmode_memory_to_memory        0x00000000
2236 u32 A_dmode_memory_to_memory_used[] = {
2237         0x00000005,
2238         0x0000001c,
2239         0x00000027,
2240         0x00000035,
2241         0x00000047,
2242         0x00000069,
2243         0x00000075,
2244         0x000000b2,
2245         0x000000c8,
2246         0x0000012a,
2247         0x00000143,
2248         0x00000199,
2249         0x000001a2,
2250         0x000001d0,
2251 };
2252 
2253 #define A_dmode_memory_to_ncr   0x00000000
2254 u32 A_dmode_memory_to_ncr_used[] = {
2255         0x00000000,
2256         0x00000017,
2257         0x00000030,
2258         0x00000042,
2259         0x0000019d,
2260 };
2261 
2262 #define A_dmode_ncr_to_memory   0x00000000
2263 u32 A_dmode_ncr_to_memory_used[] = {
2264         0x00000022,
2265         0x00000064,
2266         0x00000070,
2267         0x000000ad,
2268         0x000000c3,
2269         0x00000125,
2270         0x0000013e,
2271         0x000001cb,
2272 };
2273 
2274 #define A_dsa_check_reselect    0x00000000
2275 u32 A_dsa_check_reselect_used[] = {
2276         0x000001bd,
2277 };
2278 
2279 #define A_dsa_cmdout    0x00000048
2280 u32 A_dsa_cmdout_used[] = {
2281         0x00000094,
2282 };
2283 
2284 #define A_dsa_cmnd      0x00000038
2285 u32 A_dsa_cmnd_used[] = {
2286 };
2287 
2288 #define A_dsa_datain    0x00000054
2289 u32 A_dsa_datain_used[] = {
2290         0x000000bb,
2291 };
2292 
2293 #define A_dsa_dataout   0x00000050
2294 u32 A_dsa_dataout_used[] = {
2295         0x000000a5,
2296 };
2297 
2298 #define A_dsa_end       0x00000070
2299 u32 A_dsa_end_used[] = {
2300 };
2301 
2302 #define A_dsa_fields_start      0x00000000
2303 u32 A_dsa_fields_start_used[] = {
2304 };
2305 
2306 #define A_dsa_msgin     0x00000058
2307 u32 A_dsa_msgin_used[] = {
2308         0x00000188,
2309 };
2310 
2311 #define A_dsa_msgout    0x00000040
2312 u32 A_dsa_msgout_used[] = {
2313         0x00000086,
2314 };
2315 
2316 #define A_dsa_msgout_other      0x00000068
2317 u32 A_dsa_msgout_other_used[] = {
2318         0x00000180,
2319 };
2320 
2321 #define A_dsa_next      0x00000030
2322 u32 A_dsa_next_used[] = {
2323         0x0000005c,
2324 };
2325 
2326 #define A_dsa_restore_pointers  0x00000000
2327 u32 A_dsa_restore_pointers_used[] = {
2328         0x0000012e,
2329 };
2330 
2331 #define A_dsa_save_data_pointer 0x00000000
2332 u32 A_dsa_save_data_pointer_used[] = {
2333         0x00000115,
2334 };
2335 
2336 #define A_dsa_select    0x0000003c
2337 u32 A_dsa_select_used[] = {
2338         0x00000081,
2339 };
2340 
2341 #define A_dsa_status    0x00000060
2342 u32 A_dsa_status_used[] = {
2343         0x00000184,
2344 };
2345 
2346 #define A_dsa_temp_addr_array_value     0x00000000
2347 u32 A_dsa_temp_addr_array_value_used[] = {
2348 };
2349 
2350 #define A_dsa_temp_addr_dsa_value       0x00000000
2351 u32 A_dsa_temp_addr_dsa_value_used[] = {
2352         0x00000003,
2353 };
2354 
2355 #define A_dsa_temp_addr_new_value       0x00000000
2356 u32 A_dsa_temp_addr_new_value_used[] = {
2357 };
2358 
2359 #define A_dsa_temp_addr_next    0x00000000
2360 u32 A_dsa_temp_addr_next_used[] = {
2361         0x00000015,
2362         0x0000004e,
2363 };
2364 
2365 #define A_dsa_temp_addr_residual        0x00000000
2366 u32 A_dsa_temp_addr_residual_used[] = {
2367         0x0000002a,
2368         0x00000039,
2369 };
2370 
2371 #define A_dsa_temp_addr_saved_pointer   0x00000000
2372 u32 A_dsa_temp_addr_saved_pointer_used[] = {
2373         0x00000026,
2374         0x00000033,
2375 };
2376 
2377 #define A_dsa_temp_addr_saved_residual  0x00000000
2378 u32 A_dsa_temp_addr_saved_residual_used[] = {
2379         0x0000002b,
2380         0x00000038,
2381 };
2382 
2383 #define A_dsa_temp_lun  0x00000000
2384 u32 A_dsa_temp_lun_used[] = {
2385         0x0000004b,
2386 };
2387 
2388 #define A_dsa_temp_next 0x00000000
2389 u32 A_dsa_temp_next_used[] = {
2390         0x0000001a,
2391 };
2392 
2393 #define A_dsa_temp_sync 0x00000000
2394 u32 A_dsa_temp_sync_used[] = {
2395         0x00000053,
2396 };
2397 
2398 #define A_dsa_temp_target       0x00000000
2399 u32 A_dsa_temp_target_used[] = {
2400         0x00000040,
2401 };
2402 
2403 #define A_int_debug_break       0x03000000
2404 u32 A_int_debug_break_used[] = {
2405         0x00000217,
2406 };
2407 
2408 #define A_int_debug_panic       0x030b0000
2409 u32 A_int_debug_panic_used[] = {
2410         0x000001e8,
2411         0x000001f8,
2412 };
2413 
2414 #define A_int_err_check_condition       0x00030000
2415 u32 A_int_err_check_condition_used[] = {
2416         0x00000194,
2417 };
2418 
2419 #define A_int_err_no_phase      0x00040000
2420 u32 A_int_err_no_phase_used[] = {
2421 };
2422 
2423 #define A_int_err_selected      0x00010000
2424 u32 A_int_err_selected_used[] = {
2425         0x000001da,
2426 };
2427 
2428 #define A_int_err_unexpected_phase      0x00000000
2429 u32 A_int_err_unexpected_phase_used[] = {
2430         0x0000008c,
2431         0x00000092,
2432         0x0000009a,
2433         0x000000d0,
2434         0x000000d4,
2435         0x000000d6,
2436         0x000000de,
2437         0x000000e2,
2438         0x000000e4,
2439         0x000000ec,
2440         0x000000f0,
2441         0x000000f2,
2442         0x000000f4,
2443         0x0000014c,
2444 };
2445 
2446 #define A_int_err_unexpected_reselect   0x00020000
2447 u32 A_int_err_unexpected_reselect_used[] = {
2448         0x000001ba,
2449 };
2450 
2451 #define A_int_msg_1     0x01020000
2452 u32 A_int_msg_1_used[] = {
2453         0x0000010e,
2454         0x00000110,
2455 };
2456 
2457 #define A_int_msg_sdtr  0x01010000
2458 u32 A_int_msg_sdtr_used[] = {
2459         0x0000016c,
2460 };
2461 
2462 #define A_int_msg_wdtr  0x01000000
2463 u32 A_int_msg_wdtr_used[] = {
2464         0x00000160,
2465 };
2466 
2467 #define A_int_norm_aborted      0x02040000
2468 u32 A_int_norm_aborted_used[] = {
2469         0x0000024d,
2470 };
2471 
2472 #define A_int_norm_command_complete     0x02020000
2473 u32 A_int_norm_command_complete_used[] = {
2474 };
2475 
2476 #define A_int_norm_disconnected 0x02030000
2477 u32 A_int_norm_disconnected_used[] = {
2478 };
2479 
2480 #define A_int_norm_reselect_complete    0x02010000
2481 u32 A_int_norm_reselect_complete_used[] = {
2482 };
2483 
2484 #define A_int_norm_reset        0x02050000
2485 u32 A_int_norm_reset_used[] = {
2486 };
2487 
2488 #define A_int_norm_select_complete      0x02000000
2489 u32 A_int_norm_select_complete_used[] = {
2490 };
2491 
2492 #define A_int_test_1    0x04000000
2493 u32 A_int_test_1_used[] = {
2494         0x000001fd,
2495 };
2496 
2497 #define A_int_test_2    0x04010000
2498 u32 A_int_test_2_used[] = {
2499         0x00000215,
2500 };
2501 
2502 #define A_int_test_3    0x04020000
2503 u32 A_int_test_3_used[] = {
2504 };
2505 
2506 #define A_msg_buf       0x00000000
2507 u32 A_msg_buf_used[] = {
2508         0x00000102,
2509         0x0000014e,
2510         0x00000158,
2511         0x0000015e,
2512         0x00000164,
2513         0x0000016a,
2514 };
2515 
2516 #define A_reconnect_dsa_head    0x00000000
2517 u32 A_reconnect_dsa_head_used[] = {
2518         0x0000006c,
2519         0x00000074,
2520         0x000001a0,
2521 };
2522 
2523 #define A_reselected_identify   0x00000000
2524 u32 A_reselected_identify_used[] = {
2525         0x00000045,
2526         0x0000019c,
2527 };
2528 
2529 #define A_reselected_tag        0x00000000
2530 u32 A_reselected_tag_used[] = {
2531 };
2532 
2533 #define A_schedule      0x00000000
2534 u32 A_schedule_used[] = {
2535         0x0000007e,
2536         0x00000192,
2537         0x000001e2,
2538         0x0000021f,
2539 };
2540 
2541 #define A_test_dest     0x00000000
2542 u32 A_test_dest_used[] = {
2543         0x000001fb,
2544 };
2545 
2546 #define A_test_src      0x00000000
2547 u32 A_test_src_used[] = {
2548         0x000001fa,
2549 };
2550 
2551 #define Ent_accept_message      0x000005d4
2552 #define Ent_cmdout_cmdout       0x0000024c
2553 #define Ent_command_complete    0x0000060c
2554 #define Ent_command_complete_msgin      0x0000061c
2555 #define Ent_data_transfer       0x00000254
2556 #define Ent_datain_to_jump      0x00000328
2557 #define Ent_debug_break 0x00000858
2558 #define Ent_dsa_code_begin      0x00000000
2559 #define Ent_dsa_code_check_reselect     0x000000f8
2560 #define Ent_dsa_code_fix_jump   0x0000003c
2561 #define Ent_dsa_code_restore_pointers   0x000000c0
2562 #define Ent_dsa_code_save_data_pointer  0x00000088
2563 #define Ent_dsa_code_template   0x00000000
2564 #define Ent_dsa_code_template_end       0x00000168
2565 #define Ent_dsa_schedule        0x00000168
2566 #define Ent_dsa_zero    0x00000168
2567 #define Ent_end_data_transfer   0x0000028c
2568 #define Ent_initiator_abort     0x00000880
2569 #define Ent_msg_in      0x00000404
2570 #define Ent_msg_in_restart      0x000003e4
2571 #define Ent_other_in    0x00000374
2572 #define Ent_other_out   0x0000033c
2573 #define Ent_other_transfer      0x000003ac
2574 #define Ent_reject_message      0x000005b4
2575 #define Ent_reselected_check_next       0x000006a4
2576 #define Ent_reselected_ok       0x00000750
2577 #define Ent_respond_message     0x000005ec
2578 #define Ent_select      0x000001fc
2579 #define Ent_select_msgout       0x00000214
2580 #define Ent_target_abort        0x00000860
2581 #define Ent_test_1      0x000007e4
2582 #define Ent_test_2      0x000007f8
2583 #define Ent_test_2_msgout       0x00000810
2584 #define Ent_wait_reselect       0x00000654
2585 u32 LABELPATCHES[] = {
2586         0x00000008,
2587         0x0000000a,
2588         0x00000013,
2589         0x00000016,
2590         0x0000001f,
2591         0x00000021,
2592         0x0000004f,
2593         0x00000051,
2594         0x0000005b,
2595         0x00000068,
2596         0x0000006f,
2597         0x00000082,
2598         0x00000084,
2599         0x0000008a,
2600         0x0000008e,
2601         0x00000090,
2602         0x00000096,
2603         0x00000098,
2604         0x0000009c,
2605         0x0000009e,
2606         0x000000a0,
2607         0x000000a2,
2608         0x000000a4,
2609         0x000000b1,
2610         0x000000b6,
2611         0x000000ba,
2612         0x000000c7,
2613         0x000000cc,
2614         0x000000d2,
2615         0x000000d8,
2616         0x000000da,
2617         0x000000e0,
2618         0x000000e6,
2619         0x000000e8,
2620         0x000000ee,
2621         0x000000f6,
2622         0x000000f8,
2623         0x00000104,
2624         0x00000106,
2625         0x00000108,
2626         0x0000010a,
2627         0x0000010c,
2628         0x00000112,
2629         0x00000114,
2630         0x00000129,
2631         0x00000142,
2632         0x00000148,
2633         0x00000150,
2634         0x00000152,
2635         0x00000154,
2636         0x0000015a,
2637         0x00000166,
2638         0x00000196,
2639         0x000001a5,
2640         0x000001a8,
2641         0x000001ac,
2642         0x000001b0,
2643         0x000001b4,
2644         0x000001b8,
2645         0x000001cf,
2646         0x000001de,
2647         0x000001e6,
2648         0x000001ec,
2649         0x000001ee,
2650         0x000001f2,
2651         0x000001f6,
2652         0x00000201,
2653         0x00000203,
2654         0x00000223,
2655         0x00000225,
2656         0x00000227,
2657         0x00000229,
2658         0x0000022b,
2659         0x0000022d,
2660         0x00000231,
2661         0x00000235,
2662         0x00000237,
2663         0x0000023b,
2664         0x0000023d,
2665         0x00000241,
2666         0x00000243,
2667 };
2668 
2669 struct {
2670         u32     offset;
2671         void            *address;
2672 } EXTERNAL_PATCHES[] = {
2673 };
2674 
2675 u32 INSTRUCTIONS        = 301;
2676 u32 PATCHES     = 81;
2677 u32 EXTERNAL_PATCHES_LEN        = 0;

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