Anyone have any details of what a "translated source string" means in this context?
Well, that's the destination buffer (string) filled with data from a source buffer (string) like in a move, but each byte translated using a translation table before being stored.
Like having an ASCII data (source string) translated to EBCDIC (translated source string).
MOVTC works much like the /370 instruction Translate (TR). Except it not only translates a series of bytes, but also moves it to a new destination (*1).
SrcLn - Length of data within the source buffer
SrcBuffer - Address of source buffer
Filler - Byte to fill the destination buffer
Table - Translate table
DestLen - Length of destination buffer
DestBuffer - Address on destination buffer
During operation each byte from the source buffer is used as an index into the translation table. The byte pointed to will be stored at the destination buffer. If DestLen is longer than SrcLen, the remaining destination buffer is filled with the Filler byte. If DestLen is shorter, then the operation is ended after DestLen translations.
In either case the condition code is set to reflect
- all translated
- DestBuffer too short
- Filling was used.
In addition, various registers contain
- First source byte not translated
- Address after Destination buffer
- Number of bytes remaining in source buffer
The Table is an up-to-256-byte structure holding the destination encoding at the address of the source encoding. For example an ASCII to EBCDIC table would have:
Table+65 = X'C1' ;A
Table+66 = X'C2' ;B
Table+67 = X'C3' ;C
Table+68 = X'C4' ;D
and so on.
Translation of byte strings is a very handy feature for code conversion, for example ASCII to EBCDIC for line code to internal, For between various line codes. In addition it's a very handy instruction to check character types and flags (*2) or for native implementation of decision tables (*3) or many other uses.
Not only has the /360 included it since the 1960s, but so has 8086 in the form of the XLAT instruction - which is part of the string instructions. A simple equivalent with source/destination length in 8086 is a loop of just 4 instructions:
*1 - MOVETC with source and destination at the same address would be exactly like TS. Amdahl had only two address fields, while DEC could make up as many as they wanted, so why not offer the freedom of moving at the same time.
*2 - Type checking like if a character is a letter or numeral is often done in code and is codeset dependent. The original implementation for C's
isalpha as Macro looked a bit like:
#define isalpha(ch) ( (ch) <= 'Z' && (ch) >= ('A') || ((ch) >= 'a') && ((ch) <= 'z') )
This will break with any code not having A..Z and a..z in consecutive places and/or providing additional letters - like EBCDIC or ISO8859. Now one can turn the macro into a function and make it compile differently depending on codeset, or build a sophisticated run time system selecting what checks are appropriate ... or simply keep for each code to be handled as a 256-byte table with a testable value like
- 2^0 -> Upper
- 2^1 -> Lower
- 2^2 -> Numeric
- 2^3 -> Punctuation
- 2^4 -> Whitespace
- 2^5 -> Control
isalpha is reduced to a test for (2^0 OR 2^1) independent of the codeset used. Even better, whole strings can be tested at once by ANDing or ORing all translated characters. When ANDed, the markers are only set where all characters have the same attribute, like numeric (2^2) is only set if all characters entered are numeric. When ORed, they are set when any of them has that attribute, like for the dreaded checking if a password contains Upper and lower and numeric and symbols.
So, VERY handy.
*3 - Decision Tables are a very handy tool to structure logic with reactions depending on arbitrary combinations of multiple input items. Code translation is a way to implement such logic native and extremely performant - at least as long as there are no more than 8 input and 8 output conditions.