Help with c code (bit reversal)

This sounds like Radix-50 encoding, there should be some resources with code examples out there to leverage.

Radix-50 was suggested on the other thread and I think, I haven’t tried that one, yet. I found that that wasn’t used on PDP-8 and according wikipedia it’s 36, 18 or 16 bits. (16 bits is possible).
I also found a Radix-40 (or was it 45? but could be the same as 50o is 40 in dec) eg. three chars per 16-bit word.
I can’t test this as character set with representation of one byte. So I would need a conversion code.

After 10 hours work of trying the 2/3 encoding (see above) on c with many errors, I tried it to be very simple.
That is my final result. Reading of 3 bytes worked. No errors, no warnings. But the output is wrong. I also tried printf %4d (needs to be 12 bits). 13 3D 18 should be 0423 4075. Who can help? Is there a conversion missing? Or can’t it be done this way at all?

printf("%02x %02x %02x\n", (int) buf[0], (int) buf[1], (int) buf[2]);
      
      temp[0] = (buf[2] << 4 | buf[0] >>8) ;
      temp[1] = (buf[2] >> 4 | buf[1] >>8) ;
      printf("%04o %04o\n", (int) temp[0], (int) temp [1]);

The original code is this (the other way). Not plausible to me

if (block % 5 == 0) {
            printf("Block %d\r",block);
            fflush(stdout);
         }
      }
         /* Send 2 words as 3 bytes */
      chksum += temp[0] + temp[1];
      buf[0] = temp[0];
      buf[1] = (temp[0] >> 8) | (temp[1] << 4);
      buf[2] = (temp[1] >> 4);
      ser_write(fd,(char *)buf,3);

Update: Radix 50:
Here’s a conversion code

-Intro to System Software, Chapter 3

Here it says that it was only used for filenames

-draft-ray-radx-00

A codetable

First Second Third First Second Third
char char char char char char
Space 000000 000000 000000 T 076400 001440 000024
A 003100 000050 000001 U 101500 001510 000025
B 006200 000120 000002 V 104600 001560 000026
C 011300 000170 000003 W 107700 001630 000027
D 014400 000240 000004 X 113000 001700 000030
E 017500 000310 000005 Y 116100 001750 000031
F 022600 000360 000006 Z 121200 002020 000032
G 025700 000430 000007 $ 124300 002070 000033
H 031000 000500 000010 . 127400 002140 000034
I 034100 000550 000011 Unused 132500 002210 000035
J 037200 000620 000012 0 135600 002260 000036
K 042300 000670 000013 1 140700 002330 000037
L 045400 000740 000014 2 144000 002500 000040
M 050500 001010 000015 3 147100 002450 000041
N 053600 001060 000016 4 152200 002520 000042
O 056700 001130 000017 5 155300 002570 000043
P 062000 001200 000020 6 160400 002640 000044
Q 065100 001250 000021 7 163500 002710 000045
R 070200 001320 000022 8 166600 002760 000046
S 073300 001370 000023 9 171700 003030 000047

Next to the above problem in c coding, I tried a RAD50 conversion.

int i;
int* c1, c2, c3;
printf("%02x %02x %02x\n", (int) buf[0], (int) buf[1], (int) buf[2]);
      
      c1 = (buf[0]);
      c2 = (buf[1]);
      c3 = (buf[2]);
      void unpack( int i, char* c1, char* c2, char* c3 ) /*original code */
      {  *c1 = ascii(i / (40*40));         /*original code */
         *c2 = ascii((i /40) % 40);
         *c3 = ascii(i %40);
         printf("%s %s %s\n", c1, c2, c3);

Now, I don’t have any warnings; but the output is empty.
I know that *c1 is a pointer. Not sure how to declare it c1 or *c1 (int, *int, char, *char). I think I’ve tried everything. Or should it be an array?
I’m also not sure how the input should be. I want to unpack the rad50 stored as characters in 3 bytes. Or is that packing? (I’ve also tried this.)
And the RAD50 value can be 6, 5 and less digits down to 1 like ‘0’ as shown on an RT-11 directory header.

Edit: The output should be up to 3 characters from an unknown amount of digits (1-6) derived from 2 bytes (16 bit)? Both packing and unpacking routines have an input of 3 characters. Maximum rad50 is 63999 (dec?) from input 9 9 9.
SWA= 75131. P=62000, 1XM= 142615, space=0. Obviously these are octal values added depending on their position from table above.

Can someone please help me with both problems?

I have manually decoded mnemonic LAD = 45454o = 4B2C hex. I’ve searched all my ROM combination without any result. So RAD50 is obviously out.

The 2/3 encoding can’t also be the case on my original file (without cross merging) as no Hex value is above 3F. But I do assume cross merging.
Another way is that every single ROM is already merged from 2 half sections, but 16 ROMs are unlikely, rather 4 or 2. Maybe each ROM is flipped/inverted?

Another progress, from another approach.
I’ve checked again in the manual how the printouts work. There are 3 kinds of printouts, all starting with different characters, probably from German terms.
/S (done by the PLC, but my device maybe can do that as well in remote-control mode) different widths, PLC also can print comments
/D (memory dump without mnemonics)
/L (reverse assembly list with mnemonics) like this

/L 00000-00003 S: 0000176022
00000: 011001 .WENN ESB EAS 1

Top: start and end addresses (octal) then S: and a checksum, probably just the right 6 digits
Below: Adress (octal), Festo instruction (octal), mnemonics, some with operands/adresses (some values are decimal eg counters).

I found all 3 /S/D/L characters and S: in my first (non-cross merged) file (after having it fixed twice) and values pointing to that locations.
One string is like this
/L X: X: X, ;C US DL. (if x is a placeholder for 00000 than that’s it, US and DL probably not involved).

The printout is sent as 7 bit ASCII (slightly different than DIN standard for the parity bit). I think the 6100 CPU has an implementation for conversion.
I wonder how this mixed line of Sixbit encoded characters, octal and decimal digits and probably other encoded characters work.

The pdp8 code of this file is not that plausible when starting at 0 or 200. But more plausible when starting at the address stored in word 0.
And that file just has 12 bit values stored in the bytes. Still unclear the 2 empty sections and the missing mnemonics.

I have checked another 16 combinations without success. 4321+8765 (to have the empty bytes at the beginning/end) and 1357+2468.
I found strings like ABCDEHOPQ)RUVW, and QRSUVXYZ[/] (). Some characters are missing, so probably the character set is wrong.

As I’ve tried dozens of plausible combinations, I think I would need the 9th ROM.
That has 4096 bits (0-7777 octal), so 1 bit for each of the words. But I’d rather expect code there, so 256 words or just 200.
That is the amount of empty bytes and also the index vectors before the start at 200.

But why using 9 ROMs when you can have the same in 8? Maybe bootstrapping or encryption including opcodes.
There are also many other start addresses like 6000, or 400,800 etc usually set by jumpers. And the vectors. So there are hundreds of code combinations.

I found this interesting site about PDP 8/A boot ROMs.
There are 4x4 bits read from a pair of 2 ROMs making 16 bits for encoding instructions.
12
||
XC
BA
There is also a c code parse-boot by Anders Sandahl (pdp-9 net) combining 2 ROMs (256 bytes each, not words).
An output looks like this

0000 0000 :A : 175144
0002 0002 :AED 0137770 : 137770
0004 0004 :AED 6127356 : 127356
0006 0006 :A : 174673
0008 0010 :AE : 127770
000a 0012 :AE : 7673
000c 0014 :A : 176121
000e 0016 :A DS 3127770 : 127770
0010 0020 :A : 5375

A= load Address, E=load ext. adr., D=deposit op, S=start oper.; Ext Adr, Address

https://www.retrotechnology.com/restore/8a_roms.html

I don’t have 16 bits and no control nybble. Obviously it’s empty on my 8 ROMs. But obviously ROM pairs were usual (same on SBC6120). And bytes and/or words are reversed.

I now consider again dumping of this fuse-link bipolar PROM, or maybe just display the bits on LEDs and write down 400 bytes by hand.
Maybe it’s just a short BIN loader.
Any thoughts?

I found some great Perl tools including a sixbit conversion. I found that site before, but never checked the tools (but papertapes).

https://so-much-stuff.com/pdp8/tools/tools.php

The sixbit output is different than from the online emu. Also some characters are different. And showing more characters and it’s very easy to identify larger sections of text. I can read T@APE, maybe a coincidence. The short section is from the online emu showing 2 columns. The 2 rows below are from CHEKMO chess. The string CHECKMATE WITH is harder to identify as it only uses one column.

Unfortunately, I haven’t found anything of interest on my files.
I haven’t checked all tools, yet. There should also be the 3 for 2 conversion (OS/8 disk ?).
One interesting thing is bin2c (quick pdp8 to c conversion).

0022 170)17400 14077 37417 0050 0053 25413 0077 17477 |@`?�O@(@+�K@?|?

0023 000)37406 22064 7413 5465 22046 3465 32037 32440 �F�4<K,5�&\5�_�
0023 010)23046 32046 17413 5444 32444 17425 22046 22044 �&�&|K,$�$|U�&�$
0023 020)22042 12446 22077 32444 20065 22037 3425 22037 �"T&�?�$�5�_\U�_
0023 030)22037 12444 22044 32446 3467 22046 32064 23046 �_T$�$�&\7�&�4�&
0023 040)0015 22006 21046 32446 17467 22065 32460 17444 @M�F�&�&|7�5�0|$
0023 050)17425 37464 14037 37443 6014 3070 6014 3006 |U�4`_�#0LX80LXF
0023 060)2402 32416 3006 6014 3065 33414 3006 2067 TB�NXF0LX5�LXFP7
0023 070)6064 3067 6004 3006 3006 3006 36456 4005 04X70DXFXFXF�. E
0023 100)4010 12016 2424 14406 6404 13006 5404 13026 HPNTTdF4DXF,DXV
0023 110)16436 7026 10024 10001 12005 15004 17034 16025 t^8V@T@APEhDx\pU
0023 120)3034 12416 15025 5404 7032 13031 6035 10020 X\TNhU,D8ZXY0]@P
0023 130)5413 10010 24461 10020 22471 10020 2011 10004 ,K@H�1@P�9@PPI@D
0023 140)21410 14431 3063 6031 4425 17024 5420 15032 �HdYX30Y$UxT,PhZ
0023 150)5413 14432 12011 7013 6404 12024 7024 12025 ,KdZPI8K4DPT8TPU
0023 160)4431 13024 16406 6413 7011 16431 0004 7000 $YXTtF4K8ItY@D8@
0023 170)25016 2431 23007 3452 0444 23067 0046 0051 �NTY�G*D$�7@&@)

0024 000)23041 22044 23041 32044 23007 3444 20407 0044 �!�$�!�$�G$�G@$
0024 010)22025 2442 22044 23025 12444 23025 12425 22044 �UT"�$�UT$�UTU�$
0024 020)22065 33444 23046 33444 7407 30054 32047 7475 �5�$�&�$<G�,�’<=

04600 0677 F> | a4600, AND I M4677
04601 6444 3$ | a4601, IOT 0444
04602 1317 KO | a4602, TAD M4717
04603 6513 4K | a4603, IOT 0513
04604 4644 &$ | a4604, JMS I C4644
04605 6507 4G | a4605, IOT 0507

04705 0626 FV | a4705, AND I M4626
04706 0413 DK | a4706, AND I M13
04707 2626 VV | a4707, ISZ I M4626
04710 3635 ^] | a4710, DCA I M4635
04711 2616 VN | a4711, ISZ I M4616
04712 2420 TP | a4712, ISZ I M20
04713 0120 AP | a4713, AND M120
04714 0524 ET | a4714, AND I M124
04715 0432 DZ | a4715, AND I M32
04716 3436 ^ | a4716, DCA I M36

0026 120)1403 1410 1405 1403 1413 1415 1401 1424 LCLHLELCLKLMLALT
0026 130)1005 1440 1427 1411 1424 1010 0040 65000 HEL LWLILTHH@ �@

Earlier, I found Radix 45, not 40 ot 50. But that should be only internally on a PAL assembler. No or very few results on Google.

After having written a simple disassembler, I can now confirm my assumption (if I got this right)

It depends on the instruction.
An IF (WENN) statement can only check for 0 or 1 signal (so digit 2 has 0 or 1).
A THEN (DANN) statement has 2, 3 or 4 at digit 2 (delete, set or load).
5, 6 or 7 at digit 2 are operands of the THEN statement (load with contents, with address, with decimal) appears on a 3rd line if any.

The last 4 digits can be part of a special instruction (OR, brackets), a device number or operand. Same values can only be 0-3 others 0-7.
Important is the 2nd digit.
And as written elsewhere, it’s easier to check from the highest values. So maybe they are stored in the ROM by numbers backwards.

One can not only check the input card for 0/1 signal, but also other hardware bits, like error channel, or for too high voltage/temperature etc.

I also found (on error codes) that at least the PLC (obviously same CPU) starts at 0 after reset/power failure. So I assume that my device starting at 0 as well.