{ *************************************************************************** } MODULE mod_handle_registers ; { Created 11-MAY-1989 MICHIGAN STATE UNIVERSITY, TRIGGER CONTROL SOFTWARE } { *************************************************************************** } INCLUDE mod_common_global_flags, mod_def_hardware_tables, mod_handle_tracing, mod_common_hard_io, {from the TRICS hardware IO library } mod_tcs_io_cbus_handling, {from the TRICS hardware IO library } mod_tcs_io_prescaler_handling ; {from the TRICS hardware IO library } { *************************************************************************** } EXPORT update_register, {PROCEDURE write a register and update hardware data base } update_prscratio, {PROCEDURE write a prescaling ratio and check } examine_register, {PROCEDURE read a register and update hardware data base } examine_multi_byte, {PROCEDURE read 2 or 3 consecutive registers } histogram_register, {PROCEDURE read register many times and update database } re_examine_register;{PROCEDURE read again previously read register } { *************************************************************************** } IMPORT status_type, ok, {already_done,} io_failure, {from module MOD_COMMON_GLOBAL_FLAGS } trace_info, trace_warn, trace_error,{from module MOD_HANDLE_TRACING } inline_tracing, {from module MOD_HANDLE_TRACING } io_tracing, db_tracing, ON, {from module MOD_HANDLE_TRACING } handle_trc_inf, {from module MOD_HANDLE_TRACING } handle_trc_wrn, {from module MOD_HANDLE_TRACING } handle_trc_err, {from module MOD_HANDLE_TRACING } {reg_singularities,}reg_class, {from module MOD_DEF_HARDWARE_TABLES } histdep, multidef, multir, multiw, dobbuf, ronly, aux_class1, aux_class2, cbus_register, card_header, {from module MOD_DEF_HARDWARE_TABLES } cbus_param_list, {from module MOD_COMMON_HARD_IO } array_0_255, {from module MOD_COMMON_HARD_IO } proced_tcs_write_cbus, {from module MOD_TCS_IO_CBUS_HANDLING } proced_tcs_read_cbus, {from module MOD_TCS_IO_CBUS_HANDLING } proced_tcs_read_cbus_histogram, {from module MOD_TCS_IO_CBUS_HANDLING } proced_tcs_write_prscratio ; {from mod MOD_TCS_IO_PRESCALER_HANDLING } { *************************************************************************** } { *************************************************************************** } TYPE byte = [BYTE] 0..255 ; { *************************************************************************** } { *************************************************************************** } PROCEDURE update_register ( tagext : VARYING_STRING(8) := '' ; card :^ANYTYPE ; register :^cbus_register ; iopar :^cbus_param_list ; data : byte ; VAR status :[OPTIONAL] status_type ) ; VAR generic_card :^card_header ; masked_dataout : byte ; masked_datain : byte ; BEGIN generic_card::BYTE_DATA := card::BYTE_DATA ; IF PRESENT(status) THEN status := ok ; iopar^.dataout := data ; masked_dataout := inline_byte_mask ( data, register^.wmsk ) ; { *** retrieve the card's hardware parameters } iopar^.cbus := generic_card^.cbus ; iopar^.mba := generic_card^.mba ; iopar^.ca := generic_card^.ca ; iopar^.fa := register^.fa ; IF ( io_tracing = ON ) THEN IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := 'HIO/CBS%' + tagext, MESSAGE := ' Reg Write' + CONVERT(STRING(4),iopar^.dataout) + ' or bin ' + BIN(iopar^.dataout,8,8) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; proced_tcs_write_cbus ( iopar ) ; IF ( inline_tracing(trace_warn) <> 0 ) THEN BEGIN IF ( db_tracing = ON ) THEN IF ( register^.class {* [ ronly, dobbuf, multiw, histdep ]} <> [] ) THEN handle_trc_wrn ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' Write Class' + show_reg_class(register^.class) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) + ' data' + CONVERT(STRING(4),data) ) ; iopar^.dataprev := inline_byte_mask ( iopar^.dataprev, register^.rmsk ) ; { this would take more work to be useful. "Trace Warning" is not being used } { removed 18-DEC-1992 { IF ( io_tracing = ON ) { THEN IF ( iopar^.dataprev = iopar^.dataout ) { THEN handle_trc_wrn ( TAG := 'HIO/CBS%' + tagext, { MESSAGE := ' Content Already was' { + CONVERT(STRING(4),iopar^.dataout) { + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) { + ' mba' + CONVERT(STRING(4),iopar^.mba) { + ' ca' + CONVERT(STRING(3),iopar^.ca) { + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; } END ; IF ( inline_tracing(trace_error) <> 0 ) THEN BEGIN IF ( masked_dataout <> iopar^.dataout ) THEN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' Range Error' + CONVERT(STRING(4),data) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) + ' wmsk ' + BIN(register^.wmsk,8,8) ) ; {Check Previous Data: verify only the read-write bits} iopar^.dataprev := inline_byte_mask ( iopar^.dataprev, register^.rmsk ) ; IF ( db_tracing = ON ) THEN IF ( inline_byte_mask( register^.content, register^.wmsk ) <> inline_byte_mask( iopar^.dataprev, register^.wmsk ) ) THEN BEGIN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' Previously' + CONVERT(STRING(4),iopar^.dataprev) + ' instead of' + CONVERT(STRING(4),register^.content) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; handle_trc_err ( TAG := 'HIO/HDB%', MESSAGE := ' (cont) ' + BIN(iopar^.dataprev,8,8) + ' i/of ' + BIN(register^.content,8,8) + ' Msk= W ' + BIN(register^.wmsk,8,8) + ' R ' + BIN(register^.rmsk,8,8) + ', Writing ' + CONVERT(STRING(3),iopar^.dataout) ) ; END ; END ; {Check New Data: verify only the read-write bits} masked_datain := inline_byte_mask ( iopar^.datain, register^.rmsk ) ; IF ( inline_byte_mask ( masked_dataout, register^.rmsk ) <> inline_byte_mask ( masked_datain, register^.wmsk ) ) THEN BEGIN IF PRESENT(status) THEN status := io_failure ; IF ( inline_tracing(trace_error) <> 0 ) THEN BEGIN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' Failure Writing' + CONVERT(STRING(4),iopar^.dataout) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) + ' read' + CONVERT(STRING(4),iopar^.datain) ) ; handle_trc_err ( TAG := 'HIO/HDB%', MESSAGE := ' (cont) Data = Out ' + BIN(iopar^.dataout,8,8) + ' In ' + BIN(iopar^.datain,8,8) + ' Mask= W ' + BIN(register^.wmsk,8,8) + ' R ' + BIN(register^.rmsk,8,8) ) ; END ; END ; register^.content := masked_datain ; END ; { *************************************************************************** } { *************************************************************************** } PROCEDURE update_prscratio ( tagext : VARYING_STRING(8) := '' ; card :^ANYTYPE ; register :^cbus_register ; iopar :^cbus_param_list ; ratio : INTEGER ; VAR status :[OPTIONAL] status_type ) ; VAR generic_card :^card_header ; BEGIN generic_card::BYTE_DATA := card::BYTE_DATA ; IF PRESENT(status) THEN status := ok ; { *** retrieve the card's hardware parameters } iopar^.cbus := generic_card^.cbus ; iopar^.mba := generic_card^.mba ; iopar^.ca := generic_card^.ca ; iopar^.fa := register^.fa ; iopar^.psratio := ratio ; IF ( io_tracing = ON ) THEN IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := 'HIO/CBS%' + tagext, MESSAGE := ' Prescaling by ' + CONVERT(STRING,ratio) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; IF ( inline_tracing(trace_error) <> 0 ) THEN IF ( register^.class <> [ histdep ] ) THEN BEGIN IF PRESENT(status) THEN status := io_failure ; handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' Not a Prescaler Ctrl Reg ' + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; END ; proced_tcs_write_prscratio ( iopar ) ; IF ( iopar^.psratio <> ratio ) THEN BEGIN IF PRESENT(status) THEN status := io_failure ; IF ( inline_tracing(trace_error) <> 0 ) THEN handle_trc_err ( TAG := 'HIO/CBS%' + tagext, MESSAGE := ' Failure Writing Ratio ' + CONVERT(STRING,ratio) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) + ' read ' + CONVERT(STRING,iopar^.psratio) ) ; END ; END ; { *************************************************************************** } { *************************************************************************** } PROCEDURE examine_register ( tagext : VARYING_STRING(8) := '' ; card :^ANYTYPE ; register :^cbus_register ; sliceage : INTEGER := 0 ; iopar :^cbus_param_list ; VAR data : byte ; VAR status :[OPTIONAL] status_type ) ; VAR generic_card :^card_header ; BEGIN IF PRESENT(status) THEN status := ok ; generic_card::BYTE_DATA := card::BYTE_DATA ; { *** retrieve the card's hardware parameters } iopar^.cbus := generic_card^.cbus ; iopar^.mba := generic_card^.mba ; iopar^.ca := generic_card^.ca ; iopar^.fa := register^.fa ; IF ( register^.pipelen = 0 ) THEN BEGIN IF ( sliceage <> 0 ) THEN BEGIN IF PRESENT(status) THEN status := io_failure ; IF ( inline_tracing(trace_error) <> 0 ) THEN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' No Slice Age' + CONVERT(STRING(2),sliceage) + ', Not a Pipelined Reg' + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; END ; END ELSE BEGIN IF ( (sliceage+1) > register^.pipelen ) THEN BEGIN IF PRESENT(status) THEN status := io_failure ; IF ( inline_tracing(trace_error) <> 0 ) THEN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' No Slice Age' + CONVERT(STRING(2),sliceage) + ', Pipe is only' + CONVERT(STRING(2),register^.pipelen) + ' deep' + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; END ELSE BEGIN CASE register^.pipelen OF 2 : CASE sliceage OF 0 : iopar^.fa := iopar^.fa + 128 ; 1 : iopar^.fa := iopar^.fa + 0 ; END ; 8 : CASE sliceage OF 0 : iopar^.fa := iopar^.fa + 224 ; 1 : iopar^.fa := iopar^.fa + 192 ; 2 : iopar^.fa := iopar^.fa + 160 ; 3 : iopar^.fa := iopar^.fa + 128 ; 4 : iopar^.fa := iopar^.fa + 96 ; 5 : iopar^.fa := iopar^.fa + 64 ; 6 : iopar^.fa := iopar^.fa + 32 ; 7 : iopar^.fa := iopar^.fa + 0 ; END ; END ; END ; END ; proced_tcs_read_cbus ( iopar ) ; iopar^.datain := inline_byte_mask ( iopar^.datain, register^.rmsk ) ; IF ( io_tracing = ON ) THEN IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := 'HIO/CBS%' + tagext, MESSAGE := ' Reg Read' + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) + ' data' + CONVERT(STRING(4),iopar^.datain) + ' or bin ' + BIN(iopar^.datain,8,8) ) ; IF ( inline_tracing(trace_error) <> 0 ) THEN IF ( db_tracing = ON ) THEN IF ( register^.class {* [ ronly, dobbuf, multiw, histdep ]} = [] ) THEN IF ( register^.content <> iopar^.datain ) THEN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' Read' + CONVERT(STRING(4),iopar^.datain) + ' instead of' + CONVERT(STRING(4),register^.content) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; register^.content := iopar^.datain ; data := iopar^.datain ; END ; { *************************************************************************** } { *************************************************************************** } { *************************************************************************** } PROCEDURE examine_multi_byte ( tagext : VARYING_STRING(8) := '' ; card :^ANYTYPE ; register :^cbus_register ; iopar :^cbus_param_list ; VAR two_byte_value :[OPTIONAL] INTEGER ; VAR three_byte_value :[OPTIONAL] INTEGER ) ; TYPE three_byter = [LONG] PACKED RECORD low_byte : [POS(0)] byte ; mid_byte : [POS(8)] byte ; high_byte : [POS(16)] byte ; END ; VAR data : three_byter ; BEGIN data::INTEGER := 0 ; inline_examine_register ( CARD := card, REGISTER := register, IOPAR := iopar, DATA := data.low_byte ) ; register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; inline_examine_register ( CARD := card, REGISTER := register, IOPAR := iopar, DATA := data.mid_byte ) ; IF PRESENT(two_byte_value) THEN two_byte_value := data::INTEGER ELSE BEGIN register::INTEGER := register::INTEGER + SIZE( cbus_register ) ; inline_examine_register ( CARD := card, REGISTER := register, IOPAR := iopar, DATA := data.high_byte ) ; three_byte_value := data::INTEGER ; END ; END ; { *************************************************************************** } { *************************************************************************** } {not exported} [INLINE] PROCEDURE inline_examine_register ( card :^ANYTYPE ; register :^cbus_register ; iopar :^cbus_param_list ; VAR data : byte ) ; VAR generic_card :^card_header ; BEGIN generic_card::BYTE_DATA := card::BYTE_DATA ; { *** retrieve the card's hardware parameters } iopar^.cbus := generic_card^.cbus ; iopar^.mba := generic_card^.mba ; iopar^.ca := generic_card^.ca ; iopar^.fa := register^.fa ; CASE register^.pipelen OF 2 : iopar^.fa := iopar^.fa + 128 ; 8 : iopar^.fa := iopar^.fa + 224 ; END ; proced_tcs_read_cbus ( iopar ) ; data := iopar^.datain ; END ; { *************************************************************************** } { *************************************************************************** } PROCEDURE histogram_register ( tagext : VARYING_STRING(8) := '' ; card :^ANYTYPE ; register :^cbus_register ; sliceage : INTEGER := 0 ; iopar :^cbus_param_list ; histogram :^array_0_255 ; sample_size : INTEGER ; VAR status :[OPTIONAL] status_type ) ; VAR generic_card :^card_header ; BEGIN IF PRESENT(status) THEN status := ok ; generic_card::BYTE_DATA := card::BYTE_DATA ; { *** retrieve the card's hardware parameters } iopar^.cbus := generic_card^.cbus ; iopar^.mba := generic_card^.mba ; iopar^.ca := generic_card^.ca ; iopar^.fa := register^.fa ; IF ( register^.pipelen = 0 ) THEN BEGIN IF ( sliceage <> 0 ) THEN BEGIN IF PRESENT(status) THEN status := io_failure ; IF ( inline_tracing(trace_error) <> 0 ) THEN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' No Slice Age' + CONVERT(STRING(2),sliceage) + ', Not a Pipelined Reg' + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; END ; END ELSE BEGIN IF ( (sliceage+1) > register^.pipelen ) THEN BEGIN IF PRESENT(status) THEN status := io_failure ; IF ( inline_tracing(trace_error) <> 0 ) THEN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' No Slice Age' + CONVERT(STRING(2),sliceage) + ', Pipe is only' + CONVERT(STRING(2),register^.pipelen) + ' deep' + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; END ELSE BEGIN CASE register^.pipelen OF 2 : CASE sliceage OF 0 : iopar^.fa := iopar^.fa + 128 ; 1 : iopar^.fa := iopar^.fa + 0 ; END ; 8 : CASE sliceage OF 0 : iopar^.fa := iopar^.fa + 224 ; 1 : iopar^.fa := iopar^.fa + 192 ; 2 : iopar^.fa := iopar^.fa + 160 ; 3 : iopar^.fa := iopar^.fa + 128 ; 4 : iopar^.fa := iopar^.fa + 96 ; 5 : iopar^.fa := iopar^.fa + 64 ; 6 : iopar^.fa := iopar^.fa + 32 ; 7 : iopar^.fa := iopar^.fa + 0 ; END ; END ; END ; END ; proced_tcs_read_cbus_histogram ( PARAM := iopar, HISTOGRAM := histogram, SAMPLE_SIZE := sample_size ) ; iopar^.datain := inline_byte_mask ( iopar^.datain, register^.rmsk ) ; IF ( io_tracing = ON ) THEN IF ( inline_tracing(trace_info) <> 0 ) THEN handle_trc_inf ( TAG := 'HIO/CBS%' + tagext, MESSAGE := ' Last Histo Entry' + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) + ' data' + CONVERT(STRING(4),iopar^.datain) + ' or bin ' + BIN(iopar^.datain,8,8) ) ; IF ( inline_tracing(trace_error) <> 0 ) THEN IF ( db_tracing = ON ) THEN IF ( register^.class {* [ ronly, dobbuf, multiw, histdep ]} = [] ) THEN IF ( register^.content <> iopar^.datain ) THEN handle_trc_err ( TAG := 'HIO/HDB%' + tagext, MESSAGE := ' Read' + CONVERT(STRING(4),iopar^.datain) + ' instead of' + CONVERT(STRING(4),register^.content) + ' @ cbus' + CONVERT(STRING(2),iopar^.cbus) + ' mba' + CONVERT(STRING(4),iopar^.mba) + ' ca' + CONVERT(STRING(3),iopar^.ca) + ' fa' + CONVERT(STRING(4),iopar^.fa) ) ; { record last reading } register^.content := iopar^.datain ; END ; { *************************************************************************** } { *************************************************************************** } PROCEDURE re_examine_register ( tagext : VARYING_STRING(8) := '' ; register :^cbus_register ; iopar :^cbus_param_list ; VAR data : byte ) ; BEGIN proced_tcs_read_cbus ( iopar ) ; iopar^.datain := inline_byte_mask ( iopar^.datain, register^.rmsk ) ; register^.content := iopar^.datain ; data := iopar^.datain ; END ; { *************************************************************************** } { *************************************************************************** } [INLINE] FUNCTION inline_byte_mask ( op1 , op2 : byte ) : byte ; VAR bool1, bool2, bool3 : BOOLEAN ; BEGIN bool1::BYTE_DATA := op1::BYTE_DATA ; bool2::BYTE_DATA := op2::BYTE_DATA ; bool3 := bool1 AND bool2 ; inline_byte_mask::BYTE_DATA := bool3::BYTE_DATA ; END ; { *************************************************************************** } { *************************************************************************** } FUNCTION show_reg_class ( class : reg_class ) : VARYING_STRING (70) ; VAR buffer : VARYING_STRING (70) ; BEGIN buffer := '' ; IF ( histdep IN class ) THEN buffer := buffer + ' HISTDEP' ; IF ( multidef IN class ) THEN buffer := buffer + ' MULTIDEF' ; IF ( multir IN class ) THEN buffer := buffer + ' MULTIR' ; IF ( multiw IN class ) THEN buffer := buffer + ' MULTIW' ; IF ( dobbuf IN class ) THEN buffer := buffer + ' DOBBUF' ; IF ( ronly IN class ) THEN buffer := buffer + ' RONLY' ; IF ( aux_class1 IN class ) THEN buffer := buffer + ' AUX_CLASS1' ; IF ( aux_class2 IN class ) THEN buffer := buffer + ' AUX_CLASS2' ; IF ( buffer = '' ) THEN show_reg_class := ' STANDARD' ELSE show_reg_class := buffer ; END ; { *************************************************************************** } { *************************************************************************** } END .