;*********************************************************************** ; 53C710 MULTI THREAD EXAMPLE ;*********************************************************************** ; ABSOLUTE declarations ABSOLUTE SCSI_id = 0 ABSOLUTE MATCH_SCSI_ID = 0x81 ; Messages ABSOLUTE CMD_COMPLETE_ = 0x00 ABSOLUTE EXTEND_MSG_ = 0x01 ABSOLUTE SAVE_DATAPTR_ = 0x02 ABSOLUTE DISCONNECT_ = 0x04 ABSOLUTE MSG_REJECT_ = 0x07 ; Interrupt codes 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 io_complete = 0x0A ABSOLUTE setup_SXFER = 0x888 ABSOLUTE reselect_id_error = 0x999 ABSOLUTE select_error = 0xfff ;*********************************************************************** ; TABLE declarations for Table Indirect offsets in bytes Table Table_Indirect \ SCSI_ID=ID{0x00,0x00,0x00,0x00} \ identify_msg_buf = {0xc0} \ synch_msgi_buf = 5{??} \ cmd_buf=12{??} \ status_buf = {??} \ msg_in_buf = {??} \ data_buf = 512{??} ;*********************************************************************** ; ENTRY declarations ENTRY multi_thread ENTRY to_decisions ENTRY id_msg_out ENTRY synch_msg_out ENTRY msg_in_phase ENTRY synch_msg_in ENTRY cmd_phase ENTRY data_in_phase ENTRY data_out_phase ENTRY status_phase ENTRY disconnected ENTRY reselected ENTRY selected ENTRY entry0 ENTRY entry1 ENTRY entry2 ENTRY io_request0 ENTRY io_request1 ENTRY io_request2 ENTRY schedule_NOP ;*********************************************************************** ; TEST CODE - DO NOT INCLUDE IN SCRIPT FILE ; C code ;pass(unsigned long SCRIPTphysaddr=0x00400000) ;pass(unsigned long nop_physaddr=0x00300000) ;pass(unsigned long table0=0x00210000) ;pass(unsigned long table1=0x00220000) ;pass(unsigned long table2=0x00230000) ; END TEST CODE ;*********************************************************************** ; Scheduler SCRIPT code scheduler: entry0: ;Initialize DSA register with table base address for using table ;indirect addressing MOVE MEMORY 4, pass(table0), pass(chip_physaddr+DSA) ;Initilize address for changing jump to nop after starting new I/O ;(after SELECT instruction in main SCRIPT code) MOVE MEMORY 4, pass(SCRIPTphysaddr+io_request0), pass(SCRIPTphysaddr+schedule_NOP+8) io_request0: JUMP REL(multi_thread) entry1: MOVE MEMORY 4, pass(table1), pass(chip_physaddr+DSA) MOVE MEMORY 4, pass(SCRIPTphysaddr+io_request1), pass(SCRIPTphysaddr+schedule_NOP+8) io_request1: JUMP REL(multi_thread) entry2: MOVE MEMORY 4, pass(table2), pass(chip_physaddr+DSA) MOVE MEMORY 4, pass(SCRIPTphysaddr+io_request2), pass(SCRIPTphysaddr+schedule_NOP+8) io_request2: JUMP REL(multi_thread) JUMP REL(wait_for_reselect) ;*********************************************************************** ; main SCRIPT code multi_thread: SELECT ATN FROM SCSI_id, REL(wait_for_reselect) ;Change jump to nop in scheduler after starting new I/O ;the destination address is initialized from scheduler SCRIPT schedule_NOP: MOVE MEMORY 4, pass(nop_physaddr), pass(place_hold_addr) JUMP REL(to_decisions), WHEN NOT MSG_OUT id_msg_out: MOVE FROM identify_msg_buf, WHEN MSG_OUT JUMP REL(to_decisions), WHEN NOT CMD cmd_phase: CLEAR ATN MOVE FROM cmd_buf, WHEN CMD JUMP REL(to_decisions), WHEN NOT DATA_IN data_in_phase: MOVE FROM data_buf, WHEN DATA_IN JUMP REL(status_phase), WHEN STATUS JUMP REL(to_decisions) data_out_phase: MOVE FROM data_buf, WHEN DATA_OUT JUMP REL(to_decisions), WHEN NOT STATUS status_phase: MOVE FROM status_buf, WHEN STATUS JUMP REL(to_decisions), WHEN NOT MSG_IN msg_in_phase: MOVE FROM msg_in_buf, WHEN MSG_IN JUMP REL(disconnected), IF DISCONNECT_ JUMP REL(msg_in_phase), WHEN SAVE_DATAPTR ;compare data, wait for phase INT error_not_cmd_complete, IF NOT 0x00 CLEAR ACK ; For 53c720 and above add the following line ; MOVE SCNTL2 & 0x7F TO SCNTL2 WAIT DISCONNECT INT io_complete disconnected: ;For 53c720 and above use the following line ; MOVE SCNTL2 & 0x7F TO SCNTL2 WAIT DISCONNECT JUMP REL(wait_for_reselect) to_decisions: JUMP REL(msg_in_phase), WHEN MSG_IN JUMP REL(cmd_phase), IF CMD JUMP REL(data_in_phase), IF DATA_IN JUMP REL(data_out_phase), IF DATA_OUT JUMP REL(status_phase), IF STATUS INT error_unexpected_phase ;Reselect SCRIPT code wait_for_reselect: WAIT RESELECT REL(CPU_set_SIGP) SCSI_id_jump_table: MOVE LCRC TO SFBR ; For 53c720 and above use the following line instead of Move LCRC to SFBR ; MOVE SSID TO SFBR JUMP REL(id_0), IF 0x81 ;chip id 7, target id0 JUMP REL(id_1), IF 0x82 JUMP REL(id_2), IF 0x84 INT reselect_id_error id_0: MOVE MEMORY 4, pass(table0), pass(chip_physaddr+DSA) ;initialize SXFER for synchronous transfers from table MOVE MEMORY 1,pass(table0+2),pass(chip_physaddr+SXFER) ; For 53c720 add the following line ; MOVE MEMORY 1,pass(table0),pass(chip_physaddr+SCNTL3) ; This will set up the clock dividers as defined in the SCNTL3 register MOVE FROM identify_msg_buf, WHEN MSG_IN CLEAR ACK JUMP REL(to_decisions) id_1: MOVE MEMORY 4, pass(table1), pass(chip_physaddr+DSA) ;initialize SXFER for synchronous transfers from table MOVE MEMORY 1, pass(table1+2),pass(chip_physaddr+SXFER) ; For 53c720 add the following line ; MOVE MEMORY 1,pass(table1),pass(chip_physaddr+SCNTL3) ; This will set up the clock dividers as defined in the SCNTL3 register MOVE FROM identify_msg_buf, WHEN MSG_IN CLEAR ACK JUMP REL(to_decisions) id_2: MOVE MEMORY 4, pass(table2), pass(chip_physaddr+DSA) ;initialize SXFER for synchronous transfers from table MOVE MEMORY 1,pass(table2+2),pass(chip_physaddr+SXFER) ; For 53c720 add the following line ; MOVE MEMORY 1,pass(table2),pass(chip_physaddr+SCNTL3) ; This will set up the clock dividers as defined in the SCNTL3 register MOVE FROM identify_msg_buf, WHEN MSG_IN CLEAR ACK JUMP REL(to_decisions) CPU_set_SIGP: JUMP Scheduler