Home | History | Annotate | Line # | Download | only in siop
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