INPUT DC X'A0B1C2D3',X'12'
OUTPUT DC CL8' ',C' '
HEXTAB EQU *-C'0'
The first sentence in the description of the UNPK instruction reads
Most of us think we have a pretty good understanding of packed decimal data, and most of us have a vague understanding of zoned decimal data. If we look at the data the first operand of the UNPK instruction points to, it is immediately obvious it is not packed decimal data!The format of the second operand is changed from packed to zoned, and the result is placed at the first-operand location.
Part of what's happening lies in this nearly unnoticeable sentence later on in the description of UNPK. "The sign and digits are not checked for valid codes." Huh!? What is this d****** thing doing!? Also, the UNPK instruction is listed in the section of the manual labeled "General Instructions," rather than the "Decimal Instructions" section. In the original System/360 this was an important distinction. In the lower end machines the decimal instructions were an optional feature, and IBM charged a hefty fee to have them in the machine. The reality is UNPK is not a "decimal" instruction. I think of it as a bit twiddler instruction.
Look at the data carefully. You will notice the input contains 4 bytes followed by a mystery byte, and the output contains 8 bytes, followed by a mystery byte, and the UNPK instruction deliberately includes the mystery. Now let's dredge up our understanding of packed decimal data. Most of a packed decimal data area consists of 4 bit digits containing bit codes 0000 (0) through 1001 (9). The first 4 bits in the last byte contain a 4 bit digit code followed by a 4 bit sign code containing bit codes 1010 through 1111. So it would seem the mystery byte in our binary data is the last byte of a pseudo packed decimal data area. So, we're going to do something or other with this byte, but it's not really going to be part of our real output.
If we work through the description of UNPK in Principles of Operation - it's pretty hard going - we will find that except for the last byte, each input byte creates two output bytes. The first 4 bits of each byte are 1111, and remaining 4 bits are from the data area. With our sample data, the first two bytes in the output area contain X'FAF0'.
The first paragraph of the description of the TR instruction reads
This is pretty opaque, especially given the way HEXTAB is defined in our example. The third and fourth paragraphs in the description provide more detail, but they are still pretty opaque.The bytes of the first operand are used as eight-bit arguments to reference a list designated by the second-operand address. Each function byte selected from the list replaces the corresponding argument in the first operand.
So let's try to make things clearer.
- Not stated, but it can readily be deduced, the table referenced by the second argument contains 256 bytes.
- The HEXTAB label in our example program defines what amounts to a virtual start of the table. We can do this because there is no data in the first operand that references relative bytes X'00' through X'EF' in the table.
- The first byte in the output area references the byte at HEXTAB+X'FA', which if you do your arithmetic, turns out to be C'A', so the instruction replaces X'FA' with C'A'.
- The second byte in the output area is X'F0', so it references the byte at HEXTAB+X'F0', which is C'0', so the instruction replaces X'F0' with C'0'. You can figure out what the remaining bytes become yourself.