MODULE mod_handle_cat_cards ; { Created 27-JAN-1992 MICHIGAN STATE UNIVERSITY, TRIGGER CONTROL SOFTWARE } { *************************************************************************** } INCLUDE mod_common_global_flags, mod_handle_tracing, mod_def_hardware_tables, mod_handle_registers, mod_common_hard_io ; { *************************************************************************** } EXPORT update_cat3_correction,{PROCEDURE set a cat3 for tree offset correction } update_cat2_threshold, {PROCEDURE load a cat2 threshold comparator by number} update_cat3_threshold, {PROCEDURE load a cat3 threshold comparator by number} examine_cat2_operand, {PROCEDURE read the value of a cat2 card operand } examine_cat3_operand, {PROCEDURE read the value of a cat3 card operand } load_cat2_threshold, {PROCEDURE load a cat2 threshold comparator by addr. } read_cat2_threshold ; {PROCEDURE read a cat2 threshold comparator by addr. } { *************************************************************************** } IMPORT status_type, {from module MOD_COMMON_GLOBAL_FLAGS } ok,{io_failure,}error_found, {from module MOD_COMMON_GLOBAL_FLAGS } trace_info,{trace_warn,}trace_error,{from module MOD_HANDLE_TRACING } inline_tracing, {from module MOD_HANDLE_TRACING } handle_trc_inf, {from module MOD_HANDLE_TRACING } handle_trc_err, {from module MOD_HANDLE_TRACING } cbus_register, {from module MOD_DEF_HARDWARE_TABLES } comparison_number, {from module MOD_DEF_HARDWARE_TABLES } cat3_cor_0_5, cat3_cor_6_11, cat3_cor_12_17, cat3_cor_18_23, bit_0_5, {from module MOD_DEF_HARDWARE_TABLES } cat2_card, {from module MOD_DEF_HARDWARE_TABLES } cat3_card, {from module MOD_DEF_HARDWARE_TABLES } cat3_cmp_0_5, {from module MOD_DEF_HARDWARE_TABLES } update_register, {from module MOD_HANDLE_REGISTER } examine_register, {from module MOD_HANDLE_REGISTER } cbus_param_list ; {from module MOD_COMMON_HARD_IO } { *************************************************************************** } { *************************************************************************** } TYPE byte = [BYTE] 0..255 ; VAR tag : VARYING_STRING(8) := 'CAT/REG%' ; { *************************************************************************** } { *************************************************************************** } PROCEDURE update_cat3_correction ( tagext : VARYING_STRING(8) := '' ; card :^cat3_card ; correction : INTEGER ; iopar :^cbus_param_list ; VAR status :[OPTIONAL] status_type ) ; TYPE integer_by_6bit_fields = [LONG] PACKED RECORD CASE INTEGER OF 0 : ( first_field : [POS( 0)] 0..63 ; second_field : [POS( 6)] 0..63 ; third_field : [POS(12)] 0..63 ; fourth_field : [POS(18)] 0..63 ; overflow : [POS(24)] 0..255 ) ; 1 : ( low_24bits : [POS( 0)] 0..16777215 ; high_8bits : [POS(24)] 0..255 ) ; END ; VAR corr_by_field : integer_by_6bit_fields ; step_status : status_type ; glob_status : status_type ; BEGIN glob_status := ok ; {the value to load is the opposite of the correction, truncated to 4*6 bits} corr_by_field::INTEGER := - correction ; IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := tag + tagext, MESSAGE := ' Write in CAT3 correction register ' + HEX (corr_by_field.low_24bits,6,6) + ' hex' ) ; IF ( ( correction <> 0 ) AND ( corr_by_field.overflow <> 255 ) ) THEN IF ( inline_tracing(trace_error) <> 0 ) THEN BEGIN handle_trc_err ( TAG := tag + tagext, MESSAGE := ' CAT3 correction register overflow ' ) ; glob_status := error_found ; GOTO cat3_correction_error ; END ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := ADDRESS(card^.corrreg[cat3_cor_0_5]), IOPAR := iopar, DATA := corr_by_field.first_field, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := ADDRESS(card^.corrreg[cat3_cor_6_11]), IOPAR := iopar, DATA := corr_by_field.second_field, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := ADDRESS(card^.corrreg[cat3_cor_12_17]), IOPAR := iopar, DATA := corr_by_field.third_field, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := ADDRESS(card^.corrreg[cat3_cor_18_23]), IOPAR := iopar, DATA := corr_by_field.fourth_field, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; cat3_correction_error: IF ( glob_status <> ok ) THEN IF ( inline_tracing(trace_error) <> 0 ) THEN handle_trc_err ( TAG := tag + tagext, MESSAGE := ' Failure Writing CAT3 correction register' ) ; IF PRESENT(status) THEN status := glob_status ; END ; { *************************************************************************** } { *************************************************************************** } PROCEDURE update_cat2_threshold ( tagext : VARYING_STRING(8) := '' ; card :^cat2_card ; comp_num : INTEGER ; count_threshold : INTEGER ; iopar :^cbus_param_list ; VAR status :[OPTIONAL] status_type ) ; TYPE integer_by_6bit_fields = [LONG] PACKED RECORD first_field : [POS( 0)] 0..63 ; second_field : [POS( 6)] 0..63 ; third_field : [POS(12)] 0..7 ; overflow : [POS(15)] 0..131071 ; END ; VAR register :^cbus_register ; thrsh : integer_by_6bit_fields ; step_status : status_type ; glob_status : status_type ; rel_card_num : INTEGER ; rel_comp_num : comparison_number ; BEGIN glob_status := ok ; rel_card_num := ( comp_num DIV 4 ) ; rel_comp_num := CONVERT( comparison_number, (comp_num MOD 4) ) ; card::INTEGER := card::INTEGER + rel_card_num * SIZE(cat2_card) ; register := ADDRESS(card^.compreg[rel_comp_num,bit_0_5]) ; IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := tag + tagext, MESSAGE := ' Write CAT2 comparator #' + CONVERT(STRING,comp_num) + ' (i.e. Card ' + CONVERT(STRING,rel_card_num) + ',' + CONVERT(STRING,rel_comp_num) + ') Threshold = ' + CONVERT(STRING,count_threshold) ) ; thrsh::INTEGER := count_threshold ; IF ( thrsh.overflow <> 0 ) THEN IF ( inline_tracing(trace_error) <> 0 ) THEN BEGIN handle_trc_err ( TAG := tag + tagext, MESSAGE := ' CAT2 Threshold overflow ' ) ; glob_status := error_found ; GOTO cat2_cmp_load_error ; END ; load_cat2_threshold ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, THRESHOLD := thrsh::INTEGER, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; cat2_cmp_load_error: IF ( glob_status <> ok ) THEN IF ( inline_tracing(trace_error) <> 0 ) THEN handle_trc_err ( TAG := tag + tagext, MESSAGE := ' Failure Writing CAT2 comparator #' + CONVERT(STRING,comp_num) + ' (i.e. Card ' + CONVERT(STRING,rel_card_num) + ',' + CONVERT(STRING,rel_comp_num) + ')' ) ; IF PRESENT(status) THEN status := glob_status ; END ; { *************************************************************************** } { *************************************************************************** } PROCEDURE update_cat3_threshold ( tagext : VARYING_STRING(8) := '' ; card :^cat3_card ; comp_num : INTEGER ; count_threshold : INTEGER ; iopar :^cbus_param_list ; VAR status :[OPTIONAL] status_type ) ; TYPE integer_by_6bit_fields = [LONG] PACKED RECORD first_field : [POS( 0)] 0..63 ; second_field : [POS( 6)] 0..63 ; third_field : [POS(12)] 0..63 ; fourth_field : [POS(18)] 0..1 ; overflow : [POS(19)] 0..8191 ; END ; VAR register :^cbus_register ; thrsh : integer_by_6bit_fields ; step_status : status_type ; glob_status : status_type ; rel_card_num : INTEGER ; rel_comp_num : comparison_number ; BEGIN glob_status := ok ; rel_card_num := ( comp_num DIV 4 ) ; rel_comp_num := CONVERT( comparison_number, (comp_num MOD 4) ) ; card::INTEGER := card::INTEGER + rel_card_num * SIZE(cat3_card) ; register := ADDRESS(card^.compreg[rel_comp_num,cat3_cmp_0_5]) ; IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := tag + tagext, MESSAGE := ' Write CAT3 comparator #' + CONVERT(STRING,comp_num) + ' (i.e. Card ' + CONVERT(STRING,rel_card_num) + ',' + CONVERT(STRING,rel_comp_num) + ') Threshold = ' + CONVERT(STRING,count_threshold) ) ; thrsh::INTEGER := count_threshold ; IF ( thrsh.overflow <> 0 ) THEN IF ( inline_tracing(trace_error) <> 0 ) THEN BEGIN handle_trc_err ( TAG := tag + tagext, MESSAGE := ' CAT3 Threshold overflow ' ) ; glob_status := error_found ; GOTO cat3_cmp_load_error ; END ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := thrsh.first_field, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := thrsh.second_field, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := thrsh.third_field, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := thrsh.fourth_field, STATUS := step_status ) ; IF ( step_status <> ok ) THEN glob_status := step_status ; cat3_cmp_load_error: IF ( glob_status <> ok ) THEN IF ( inline_tracing(trace_error) <> 0 ) THEN handle_trc_err ( TAG := tag + tagext, MESSAGE := ' Failure Writing CAT3 comparator #' + CONVERT(STRING,comp_num) + ' (i.e. Card ' + CONVERT(STRING,rel_card_num) + ',' + CONVERT(STRING,rel_comp_num) + ')' ) ; IF PRESENT(status) THEN status := glob_status ; END ; { *************************************************************************** } { *************************************************************************** } PROCEDURE examine_cat2_operand ( tagext : VARYING_STRING(8) := '' ; card :^cat2_card ; op_num : INTEGER ; iopar :^cbus_param_list ; VAR op_value : INTEGER ) ; VAR data : byte ; register :^cbus_register ; BEGIN IF ( ( op_num < 1 ) OR ( op_num > 8 ) ) THEN handle_trc_err ( TAG := tag + tagext, MESSAGE := ' illegal parameter call to examine_cat2_operand' ); register := ADDRESS(card^.inopreg[op_num,bit_0_5]) ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data ) ; op_value := data ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data ) ; op_value := 64 * data + op_value ; IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := tag + tagext, MESSAGE := ' Read CAT2 Input operand #' + CONVERT(STRING,op_num) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' = ' + CONVERT(STRING,op_value) ); END ; { *************************************************************************** } { *************************************************************************** } PROCEDURE examine_cat3_operand ( tagext : VARYING_STRING(8) := '' ; card :^cat3_card ; op_num : INTEGER ; iopar :^cbus_param_list ; VAR op_value : INTEGER ) ; VAR data : byte ; register :^cbus_register ; BEGIN CASE op_num OF 1 : register := ADDRESS(card^.inopreg[0]) ; 2 : register := ADDRESS(card^.inopreg[2]) ; 3 : register := ADDRESS(card^.inopreg[5]) ; 4 : register := ADDRESS(card^.inopreg[8]) ; 5 : register := ADDRESS(card^.inopreg[10]) ; 6 : register := ADDRESS(card^.inopreg[13]) ; OTHERWISE handle_trc_err ( TAG := tag + tagext, MESSAGE := ' illegal parameter call to examine_cat3_operand' ); END ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data ) ; CASE op_num OF 1,4 : op_value := data ; {bit 0:5 become bit 0:5} 2,5 : op_value := data DIV 16 ; {bit 4:5 become bit 0:1} 3,6 : op_value := data DIV 4 ; {bit 2:5 become bit 0:3} END ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data ) ; CASE op_num OF 1,4 : op_value := op_value + 64 * data ; {bit 0:5 become bit 6:11} 2,5 : op_value := op_value + 4 * data ; {bit 0:5 become bit 2:7 } 3,6 : op_value := op_value + 16 * data ; {bit 0:5 become bit 4:9 } END ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data ) ; CASE op_num OF 1,4 : op_value := op_value + 4096 *(data MOD 16); {bit 0:3 become bit 12:15} 2,5 : op_value := op_value + 256 * data ; {bit 0:5 become bit 8:13} 3,6 : op_value := op_value + 1024 * data ; {bit 0:5 become bit 10:15} END ; IF ( ( op_num = 2 ) OR ( op_num = 5 ) ) THEN BEGIN register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data ) ; op_value := op_value + 16384 *(data MOD 4); {bit 0:1 become bit 14:15} END ; IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := tag + tagext, MESSAGE := ' Read CAT3 Input operand #' + CONVERT(STRING,op_num) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' = ' + CONVERT(STRING,op_value) ); END ; { *************************************************************************** } { *************************************************************************** } [INLINE] PROCEDURE load_cat2_threshold ( tagext : VARYING_STRING(8) := '' ; card :^ANYTYPE ; register :^cbus_register ; iopar :^cbus_param_list ; threshold : INTEGER ; VAR status :[OPTIONAL] status_type ) ; TYPE integer_by_6bit_fields = [LONG] PACKED RECORD first_field : [POS( 0)] 0..63 ; second_field : [POS( 6)] 0..63 ; third_field : [POS(12)] 0..7 ; rest : [POS(15)] 0..131071 ; END ; VAR thrsh : ^integer_by_6bit_fields ; load_status : status_type ; BEGIN IF PRESENT(status) THEN status := ok ; thrsh := ADDRESS(threshold::integer_by_6bit_fields) ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := thrsh^.first_field, STATUS := load_status ) ; IF ( load_status <> ok ) THEN IF PRESENT(status) THEN status := load_status ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := thrsh^.second_field, STATUS := load_status ) ; IF ( load_status <> ok ) THEN IF PRESENT(status) THEN status := load_status ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; update_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := thrsh^.third_field, STATUS := load_status ) ; IF ( load_status <> ok ) THEN IF PRESENT(status) THEN status := load_status ; END ; { *************************************************************************** } { *************************************************************************** } [INLINE] PROCEDURE read_cat2_threshold ( tagext : VARYING_STRING(8) := '' ; card :^ANYTYPE ; register :^cbus_register ; iopar :^cbus_param_list ; VAR threshold : INTEGER ; VAR status :[OPTIONAL] status_type ) ; TYPE integer_by_6bit_fields = [LONG] PACKED RECORD first_field : [POS( 0)] 0..63 ; second_field : [POS( 6)] 0..63 ; third_field : [POS(12)] 0..7 ; rest : [POS(15)] 0..131071 ; END ; VAR thrsh : ^integer_by_6bit_fields ; read_status : status_type ; data : byte ; BEGIN IF PRESENT(status) THEN status := ok ; thrsh := ADDRESS(threshold::integer_by_6bit_fields) ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data, STATUS := read_status ) ; IF ( read_status <> ok ) THEN IF PRESENT(status) THEN status := read_status ; thrsh^.first_field := data ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data, STATUS := read_status ) ; IF ( read_status <> ok ) THEN IF PRESENT(status) THEN status := read_status ; thrsh^.second_field := data ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; examine_register ( TAGEXT := tagext, CARD := card, REGISTER := register, IOPAR := iopar, DATA := data, STATUS := read_status ) ; IF ( read_status <> ok ) THEN IF PRESENT(status) THEN status := read_status ; thrsh^.third_field := data ; END ; { *************************************************************************** } { *************************************************************************** } END.