siop.ss revision 1.2 1 ARCH 720
2
3 ; offsets in sym_xfer
4 ABSOLUTE t_id = 20;
5 ABSOLUTE t_msg_in = 28;
6 ABSOLUTE t_ext_msg_in = 36;
7 ABSOLUTE t_ext_msg_data = 44;
8 ABSOLUTE t_ext_msg_tag = 52;
9 ABSOLUTE t_msg_out = 60;
10 ABSOLUTE t_cmd = 68;
11 ABSOLUTE t_status = 76;
12 ABSOLUTE t_data = 84;
13
14 ;; interrupt codes
15 ABSOLUTE int_done = 0xff00;
16 ABSOLUTE int_msgin = 0xff01;
17 ABSOLUTE int_extmsgin = 0xff02;
18 ABSOLUTE int_extmsgdata = 0xff03;
19 ABSOLUTE int_resel = 0xff04;
20 ABSOLUTE int_reseltag = 0xff05;
21 ABSOLUTE int_resfail = 0xff06;
22 ABSOLUTE int_disc = 0xff07;
23 ABSOLUTE int_err = 0xffff;
24
25 ; flags for scratcha0
26 ABSOLUTE flag_sdp = 0x01 ; got save data pointer
27
28 ENTRY waitphase;
29 ENTRY send_msgout;
30 ENTRY msgout;
31 ENTRY msgin;
32 ENTRY msgin_ack;
33 ENTRY dataout;
34 ENTRY datain;
35 ENTRY cmdout;
36 ENTRY status;
37 ENTRY disconnect;
38 ENTRY reselect;
39 ENTRY selected;
40 ENTRY get_extmsgdata;
41 ENTRY sheduler;
42 ENTRY slot;
43 ENTRY idsa0;
44 ENTRY idsa1;
45 ENTRY idsa2;
46 ENTRY idsa3;
47 ENTRY slotdata;
48 ENTRY nextslot;
49 ENTRY endslot;
50
51 EXTERN slot_nextp;
52 EXTERN slot_shed_addrsrc;
53 EXTERN slot_abs_reselect;
54 EXTERN slot_abs_selected;
55
56 EXTERN endslot_abs_reselect;
57
58 PROC siop_script:
59
60 selected:
61 ; starting a new session, init 'local variables'
62 MOVE 0 to SCRATCHA0 ; flags
63 MOVE 0 to SCRATCHA1 ; DSA offset (for S/G save data pointer)
64 waitphase:
65 JUMP REL(msgout), WHEN MSG_OUT;
66 JUMP REL(msgin), WHEN MSG_IN;
67 JUMP REL(dataout), WHEN DATA_OUT;
68 JUMP REL(datain), WHEN DATA_IN;
69 JUMP REL(cmdout), WHEN CMD;
70 JUMP REL(status), WHEN STATUS;
71 err:
72 INT int_err;
73
74 reselect:
75 WAIT RESELECT REL(reselect_fail)
76 MOVE SSID & 0x8f to SFBR
77 MOVE SFBR to SCRATCHA0 ; save reselect ID
78 INT int_err, WHEN NOT MSG_IN;
79 MOVE FROM t_msg_in, WHEN MSG_IN;
80 CLEAR ACK;
81 INT int_resel;
82
83 reselect_fail:
84 ; check that host asserted SIGP, this'll clear SIGP in ISTAT
85 MOVE CTEST2 & 0x40 TO SFBR;
86 INT int_resfail, IF 0x00;
87 JUMP REL(sheduler);
88
89 msgin:
90 CLEAR ATN
91 MOVE FROM t_msg_in, WHEN MSG_IN;
92 JUMP REL(handle_dis), IF 0x04 ; disconnect message
93 JUMP REL(handle_cmpl), IF 0x00 ; command complete message
94 JUMP REL(handle_sdp), IF 0x02 ; save data pointer message
95 JUMP REL(handle_extin), IF 0x01 ; extended message
96 INT int_msgin;
97 msgin_ack:
98 CLEAR ACK;
99 JUMP REL(waitphase);
100
101 ; entry point for msgout after a msgin or status phase
102 send_msgout:
103 SET ATN;
104 CLEAR ACK;
105 msgout:
106 MOVE FROM t_msg_out, WHEN MSG_OUT;
107 CLEAR ATN;
108 JUMP REL(waitphase);
109 cmdout:
110 MOVE FROM t_cmd, WHEN CMD;
111 JUMP REL(waitphase);
112 status:
113 MOVE FROM t_status, WHEN STATUS;
114 JUMP REL(waitphase);
115 datain:
116 CALL REL(savedsa);
117 datain_loop:
118 MOVE FROM t_data, WHEN DATA_IN;
119 MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
120 MOVE DSA0 + 8 to DSA0;
121 MOVE DSA1 + 0 to DSA1 WITH CARRY;
122 MOVE DSA2 + 0 to DSA2 WITH CARRY;
123 MOVE DSA3 + 0 to DSA3 WITH CARRY;
124 JUMP REL(datain_loop), WHEN DATA_IN;
125 CALL REL(restoredsa);
126 JUMP REL(waitphase);
127
128 dataout:
129 CALL REL(savedsa);
130 dataout_loop:
131 MOVE FROM t_data, WHEN DATA_OUT;
132 MOVE SCRATCHA1 + 1 TO SCRATCHA1 ; adjust offset
133 MOVE DSA0 + 8 to DSA0;
134 MOVE DSA1 + 0 to DSA1 WITH CARRY;
135 MOVE DSA2 + 0 to DSA2 WITH CARRY;
136 MOVE DSA3 + 0 to DSA3 WITH CARRY;
137 JUMP REL(dataout_loop), WHEN DATA_OUT;
138 CALL REL(restoredsa);
139 JUMP REL(waitphase);
140
141 savedsa:
142 MOVE DSA0 to SFBR;
143 MOVE SFBR to SCRATCHB0;
144 MOVE DSA1 to SFBR;
145 MOVE SFBR to SCRATCHB1;
146 MOVE DSA2 to SFBR;
147 MOVE SFBR to SCRATCHB2;
148 MOVE DSA3 to SFBR;
149 MOVE SFBR to SCRATCHB3;
150 RETURN;
151
152 restoredsa:
153 MOVE SCRATCHB0 TO SFBR;
154 MOVE SFBR TO DSA0;
155 MOVE SCRATCHB1 TO SFBR;
156 MOVE SFBR TO DSA1;
157 MOVE SCRATCHB2 TO SFBR;
158 MOVE SFBR TO DSA2;
159 MOVE SCRATCHB3 TO SFBR;
160 MOVE SFBR TO DSA3;
161 RETURN;
162
163 disconnect:
164 MOVE SCNTL2 & 0x7f TO SCNTL2;
165 CLEAR ATN;
166 CLEAR ACK;
167 WAIT DISCONNECT;
168 RETURN;
169
170 handle_dis:
171 CALL REL(disconnect);
172 ; if we didn't get sdp, or if offset is 0, no need to interrupt
173 MOVE SCRATCHA0 & flag_sdp TO SFBR;
174 JUMP REL(sheduler), if 0x00;
175 MOVE SCRATCHA1 TO SFBR;
176 JUMP REL(sheduler), if 0x00;
177 ; Ok, we need to save data pointers
178 INT int_disc;
179
180 handle_cmpl:
181 CALL REL(disconnect);
182 INT int_done;
183 handle_sdp:
184 CLEAR ACK;
185 MOVE SCRATCHA0 | flag_sdp TO SCRATCHA0;
186 JUMP REL(msgin) ; should get a disconnect message now
187
188 handle_extin:
189 CLEAR ACK;
190 INT int_err, IF NOT MSG_IN;
191 MOVE FROM t_ext_msg_in, WHEN MSG_IN;
192 INT int_extmsgin; /* let host fill in t_ext_msg_data */
193 get_extmsgdata:
194 CLEAR ACK;
195 INT int_err, IF NOT MSG_IN;
196 MOVE FROM t_ext_msg_data, WHEN MSG_IN;
197 INT int_extmsgdata;
198
199 sheduler:
200 NOP; /* will be changed by the slot scripts */
201
202 ; script used for the sheduler: when a slot is free the JUMP points to
203 ; the next slot so that instructions for this slot are not run.
204 ; once the CPU has set up the slot variables (DSA address) it changes
205 ; the JUMP address to 0 (so that it'll jump to the next instruction) and
206 ; this command will be processed next time the sheduler is executed.
207 ; When the target has been successfully selected the script changes the jump
208 ; addr back to the next slot, so that it's ignored the next time.
209 ;
210
211 PROC slot_script:
212 slot:
213 JUMP REL(nextslot);
214 idsa0:
215 MOVE 0x00 to dsa0;
216 idsa1:
217 MOVE 0x01 to dsa1;
218 idsa2:
219 MOVE 0x02 to dsa2;
220 idsa3:
221 MOVE 0x03 to dsa3;
222 SELECT ATN FROM t_id, slot_abs_reselect;
223 MOVE MEMORY 4, slot_shed_addrsrc, slot_nextp;
224 JUMP slot_abs_selected;
225 slotdata:
226 NOP; slot variables: dsa & jumppatchp
227 nextslot: NOP; /* will be changed to the next slot entry
228
229 PROC endslot_script:
230 JUMP endslot_abs_reselect;
231