08-03-2020, 08:34 AM
I wrote a small HP-49G RPL program to test a Tektronix vector graphics terminal emulator (which I would normally use with a CP/M or MS-DOS system) – but why not with a graphing calculator?
The Tektronix terminals expect each pair 12-bit integer x-y- coordinates [0…4095] in a specific format as a sequence of 5 printable characters with the following bit patterns:
Input
Output
Because the conversion has to be performed for each data point I would like to have it fast.
I wrote several version of the conversion subroutine
Variant 3 and 4 were slowest and made no difference in speed. Version 2 using the stack was slightly faster than version 1 with the local variables. So currently version 2 is my favorite. Do you see more options to speed up the code without reverting to SysRPL or other heavy tricks?
On entry to my routine TEKXY the X and Y coordinates are on the stack. In my example the ranges are X=[0…400], Y=[0…2]. Therefore Y is scaled by 1500 and X by 10 to map approximately to the 12 bit range [0…4095]. The output of the routine is a 5 character string.
Example:
Code of variant 2 (line breaks added to show scaling, composition of the bytes 1…5 and, final cleanup).
The first scaling step leaves X and Y swapped on the stack so that the PICKs use this stack layout:
The Tektronix terminals expect each pair 12-bit integer x-y- coordinates [0…4095] in a specific format as a sequence of 5 printable characters with the following bit patterns:
Input
Code:
X: X12.X11.X10.X9.X8.X7.X6.X5.X4.X3.X2.X1
Y: Y12.Y11.Y10.Y9.Y8.Y7.Y6.Y5.Y4.Y3.Y2.Y1
Code:
Byte1: 0.0.1.Y12.Y11.Y10.Y9.Y8
Byte2: 0.1.1.0.Y2.Y1.X2.X1
Byte3: 0.1.1.Y7.Y6.Y5.Y4.Y3
Byte4: 0.0.1.X12.X11.X10.X9.X8
Byte5: 0.1.0.X7.X6.X5.X4.X3
I wrote several version of the conversion subroutine
- using real numbers and local variables for X and Y
- using real numbers with X and Y on the stack
- using binary integers (with default 64 STWS) and local variables
- using binary integers (with 12 STWS) and local variables
Variant 3 and 4 were slowest and made no difference in speed. Version 2 using the stack was slightly faster than version 1 with the local variables. So currently version 2 is my favorite. Do you see more options to speed up the code without reverting to SysRPL or other heavy tricks?
On entry to my routine TEKXY the X and Y coordinates are on the stack. In my example the ranges are X=[0…400], Y=[0…2]. Therefore Y is scaled by 1500 and X by 10 to map approximately to the 12 bit range [0…4095]. The output of the routine is a 5 character string.
Example:
Code:
2: 123 note: X
1: 1 note: Y
‘TEKXY’ EVAL
1: “+bw)S”
Code of variant 2 (line breaks added to show scaling, composition of the bytes 1…5 and, final cleanup).
The first scaling step leaves X and Y swapped on the stack so that the PICKs use this stack layout:
Code:
1: Y
2: X
Code:
'TEKXY'
<< 1500. * SWAP 10. *
2. PICK 128. / IP 32. MOD 32. + CHR
PICK3 4. MOD 4. * PICK3 4. MOD + 96. + CHR +
PICK3 4. / IP 32. MOD 96. + CHR +
2. PICK 128. / IP 32. MOD 32. + CHR +
SWAP 4. / IP 32. MOD 64. + CHR +
SWAP DROP
>>