;************************************************************************* ; demo10.ss ; ARCH 710 ; ABSOLUTE declarations ABSOLUTE SCSI_id = 0x02 ABSOLUTE error_not_cmd_phase = 0x01 ABSOLUTE error_not_data_in_phase = 0x02 ABSOLUTE error_not_data_out_phase = 0x03 ABSOLUTE error_not_msg_in_phase = 0x04 ABSOLUTE error_not_msg_out_phase = 0x05 ABSOLUTE error_not_status_phase = 0x06 ABSOLUTE error_unexpected_phase = 0x07 ABSOLUTE error_jump_not_taken = 0x10 ABSOLUTE error_not_cmd_complete = 0x20 ABSOLUTE error_not_extended_msg = 0x21 ABSOLUTE end_of_SCSI_SCRIPT = 0x0A ABSOLUTE reselected_interrupt = 0x80 ABSOLUTE selected_interrupt = 0x81 ABSOLUTE synch_xfer_interrupt = 0x888 RELATIVE rel_data1 \ identify_msg_buf = { 0x80 }, \ ;identify_msg_buf=1 byte synch_msgo_buf = 5{??}, \ ;synch_msgo_buf=5 bytes synch_msgi_buf = 5{??}, \ ;synch_msgi_buf=5 bytes dummy_buf = 9{??}, \ disconnect_msg_in_buf = 2{??} ;disconnect_msg_in_buf=2 bytes TABLE table_indirect \ reselect_id = ID{ 0x00, 0x07, 0x00, 0x00 }\ stat_buf = ??, \ ;stat_buf=1 byte msg_in_buf = ??, \ ;msg_in_buf=1 byte bogus_buf = 7{??}, \ data_buf = 512{??}, \ W_cmd_buf = 6{??}, \ ;W_cmd_buf=6 bytes select_id = ID{ 0x00, 0x04, 0x40, 0x00 } ; select id EXTERN cmd_buf = 12{??} ;cmd_buf=12 bytes EXTERN read_cap_buf = 8{??} ;read_cap_buf=8 bytes EXTERN inquiry_buf = 36{??} ;inquiry_buf=36 bytes EXTERN request_sense_buf= 18{??} ;request_sense_buf=18 bytes EXTERN unused_buf = 7{??} EXTERN write_cmd = { 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00 } EXTERN read_cmd = { 0x08, 0x00, 0x00, 0x00, 0x01, 0x00 } EXTERN tur_cmd = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } EXTERN inquiry_cmd = { 0x12, 0x00, 0x00, 0x00, 0x24, 0x00 } EXTERN read_cap_cmd = { 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00 } ; additional relative data area for testing RELATIVE rel_data2 \ r1 = 3{??}, \ r2 = { 0x02, 0x04, 0x06, 0x08 }, \ r3 = { 0xEE } ;*********************************************************************** ; ENTRY declarations ENTRY test_unit_ready ENTRY read_capacity ENTRY inquiry ENTRY request_sense ENTRY initiator_synchronous ENTRY initiator_read ENTRY initiator_write ENTRY loop_write_read ENTRY loop_read_select ENTRY target_script ENTRY target_reselect ENTRY init_write_read_disconnect ENTRY i_d_write_reconnect ENTRY i_d_read_reconnect ENTRY initiator_reselect ENTRY init_read_byte_count ENTRY init_write_byte_count ENTRY init_loop_read_byte_count ENTRY init_loop_write_byte_count ENTRY to_decisions ;*********************************************************************** ; TEST UNIT READY SCRIPT test_unit_ready: select ATN from select_id, alt_jump_reselected ;select the target jump tur_decisions tur_msg_out: move 1, identify_msg_buf, when MSG_OUT ;move the message byte in tur_command: clear ATN ;clear ATN when drive does ;not support disconnect int error_not_cmd_phase, when not CMD ; check for command phase move memory 6, tur_cmd, cmd_buf ; move the tur command into the ; cmd_buf move 6, cmd_buf, when CMD ; move the command bytes int error_not_status_phase, when not STATUS ;check for status phase move from stat_buf, when STATUS ;move the status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move from msg_in_buf, when MSG_IN ;move the message in int error_not_cmd_complete, if not 00 ;interrupt if not command ;complete message clear ACK ;accept the message byte wait disconnect end_of_SCSI_SCRIPT ;wait for bus free int end_of_SCSI_SCRIPT ;interrupt end of SCSI I/O tur_decisions: jump tur_msg_out, when MSG_OUT ; move identify message jump tur_command, if CMD ;jump to command when not ;message out phase, drive may ;not support select w/ ATN jump init_synch_msg_in_phase, if MSG_IN ;some drives immediately try ;synchronous negotiation int error_unexpected_phase ; end Test Unit Ready SCRIPT ;*********************************************************************** ;READ CAPACITY SCRIPT PROC read_capacity: select ATN SCSI_id, alt_jump_reselected ;select the target jump read_cap_cmd_phase, when not MSG_OUT ;jump to cmd when not msg ;out phase, drive may not ;support select w/atn move 1, identify_msg_buf, when MSG_OUT ;move the msg byte into the ;identify_msg_buf read_cap_cmd_phase: clear ATN ;clear atn when drive does ;not support select w/atn int error_not_cmd_phase, when not CMD ;issue interrupt when not ;cmd phase move memory 10, read_cap_cmd, cmd_buf ;load the command buffer with ;read capacity command move 10, cmd_buf, when CMD ;move the read capacity cmd int error_not_data_in_phase, when not DATA_IN ;check for data in phase move 8, read_cap_buf, when DATA_IN ;move data bytes: logical ;block address byte 0-3 ;block length in bytes ;byte 4-7 int error_not_status_phase, when not STATUS ;check for status phase move from stat_buf, when STATUS ;move status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move from msg_in_buf, when MSG_IN ;move the cmd complete msg in int error_not_cmd_complete, if not 00 ;interrupt if not a cmd compl. ;message clear ACK ;accept the msg byte wait disconnect end_of_SCSI_SCRIPT ;wait for bus free ;interrupt int end_of_SCSI_SCRIPT ;interrupt end SCSI I/O ; end Read Capacity SCRIPT ;*********************************************************************** ; INQUIRY SCRIPT inquiry: select ATN from select_id, alt_jump_reselected ;select the target jump inq_command_phase, when not MSG_OUT ;jump to command when ;not message out phase, ;drive may not support ;select w/ ATN int error_not_msg_out_phase, when not MSG_OUT ;check for message out move 1, identify_msg_buf, when MSG_OUT ;move command byte in inq_command_phase: clear ATN int error_not_cmd_phase, when not CMD ;check for command phase move memory 6, inquiry_cmd, cmd_buf ;load the inquiry command into ;cmd_buf move 6, cmd_buf, when CMD ;move the command bytes out int error_not_data_in_phase, when not DATA_IN ;check for data in phase move 36, inquiry_buf, when DATA_IN ;move inquiry bytes int error_not_status_phase, when not STATUS ;check for status phase move from stat_buf, when STATUS ;move the status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move from msg_in_buf, when MSG_IN ;move command complete message in int error_not_cmd_complete, if not 00 ;interrupt if not a command complete clear ACK ;accept the message byte wait disconnect end_of_SCSI_SCRIPT ;wait for bus free int end_of_SCSI_SCRIPT ;interrupt end SCSI I/O ; end Inquiry SCRIPT ;*********************************************************************** ; REQUEST SENSE SCRIPT PROC request_sense: select ATN SCSI_id, alt_jump_reselected ;select the target jump req_sense_command_phase, when not MSG_OUT ;jump to command when ;not message out phase ;drive may not ;support select w/ ATN int error_not_msg_out_phase, when not MSG_OUT ;check for message out phase next move 1, identify_msg_buf, when MSG_OUT ;move command byte in req_sense_command_phase: clear ATN int error_not_cmd_phase, when not CMD ;check for command phase move 6, cmd_buf, when CMD ;move the command bytes out int error_not_data_in_phase, when not DATA_IN ;check for data in phase move 18, request_sense_buf, when DATA_IN ;move sense bytes int error_not_status_phase, when not STATUS ;check for status phase next move from stat_buf, when STATUS ;move the status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move from msg_in_buf, when MSG_IN ;move message in int error_not_cmd_complete, if not 00 ;interrupt if not command ;complete message clear ACK ;accept the message byte wait disconnect end_of_SCSI_SCRIPT ;wait for bus free int end_of_SCSI_SCRIPT ;interrupt end of SCSI I/O ; end Request Sense SCRIPT ;*********************************************************************** ; INITIATOR SYNCHRONOUS NEGOTIATION SCRIPT initiator_synchronous: select ATN SCSI_id, alt_jump_reselected ;select the target jump init_synch_id_msg, when MSG_OUT clear ATN jump to_decisions init_synch_id_msg: move 1, identify_msg_buf, when MSG_OUT ;move the message byte in set ATN ;set ATN for synch negotiation jump to_decisions init_synch_cmd_phase: int error_not_cmd_phase, if not CMD ;check for command phase move 6, cmd_buf, when CMD ;move the command bytes out jump to_decisions; init_synch_msg_out_phase: int error_not_msg_out_phase, if not MSG_OUT ;check for message out move 1, synch_msgo_buf, when MSG_OUT ;move synch negotiation message jump init_synch_msg_in_phase, when MSG_IN set ATN move 4, synch_msgo_buf+1, when MSG_OUT ;move synch negotiation message jump to_decisions init_synch_msg_in_phase: int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move 1, synch_msgi_buf, when MSG_IN ;move 1st message byte in clear ACK ;accept the message byte jump to_decisions, if 7 ;asynch if message reject ;take jump to_data_in_phase ;to properly check phase ;with when instead of ;if at data_in int error_not_extended_msg, if not 1 ;interrupt if not extended message move 4, synch_msgi_buf+1, when MSG_IN ;move synch negotiation message in clear ACK ;accept the message byte int synch_xfer_interrupt ;interrupt to initialize ;SIOP for synchronous transfer ;(SXFER register) to_decisions: jump init_synch_msg_out_phase, when MSG_OUT jump init_read_data_in_phase, if DATA_IN jump init_write_data_out_phase, if DATA_OUT jump init_read_status_phase, if STATUS jump init_synch_cmd_phase, if CMD jump init_synch_msg_in_phase, if MSG_IN int error_unexpected_phase ; end Initiator Synchronous Negotiation SCRIPT ;*********************************************************************** ; INITIATOR READ SCRIPT initiator_read: select ATN SCSI_id, alt_jump_reselected ;select the target jump init_read_cmd_phase, when not MSG_OUT ;jump to command when not ;message out phase, ;drive may not ;support select w/ ATN int error_not_msg_out_phase, when not MSG_OUT ;check for message out phase next move 1, identify_msg_buf, when MSG_OUT ;move the message byte in init_read_cmd_phase: int error_not_cmd_phase, when not CMD ;check for command phase clear ATN ;clear ATN when drive does ;not support select w/ ATN move memory 6, read_cmd, cmd_buf ;move the read command into the ;cmd_buf move 6, cmd_buf, when CMD ;move the command bytes out init_read_data_in_phase: int error_not_data_in_phase, when not DATA_IN ;check for data in phase init_read_byte_count: move from data_buf, when DATA_IN ;move data bytes init_read_status_phase: int error_not_status_phase, when not STATUS ;check for status phase next move from stat_buf, when STATUS ;move the status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in move from msg_in_buf, when MSG_IN ;move the message in int error_not_cmd_complete, if not 00 ;interrupt if not command complete message clear ACK ;accept the message byte wait disconnect end_of_SCSI_SCRIPT ;wait for bus free int end_of_SCSI_SCRIPT ;interrupt end of SCSI I/O ; end of Initiator Read SCRIPT ;*********************************************************************** ; INITIATOR WRITE SCRIPT initiator_write: select ATN SCSI_id, alt_jump_reselected ;select the target jump init_write_command_phase, when not MSG_OUT ;jump to command when ;not message out phase ;drive may not ;support select w/ ATN int error_not_msg_out_phase, when not MSG_OUT ;check for message out move 1, identify_msg_buf, when MSG_OUT ;move the message byte in init_write_command_phase: int error_not_cmd_phase, when not CMD ;check for command phase next clear ATN ;clear ATN when drive does not ;support select w/ ATN move memory 6, write_cmd, cmd_buf ;move the write command into the ;cmd_buf move 6, cmd_buf, when CMD ;move the command bytes out init_write_data_out_phase: int error_not_data_out_phase, when not DATA_OUT ;interrupt if not data out init_write_byte_count: move from data_buf, when DATA_OUT ;move data bytes int error_not_status_phase, when not STATUS ;check for status phase next move from stat_buf, when STATUS ;move the status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move from msg_in_buf, when MSG_IN ;move the message in int error_not_cmd_complete, if not 00 ;interrupt if not command complete clear ACK ;accept the message byte wait disconnect end_of_SCSI_SCRIPT ;wait for bus free int end_of_SCSI_SCRIPT ;interrupt end SCSI I/O ; end Initiator Write SCRIPT ;*********************************************************************** ; INITIATOR LOOP WRITE/READ SCRIPT ; WRITE loop_write_read: select ATN SCSI_id, alt_jump_reselected ;select the target jump w_r_command_phase, when not MSG_OUT ;jump to command when not ;message out phase, drive may ;not support select w/ ATN int error_not_msg_out_phase, when not MSG_OUT ;check for message out phase next move 1, identify_msg_buf, when MSG_OUT ;move the message byte in w_r_command_phase: int error_not_cmd_phase, when not CMD ;check for command phase next clear ATN ;clear ATN when drive does not ;support select w/ ATN move from W_cmd_buf, when CMD ;move the command bytes out int error_not_data_out_phase, when not DATA_OUT ;interrupt if not data out init_loop_write_byte_count: move from data_buf, when DATA_OUT ;move data bytes ; used to test scatter gather - seperate data buffers ; move 512, data_buf0, when DATA_OUT ; move 512, data_buf1, when DATA_OUT ; move data bytes ; move 512, data_buf2, when DATA_OUT ; move data bytes ; move 512, data_buf3, when DATA_OUT ; move data bytes int error_not_status_phase, when not STATUS ;check for status phase next move from stat_buf, when STATUS ;move the status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move from msg_in_buf, when MSG_IN ;move the command complete message in int error_not_cmd_complete, if not 00 ;interrupt if not command complete message clear ACK ;accept the message byte wait disconnect end_of_SCSI_SCRIPT ;wait for the bus free ; READ loop_read_select: select ATN SCSI_id, alt_jump_reselected ;select the target jump r_w_command_phase, when not MSG_OUT ;jump to command when not ;message out phase, drive may not ;support select w/ ATN int error_not_msg_out_phase, when not MSG_OUT ;check for message out phase next move 1, identify_msg_buf, when MSG_OUT ;move the message byte in r_w_command_phase: int error_not_cmd_phase, when not CMD ;check for command phase next clear ATN ;clear ATN when drive does not ;support select w/ ATN move 6, cmd_buf, when CMD ;move the command bytes out int error_not_data_in_phase, when not DATA_IN ;interrupt if not data in init_loop_read_byte_count: move from data_buf, when DATA_IN ;move data bytes ; used to test scatter gather - seperate data buffers ; move 512, data_buf0, when DATA_IN ; move 512, data_buf1, when DATA_IN ; move data bytes ; move 512, data_buf2, when DATA_IN ; move data bytes ; move 512, data_buf3, when DATA_IN ; move data bytes int error_not_status_phase, when not STATUS ;check for status phase move from stat_buf, when STATUS ;move the status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move from msg_in_buf, when MSG_IN ;move the command complete message in int error_not_cmd_complete, if not 00 ;interrupt if not a command complete message clear ACK ;accept the message byte wait disconnect end_of_SCSI_SCRIPT ;wait for the bus free jump loop_write_read ;jump to start of loop read/write ; end Initiator loop read write SCRIPT ;*********************************************************************** ; TARGET SCRIPT ; accepts Test Unit Ready, Read, Write target_script: wait select alt_jump_selected ;wait for selection jump t_no_msg_out, if not ATN ;check for atn next move 1, identify_msg_buf, with MSG_OUT ;move the message byte in jump t_allow_disconnect, if 0xc0 ;allow disconnects t_no_msg_out: move 0, cmd_buf, with CMD ;move the command bytes out next jump t_status, if 0x00 ;test unit ready command jump t_read, if 0x08 ;read command jump t_write, if 0x0a ;write command jump t_disconnect ;else disconnect t_read: move from data_buf, with DATA_IN ;read operation if here jump t_status t_write: move from data_buf, with DATA_OUT ;write operation if here t_status: move from stat_buf, with STATUS ;move the status byte in move from msg_in_buf, with MSG_IN ;move the command complete message in t_disconnect: disconnect jump target_script ;loop back for another round of targeting t_allow_disconnect: move 0, cmd_buf, with CMD ;move the command bytes out next move 1, disconnect_msg_in_buf, with MSG_IN ;move save data pointers ; & disconnect message disconnect ;*********************************************************************** ; TARGET RESELECT SCRIPT target_reselect: reselect 7, alt_jump_selected move 1, identify_msg_buf, with MSG_IN ;move the identify message byte ; to the initiator for implied ; restore data pointers jump t_write, if 0x0A ;write disconnect jump t_read, if 0x08 ;read disconnect int 0xBB ;********************************************************************** ; autoswitching experiment select while initiator WAIT RESELECT autoswitch: clear TARGET select ATN SCSI_id, alt_jump_selected ; jump switch_to_init_test int 0x77 ;*********************************************************************** ;*********************************************************************** ; INITIATOR WRITE SCRIPT w/ DISCONNECT init_write_read_disconnect: select ATN SCSI_id, initiator_reselect ;select the target jump i_d_cmd, when not MSG_OUT ;check for message out phase move 1, identify_msg_buf, when MSG_OUT ;move the message byte in i_d_cmd: int error_not_cmd_phase, when not CMD ;check for command phase next move 6, cmd_buf, when CMD ;move the command bytes out next jump check_for_disconnect, when MSG_IN ;check for disconnect jump i_d_write_reconnect, if DATA_OUT jump i_d_read_reconnect, if DATA_IN int 0x10 i_d_read_reconnect: move from data_buf, when DATA_IN ;move data jump i_d_status, when STATUS jump check_for_disconnect, if MSG_IN int 0x20 ;int on disconnect after data ;transfer i_d_write_reconnect: move from data_buf, when DATA_OUT ;move data bytes jump i_d_status, when STATUS jump check_for_disconnect, if MSG_IN int 0x30 ;int on disconnect after data ;transfer i_d_status: int error_not_status_phase, when not STATUS ;check for status phase move from stat_buf, when STATUS ;move the status byte in int error_not_msg_in_phase, when not MSG_IN ;check for message in phase move from msg_in_buf, when MSG_IN ;move the command complete message in int error_not_cmd_complete, if not 00 ;interrupt if not a command complete clear ACK ;accept the message byte wait disconnect end_of_SCSI_SCRIPT ;wait for the bus free int end_of_SCSI_SCRIPT ;interrupt end SCSI I/O check_for_disconnect: int 0x40, if not MSG_IN ;interrupt when not MSG_IN move 1, disconnect_msg_in_buf, when MSG_IN ;move 1st message in clear ACK ;accept the message byte jump initiator_disconnect, if 0x04 ;disconnect if disconnect message int error_not_msg_in_phase, when not MSG_IN move 1, disconnect_msg_in_buf+1, when MSG_IN ;move 2nd message in clear ACK ;accept the message byte jump initiator_disconnect, if 0x04 ;disconnect if disconnect message initiator_disconnect: wait disconnect end_of_SCSI_SCRIPT ;wait for the bus free initiator_reselect: wait reselect init_select_test ;wait for reselect jump i_d_status, when STATUS jump i_d_read_reconnect, if DATA_IN jump i_d_write_reconnect, if DATA_OUT int error_not_msg_in_phase, if not MSG_IN ;check for message in phase msg_in_reconnect: move from msg_in_buf, when MSG_IN ;move the message in clear ACK ;accept the message byte jump msg_in_reconnect, when MSG_IN jump i_d_status, if STATUS jump i_d_read_reconnect, if DATA_IN jump i_d_write_reconnect, if DATA_OUT int error_unexpected_phase ; end Initiator Write SCRIPT ;********************************************************* ;interrupt if it took the alternate jump alt_jump_reselected: int reselected_interrupt alt_jump_selected: int selected_interrupt ; ******** autoswitch test ****** init_select_test: int 0x82 ; jump target_script ;end of code