MS-DOS 6.22 variable trimming

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
cajunjon
Posts: 2
Joined: 01 Apr 2021 09:10

MS-DOS 6.22 variable trimming

#1 Post by cajunjon » 01 Apr 2021 11:00

I inherited a legacy MS-DOS 6.22 project which has an app that reads a CPU's IA32_PERF_STATUS Register, MSR 0x198, which then outputs a HEX value. I need to trim off everything right and left of the 29th and 30th characters (24 in this output). The outputted values will be different for different model CPU's.
I then need to convert that value to Decimal. The code below works in Windows but not in MS-DOS 6.22.
Here's what I tried without the HEX2DEC conversion. I found a MS-DOS 16bit HEX converter app at http://blog.code-cop.org/2008/07/dos-tools.html that can do the conversion as well.

@echo off
rdmsr.exe 0x198 > 198.txt
rem Expected output is "CPU_0 APIC_0 MSR 0x0198 = 0x24AB24AB 0x240024AB"
for /F "tokens=*" %%A in (198.txt) do set string=%%A
set /A perf=%string:~17,2%
@echo %perf%c

Any help would be appreciated.

jeb
Expert
Posts: 979
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: MS-DOS 6.22 variable trimming

#2 Post by jeb » 02 Apr 2021 06:23

Hi cajunjon,

you could split your problem into smaller problems and use some helper files.

The list of your problems
  1. You need to assign the program output to a variable
  2. Split a string into parts
  3. substring works only for strings without spaces or other delimiters
  4. A variable can't contain an equal sign (or I don't know how to assign it)
Problem 1 is easy to solve with a file containing only "SET var=" without any line feeds, see READ.BAT
call READ.BAT 198.txt line

Problem 2 can be solved with SUBSTR.BAT (requires INC.BAT)

Code: Select all

call READ.BAT 198.txt str
call SUBSTR.BAT 29 2 resutl
Problem 3 can be solved, if you take only the 5th word of your string by using a simple FOR loop, see SPLITSTR.BAT

Code: Select all

call READ.BAT 198.txt str
call SPLITSTR strparts
set str=%strparts[4]%
call SUBSTR.BAT 2 2 result
echo %result%
Only problem4 isn't solved yet, but the solution should be obvious :D

SUBSTR.BAT

Code: Select all

@echo off
rem Extract a substring from a string 
rem The input string has to be stored in "str"
rem @base index of the first character, 0 is the first
rem @length Take @length characters from index or stop at the string end
rem Usage: call substr @base @length @returnvar
rem Sample: call substr 2 6 result

for %%L in (/%0) do if "%%L"=="/" goto %1

:main
call %0// :split %1
set str=%_right%
call %0// :split %2
if "%3"=="" echo ["%_left%", "%_right%"]
if "%3"=="" goto :clear
set %3=%_left%

:clear
REM Clear temp vars
FOR %%v in (_left _right _idx _splitpos _finish _remain) do set %%v=
goto :eof

:split
if NOT %2==0 goto :process
  set _left=
  set _right=%str%
goto :eof

:process
set _left=
set _right=
set _idx=1
set _splitpos=%2
set _finish=0
set _remain=%str%

:loop
set _first=1
FOR %%a in (/%_remain%) DO call %0// :split_char %%a
if %_finish%==1 goto :eof
if NOT "%_remain%"=="" goto :loop
goto :eof

:split_char
if "%_first%"=="" goto :_second
if %_idx%==%_splitpos% set _finish=1
set _left=%_left%%2
call inc %_idx% _idx
set _first=
set _remain=
goto :eof

:_second
set _remain=%2
if %_finish%==1 set _right=%2
goto :eof

:eof
INC.BAT

Code: Select all

@echo off

for %%L in (/%0) do if "%%L"=="/" goto %1

REM Split and reverse number into _valueRev
set _remain=%1
set _valueRev=

:split_loop
set _loop=1

for %%a in (/%_remain%) do call %0// :split %1 %%a
if NOT "%_remain%"=="" goto :split_loop
goto :increment

:split
if %_loop%==2 goto :split_2
set _loop=2
set _remain=
set _valueRev=%3,%_valueRev%
goto :eof

:split_2
set _remain=%3
goto :eof

REM The main increment function
:increment
set _incresult=
set _carry=1
for %%d in (%_valueRev%) do call %0// :incDig %%d
if not "%_carry%"=="" call %0// :incDig 0

if NOT "%2"=="" set %2=%_incresult%
REM Clear temp vars
FOR %%v in (_incresult _carry _loop _valueRev _valueRev_comma _digit _remain) do set %%v=
goto :eof

:incDig
set _digit=%2
if "%_carry%"=="" goto :endinc
set _carry=
if %2==9 set _digit=0
if %2==9 set _carry=1
if %2==8 set _digit=9
if %2==7 set _digit=8
if %2==6 set _digit=7
if %2==5 set _digit=6
if %2==4 set _digit=5
if %2==3 set _digit=4
if %2==2 set _digit=3
if %2==1 set _digit=2
if %2==0 set _digit=1

:endinc
set _incresult=%_digit%%_incresult%
:eof
READ.BAT

Code: Select all

@echo off

type READ.HLP > TMP.BAT 
TYPE %1 >> TMP.bat
call TMP.bat
del tmp.bat
set %2=%_read%
set _read=
READ.HLP

Code: Select all

SET _read=
SPLITSTR.BAT

Code: Select all

@echo off
rem Splits a string into parts by the standard delimiters
rem The input string has to be stored in "str"
rem @returnvar Name of the variable array to return 

rem Usage: call SPLTSTR.BAT result
rem Example for: str=Hello world, how are you
REM Output: 
REM result[0]=Hello
REM result[1]=world
REM result[2]=how
REM result[3]=are
REM result[4]=you

for %%L in (/%0) do if "%%L"=="/" goto %1

:main
set _idx=0
set _varname=%1
FOR %%W in (%str%) DO CALL %0// :store %%W

:clear
REM Clear temp vars
FOR %%v in (_idx _varname) do set %%v=
goto :eof

:store
set %_varname%[%_idx%]=%2
call INC.BAT %_idx% _idx
:eof

cajunjon
Posts: 2
Joined: 01 Apr 2021 09:10

Re: MS-DOS 6.22 variable trimming

#3 Post by cajunjon » 09 Apr 2021 12:43

Jeb,
Wow. I see why your title is expert! Thanks for the help. I'm offsite for a few weeks so I'll have to make the changes when I get back.
-Cajunjon

Post Reply