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