Topics

#fst4 packtext77 / mp_short_ops subroutines #FST4


Andy TALBOT
 

Help I'm tearing my hair out :-(
Trying to understand the plain text encoding, the 'packtext77' routine  in the 'packjt77' module. and getting totally flummoxed by the mp_short ops.   Specifically ...init, ...add and ...mult which are needed in the packing process.

I have the Fortran manual to hand;  the equivalence statement makes sense, interpreting the same memory space as either integers and characters.

But what it's actually doing doesn't seem to make sense
I'm guessing the 'mp' start of the subroutine name stands for "multiple precision"?Only a guess, but it makes sense in context of the packing process.

Can someone help and explain in plain English what the packtext77 routine is actually doing.   Or , at least what those mp_short bits are doing - the code that calls them seems obvious enough.

Backgroud :
I want to write my own code, in my programming language of choice, for generating the symbols for a small subset of FST4 / FST4W messages.    Specifically WSPR type 1,  Telemetry and plain text messages.  Those are the only three I'm interested in.
I currently have the first two sorted but totally lost on plain text.

Was pleased at how simple the encoding process was;  I get symbol sets that agree perfectly with those generated from FST4SIM for WSPR Type 1 and Telemetry format messages.   Missed the rvec scrambling at first, but spotted it just before asking here why my results were total rubbish.

Hoping it may be possible to do the encoding in a PIC, but it'll have to be one with plenty of program memory to hold the parity generating tables.   Apart from that memory aspect, it looks to be  simpler than encoding JT4/JT9 in a PIC processor.


Bill Somerville
 

On 07/04/2021 17:37, Andy TALBOT wrote:
Help I'm tearing my hair out :-(
Trying to understand the plain text encoding, the 'packtext77' routine  in the 'packjt77' module. and getting totally flummoxed by the mp_short ops.   Specifically ...init, ...add and ...mult which are needed in the packing process.

I have the Fortran manual to hand;  the equivalence statement makes sense, interpreting the same memory space as either integers and characters.

But what it's actually doing doesn't seem to make sense
I'm guessing the 'mp' start of the subroutine name stands for "multiple precision"?Only a guess, but it makes sense in context of the packing process.

Can someone help and explain in plain English what the packtext77 routine is actually doing.   Or , at least what those mp_short bits are doing - the code that calls them seems obvious enough.

Backgroud :
I want to write my own code, in my programming language of choice, for generating the symbols for a small subset of FST4 / FST4W messages.    Specifically WSPR type 1,  Telemetry and plain text messages.  Those are the only three I'm interested in.
I currently have the first two sorted but totally lost on plain text.

Was pleased at how simple the encoding process was;  I get symbol sets that agree perfectly with those generated from FST4SIM for WSPR Type 1 and Telemetry format messages.   Missed the rvec scrambling at first, but spotted it just before asking here why my results were total rubbish.

Hoping it may be possible to do the encoding in a PIC, but it'll have to be one with plenty of program memory to hold the parity generating tables.   Apart from that memory aspect, it looks to be  simpler than encoding JT4/JT9 in a PIC processor.

Hi Andy,

the routines pack ASCII character strings of a limited alphabet (the 42 characters in the variable c) into a base 42 number. mp_short_init is an Endian detector so that the packing and unpacking works the same on big and little Endian platforms. An output register (qa) is initialized to zero, then successively multiplied by 42, then the next of the 13 free text characters, mapped to an index between 0 and 41, is added, and so on; to create a long base 42 number unique to the free text message.

The resulting number is 71 bits long.

Unpacking successively pops off indexes which are converted back to ASCII, then the register is divided by 42, and the process is repeated until all 13 ASCII characters are unpacked.

73
Bill
G4WJS.


Andy TALBOT
 

Ah, thanks Bill.   An endian detector - life must get very gets complicated if you need to cope with both.
 So I can ignore most of that and just calculate the base 42 number from scratch.
42 ^ 13 can be represented by 71 bits so that makes immediate sense.   
Pity the longest integer I can handle is 64 bits, so it'll need two hits at least.

Andy  G4JNT


Joe
 

Hi Andy,

Yes, the mp_* routines are there to do slow-but sure multiple-precision arithmetic.  This is necessary because we need to save a 71-bit result of the packing operation.

I just wrote a simple Fortran test program that you can use to help yourself figure out what is going on.  You can download it here, compile it for yourself, and then work out how to re-write it in C (or whatever).
https://physics.princeton.edu/pulsar/k1jt/t1.f90

  -- 73, Joe, K1JT


Andy TALBOT
 

Thank Joe and Steve.
My language of choice,  PowerBasic, has a number of commands that make life a bit easier for that sort of thing.  Not having to worry about endian matters it turned out, after a bit of playing around with pen and paper as to how we actually DO long multiplication, as a nice elegant bit of code 

This routine takes in two byte values A and B and calculates the sum
C = C * A + B.   C is expressed as a string of '1's and '0's . A and B can be 0 - 255.   Basic and all its derivatives does string handling very well, so I use this method to handle long binary words rather than Fortran's and C's use of arrays
The BIN$(number) and  VAL("&B" & string$) handle the conversions to and from numbers

Variables without an identifier type are 32 bit integer, $ means string, and ? means a byte variable.    This being able to allocate variable types on the fly is why I prefer Basic over other programming languages.   However, after many hours of poring over Fortran 90 listings, I've gained a great appreciation of that language too.
Don't like C - horrible language.

SUB LongMac(a? , b? , c$)       'C = C * A + B    C represented by string of '1/0's
    nb = LEN(c$)/8                        'nb = Number of bytes, LEN(c$) must be a multiple of 8
    acc = b?
    FOR z = nb TO 1 STEP -1
        acc = acc + a? * VAL("&B" & MID$(c$, z * 8 - 7 , 8))    'get the next byte into accumulator, starting at lowest
        MID$(c$, z * 8 - 7 , 8) = BIN$(acc AND &hFF, 8)     'Replace lowest byte
        SHIFT RIGHT acc, 8                                  'Place MSBs ready for adding in next byte
    NEXT z
END SUB       


Andy TALBOT
 

sri, meant thanks Bill and Joe :-)