$include (..\lib\compStch.ext) /* *============================================================================ * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE * * Permission to use for any purpose, modify, copy, and make enhancements * and derivative works of the software is granted if attribution is given to * R.M. Gillmore, dba the ACME Software Deli, as the author * * While the ACME Software Deli does not work for money, there is nonetheless * a significant amount of work involved. The ACME Software Deli maintains the * rights to all code written, though it may be used and distributed as long as * the following conditions are maintained. * * 1. The copyright statement at the top of each code block is maintained in * your distribution. * 2. You do not identify yourself as the ACME Software Deli * 3. Any changes made to the software are sent to the ACME Software Deli *============================================================================ */ debugHelpersModule: do; $if not noID declare IDString (*) byte data ( '@(#)debugHlp.p86 $Author: rmgillmore $ $Date:: 2025-05-04 19:35:39#$:', 0 ); $endif $include (..\lib\comnDefs.ext) $include (..\lib\sysCalls.ext) $include (..\lib\string.ext) $include (..\lib\fileIO.ext) $include (..\lib\numStrs.ext) $include (..\lib\ctype.ext) $include (..\lib\ptrMath.ext) $set (DEBUGHLP_IMPLEMENTATION) $include (..\lib\debugHlp.ext) $set (reportTheLines) declare eolString pointer data ( @( CR, LF, 0 ) ); reportVarValue: procedure ( varNameString, varType, varAddress ) reentrant public; declare varNameString pointer, varType numberReportType, varAddress pointer; declare reportString ( 130 ) char; call varToString( varAddress, varType, varNameString, @reportString ); call printStringAsciiZ( @reportString ); call printStringAsciiZ( eolString ); end reportVarValue; reportLine: procedure ( dataLocation, interpretLocationAsAddress, varType, numberElements, dataAddress ) reentrant; declare dataLocation dword, dataLocationPtr pointer at ( @dataLocation ), interpretLocationAsAddress boolean, varType numberReportType, numberElements word, dataAddress pointer, byteArray based dataAddress (*) byte, wordArray based dataAddress (*) word, dwordArray based dataAddress (*) dword; declare INDEX_REPORTED_AT literally '0', VALUES_START_AT literally '12', ASCII_START_AT literally '63', /* this must be long enough to handle 16 bytes (either as words or bytes), * plus the ASCII for each BYTE */ NUMBER_CHARS_PER_LINE literally '80'; declare valueString ( NUMBER_CHARS_PER_LINE ) char, stringIndex word, dataIndex word, hyphenIndex word, valueWidth word; /* * initialize the string */ call memset( @valueString, ' ', NUMBER_CHARS_PER_LINE - 1 ); valueString( NUMBER_CHARS_PER_LINE - 1 ) = NUL; /* * tell us where we are */ if ( interpretLocationAsAddress ) then do; call pointerToHexString( dataLocationPtr, @valueString( INDEX_REPORTED_AT ) ); valueString( 9 ), valueString( 10 ) = ' '; end; else do; call dwordToHexString( dataLocation, @valueString( INDEX_REPORTED_AT ) ); valueString( 8 ), valueString( 9 ) = ' '; end; dataIndex = 0; stringIndex = VALUES_START_AT; if ( varType = byteType ) then do; hyphenIndex = VALUES_START_AT + 23; valueWidth = 2; end; else if ( varType = wordType ) then do; hyphenIndex = VALUES_START_AT + 19; valueWidth = 4; end; else if ( varType = dwordType ) then do; hyphenIndex = VALUES_START_AT + 17; valueWidth = 8; end; do while ( dataIndex < numberElements ); if ( varType = byteType ) then do; call byteToHexString( byteArray( dataIndex ), @valueString( stringIndex ) ); if ( isprint( signed( byteArray( dataIndex ) ) ) ) then valueString( ASCII_START_AT + dataIndex ) = byteArray( dataIndex ); else valueString( ASCII_START_AT + dataIndex ) = '.'; end; else if ( varType = wordType ) then call wordToHexString( wordArray( dataIndex ), @valueString( stringIndex ) ); else if ( varType = dwordType ) then call dwordToHexString( dwordArray( dataIndex ), @valueString( stringIndex ) ); valueString( stringIndex + valueWidth ) = ' '; valueString( stringIndex + valueWidth + 1 ) = ' '; stringIndex = stringIndex + valueWidth + 1; dataIndex = dataIndex + 1; end; /* while data to represent */ valueString( hyphenIndex ) = '-'; call printStringAsciiZ( @valueString ); call printStringAsciiZ( eolString ); end reportLine; reportBlockValues: procedure ( varNameString, varType, arrayLength, varAddress ) reentrant public; declare varNameString pointer, varType integer, arrayLength word, varAddress pointer; declare arrayIndex word, varDataBytes based varAddress (*) byte, varDataWords based varAddress (*) word, varDataDWords based varAddress (*) dword; /* * MAX_NUM_BYTES_RPTD_PER_LINE == maximum number bytes reported per line */ declare MAX_NUM_BYTES_RPTD_PER_LINE literally '16', MAX_NUM_WORDS_RPTD_PER_LINE literally ' (MAX_NUM_BYTES_RPTD_PER_LINE / 2)', MAX_NUM_DWORDS_RPTD_PER_LINE literally ' (MAX_NUM_BYTES_RPTD_PER_LINE / 4)'; /* * write the variable name or comment */ call printStringAsciiZ( varNameString ); call printStringAsciiZ( eolString ); arrayIndex = 0; stillDataToReport: do; declare numberElements word; do while ( arrayIndex < arrayLength ); if ( varType = byteType ) then do; if ( ( arrayIndex + MAX_NUM_BYTES_RPTD_PER_LINE ) < arrayLength ) then numberElements = MAX_NUM_BYTES_RPTD_PER_LINE; else numberElements = ( arrayLength - arrayIndex ); call reportLine( ptdw( @varDataBytes( arrayIndex ) ), TRUE, varType, numberElements, @varDataBytes( arrayIndex ) ); end; else if ( varType = wordType ) then do; if ( ( arrayIndex + MAX_NUM_WORDS_RPTD_PER_LINE ) < arrayLength ) then numberElements = MAX_NUM_WORDS_RPTD_PER_LINE; else numberElements = ( arrayLength - arrayIndex ); call reportLine( ptdw( @varDataWords( arrayIndex ) ), TRUE, varType, numberElements, @varDataWords( arrayIndex ) ); $if reportTheLines call reportLine( arrayIndex, FALSE, varType, numberElements, @varDataWords( arrayIndex ) ); $endif end; else if ( varType = dwordType ) or ( varType = pointerType ) then do; if ( ( arrayIndex + MAX_NUM_DWORDS_RPTD_PER_LINE ) < arrayLength ) then numberElements = MAX_NUM_DWORDS_RPTD_PER_LINE; else numberElements = ( arrayLength - arrayIndex ); call reportLine( ptdw( @varDataDwords( arrayIndex ) ), TRUE, varType, numberElements, @varDataDwords( arrayIndex ) ); $if reportTheLines call reportLine( arrayIndex, FALSE, varType, numberElements, @varDataDWords( arrayIndex ) ); $endif end; else do; /* * if we get here, the varType is not supported, so essentially * do nothing */ numberElements = arrayLength; call printStringAsciiZ( @( 'specified report type not supported', 0 ) ); end; arrayIndex = arrayIndex + numberElements; end; /* while there is more data */ end stillDataToReport; call printStringAsciiZ( eolString ); end reportBlockValues; end debugHelpersModule;