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