 c24e931f09
			
		
	
	
		c24e931f09
		
	
	
	
	
		
			
			commit 0d6833b23da2519155ee93b98b4144240b356730
Author: Jordan Sherer <jordan@widefido.com>
Date:   Thu Sep 5 14:06:47 2019 -0400
    Bump version
commit 17705fcff6a22529f3dec45aa95cad90feb78c63
Author: Jordan Sherer <jordan@widefido.com>
Date:   Thu Sep 5 10:36:03 2019 -0400
    Updated configration labeling for idle timeout
commit a9f8aa9549c1c6b62201a6c102d91649ee17b9a5
Author: Jordan Sherer <jordan@widefido.com>
Date:   Thu Sep 5 10:07:11 2019 -0400
    Decoder params tests
commit 94e524741020fd8b3925233a189cedf0a8a282cc
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Sep 4 21:24:23 2019 -0400
    Fixed decoder bug that crashed the software
commit 4fdbfc8d9082e0f52513a5c215489b13558972f9
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Sep 4 21:02:52 2019 -0400
    Decoder params tweak
commit 1e25ac41d442372f09b254d957e0d9e31773254e
Merge: 97a0fb5 552cd7f
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Sep 4 18:17:40 2019 -0400
    Merge branch 'fortran-cleanup' of bitbucket.org:widefido/js8call-private into fortran-cleanup
commit 97a0fb51b37c24e2638400dc5694fc4e988ae4f2
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Sep 4 18:15:25 2019 -0400
    Heartbeat as a mode does not work if slow mode does not work. Tabling this idea for now.
commit 552cd7fe5fc81c712b57b5f3ea79599177e53f69
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 23:35:14 2019 +0000
    js8_params.f90 edited online with Bitbucket
commit 7c9e960b863148a4ecbca4f61584536471623ea2
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 16:28:52 2019 -0400
    Do not randomize offset at startup
commit cff7b90dbb9aada2944e668a9bcf078470af4608
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 16:20:19 2019 -0400
    Slow label for button
commit 977145dee89ccd7da4d43ce0bc2f9b79243aa200
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 16:17:36 2019 -0400
    Experimental slow mode
commit 27c128e0b327e1c077a9b49e11750bef2f3c26eb
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 15:26:01 2019 -0400
    HBs are Normal
commit 89792f91abf22dcd7c512bf7362f5e2e1cb36374
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 14:16:27 2019 -0400
    Update heartbeat UI for more clarity
commit f5cebbcdabe37d90b75ca7e8d1675a553e107c83
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 11:58:53 2019 -0400
    Optimize decode params
commit b14003bb34d93f9e93d7d4ad4241d619963c3a65
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 11:30:00 2019 -0400
    Shrink speed column for Joe ;)
commit 35f4446146efc9fd7044af3b56b0b93664238b24
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 10:54:28 2019 -0400
    Fixed fast mode decoder for directed messages
commit 64212acc30dd360348a72b354899a5b0de28aa83
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 10:05:11 2019 -0400
    Simplified decoder callbacks
commit a026766517d282a3fda0258356f6f22fee2a916f
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Sep 3 09:50:33 2019 -0400
    Commentary
commit 9d28b1ff5bd5cda7a04028218a01639e3902bf7b
Author: Jordan Sherer <jordan@widefido.com>
Date:   Mon Sep 2 23:33:22 2019 -0400
    Let's experiment with a new UI for HB
commit a013d66d8b8d16cc941a14eb76af2ce23b7bb6d5
Author: Jordan Sherer <jordan@widefido.com>
Date:   Mon Sep 2 21:44:26 2019 -0400
    31.25 baud experiment
commit 0671458bf588dd94710c5ba34f20695e13a28d31
Author: Jordan Sherer <jordan@widefido.com>
Date:   Mon Sep 2 15:31:43 2019 -0400
    Added basic foundation for slow mode, coming soon.
commit 8b9aed6e29b093e8fb736ebdbdf0fbe12a820e8e
Author: Jordan Sherer <jordan@widefido.com>
Date:   Mon Sep 2 09:59:08 2019 -0400
    Display SPEED+AUTO
commit 5f5af250c1c5b610e8969b32c01654d3467f0973
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sun Sep 1 09:45:39 2019 -0400
    Added mode speed option to the activity tables
commit 82fa0335fdd41f0a578149e0211d6307293c739d
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 31 23:14:07 2019 -0400
    Remember mode speed setting
commit 79ec805b223099bb4d552dc612a6c97a8982525e
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 31 21:14:04 2019 -0400
    Remove unused sync vars
commit fc52dfcc320e59f6c7ca58ba277cb70469419587
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 31 21:12:11 2019 -0400
    Timing delta max
commit 62b8fc5054d3611d40d7441d57d695df594b8446
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 31 17:14:08 2019 -0400
    Fast modes optionally can use huff encoding for data... we'll see which is best
commit 44c357aff3e1c6687e93fb843917bd420888b397
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 31 17:03:21 2019 -0400
    Added ability to use a different message packing algorithm for fast modes
commit e075a078eb75509ef690e6c78c0e797ada569b94
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 31 16:18:14 2019 -0400
    Fixed symbol offset in sync code for turbo mode
commit a130b5d4a594e9bceece003be0ba72abb05a9f90
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 31 16:09:27 2019 -0400
    Added WPM to menu
commit 98cacab7bfc243492b6dec703d216d378cc3d34d
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 30 23:18:58 2019 -0400
    Key eater
commit eef58e2c88d010c7f3917a111243eae744a425c3
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 30 16:07:31 2019 -0400
    Reorganizing js8dec for better understanding and less confusion between it and JS8b
commit 08c14f966e1cda836ca90a8bd1ccd5ae68ec8dd7
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 30 14:20:52 2019 -0400
    Do no expose relay and messaging to fast and turbo modes
commit c605a31c266866f78eb043812af837ead6442ede
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 30 12:02:41 2019 -0400
    Do not allow mode speed changes if transmitting
commit add062e657a5215f9a4a1ae3ee82063aa85cf0e4
Author: Jordan Sherer <jordan@widefido.com>
Date:   Thu Aug 29 23:02:31 2019 -0400
    Fixed bug where tones were not generated with the correct costas arrays...causing really poor synchronization and failed decodes. I'm surprised it worked at all :P
commit cd492b5dd9fd62b5518a5711a1ef8ec522ea08fe
Author: Jordan Sherer <jordan@widefido.com>
Date:   Thu Aug 29 21:56:45 2019 -0400
    Back to 20 baud. It has the best decodability, imho
commit a2266cd00b8bd14c77bdbc8fc18818689e969858
Author: Jordan Sherer <jordan@widefido.com>
Date:   Thu Aug 29 14:27:29 2019 -0400
    Back to 20 baud with some decoder optimizations
commit 86413042e75873585bcb40236da67f2d64870859
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 28 23:04:47 2019 -0400
    Try 24 baud
commit a6704162b37d1c0704f43a64ab6b8a0a6e3c1cba
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 28 17:09:12 2019 -0400
    Fixed legacy compiler issue with mode text
commit 2fdbcc12e5f0c8cc8062c745af0930db4472cd9c
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 28 10:17:23 2019 -0400
    Function for determining current mode
commit 82e70345baa665418a51307f0309f2b7dcb3d3b7
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 28 09:59:26 2019 -0400
    Don't write the log
commit d3380e01676537f4bab9a05932cb5a59de3cf45f
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 28 09:59:03 2019 -0400
    Fixed issues with turbo decode with partial sync code
commit c2a8ebb8f305e67fcb2597d25e062663722a0d73
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 28 03:30:02 2019 -0400
    Working through better decoding of fast modes
commit 7ca93f8c6a7970559577c9dfd833eb92a1b91a0c
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 23:23:34 2019 -0400
    Trying for better TX/RX delays
commit b99271b4feaa7e41c7b88219cb3c7d43dbe7b48d
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 22:57:02 2019 -0400
    Added flags to easily enable/disable the faster modes
commit 32d913a7f7d3deb6a8d66651d51673ec451d2500
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 22:43:20 2019 -0400
    Added mode button
commit c7cc90548591638bfc5a4a8895036dd67b155aaa
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 22:17:42 2019 -0400
    Updated start delay for the modes
commit b91dc63f92101cd8b6adbf9de588c4ffd10bfc10
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 21:55:57 2019 -0400
    Late threshold for turbo mode is 1/2 the delay
commit 09ec95fab1307e65aa9bd462d60525afd2a770fe
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 21:52:55 2019 -0400
    Renamed mode menu items
commit a4e5a9ed9bce66c625e4df1182cd3c91a6ba44dd
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 21:50:45 2019 -0400
    Only enable networking and autoreply for normal JS8
commit fc558d5823c46fc5d3dc651610b7af43e7519165
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 21:14:12 2019 -0400
    Fixed spot button tooltip
commit 9a9965d543540a2d215bcbfff34934846afe507a
Author: Jordan Sherer <jordan@widefido.com>
Date:   Tue Aug 27 10:04:31 2019 -0400
    Working selectable decoder
commit 4a9cdbc52dae1d857c102d8777f1aded4fac87bb
Author: Jordan Sherer <jordan@widefido.com>
Date:   Mon Aug 26 20:53:30 2019 -0400
    Mode menu selection of the submodes. Turbo decoder disabled right now. Naming to be determined
commit a3acbf7c243f7aa740c229ae178fffa528e68933
Merge: 8ea554d daa8cc2
Author: Jordan Sherer <jordan@widefido.com>
Date:   Mon Aug 26 13:29:14 2019 -0400
    Merge branch 'ft8call-develop' into fortran-cleanup
commit 8ea554d79904c9b2f3ccf1027bf4d41fb25e6fe3
Author: Jordan Sherer <jordan@widefido.com>
Date:   Mon Aug 26 09:53:21 2019 -0400
    Use indx variable instead of computed
commit 067e65500328133f921b172e515babbcc0df831b
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sun Aug 25 22:41:00 2019 -0400
    Make it easier to flip between modes
commit a544a7635201072f3ea20483353edf2e79dc813d
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sun Aug 25 21:18:46 2019 -0400
    Fixed sync issues with multi costas. Added log statements for future debugging
commit a8f3ead932017ae7d98fdb9a779bf3bb44bd395d
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sun Aug 25 15:54:59 2019 -0400
    Playing around with different costas arrays
commit fa89fe11a15d26abadd5102c8980620cfeffccd9
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sun Aug 25 15:51:45 2019 -0400
    Added reference to 7x7 costas arrays
commit 2417ebed6139534214f76ce94bdf1f54a966760a
Merge: 6011f1e 32fcabd
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 24 23:41:39 2019 -0400
    Merge branch 'ft8call-develop' into fortran-cleanup
commit 6011f1e807b1814399477d3c172db46831a090c6
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 24 23:35:42 2019 -0400
    Back to 10 baud. Update late threshold to be computed to 3/4 dead air time.
commit 41d3995861226f7208b2773430010a48abc125c1
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 24 15:36:12 2019 -0400
    Trying out 20 baud
commit a8d77e9e5b98f3f0bf19f68b53199b5952e8aaad
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 24 15:23:36 2019 -0400
    Fixed up sync quarter symbol constant
commit 7050722436b9c629ea00649e6b3c81d7af7be82a
Author: Jordan Sherer <jordan@widefido.com>
Date:   Sat Aug 24 14:43:48 2019 -0400
    Computed symbol stop
commit f130fe87abdccbabd2e71f2771b789c7f46d57ca
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 23 20:56:59 2019 -0400
    Added reference to 7x7 costas arrays
commit 53e91858f5a4e9ce78c38ef65c77e87f1903c058
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 23 16:34:51 2019 -0400
    Back to 10 baud
commit 1ae79d566ebd9a40ad3cf4a07977ef0e09615d91
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 23 15:14:41 2019 -0400
    Testing 31.25 baud
commit 7e033c28ae090d6c3f5a63fa651ee51c3243d61c
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 23 15:14:17 2019 -0400
    Experimenting with a few different baudrates
commit 050e24ad3a040924ded6d641004ae63da47e4251
Author: Jordan Sherer <jordan@widefido.com>
Date:   Fri Aug 23 12:25:50 2019 -0400
    Added ldpcsim for js8
commit d309a75d860e39737dec732560432a191290b258
Author: Jordan Sherer <jordan@widefido.com>
Date:   Thu Aug 22 22:42:11 2019 -0400
    Experimental submode switching
commit 74f72bb24a22631b8b69942ea0633bb0564b8aa3
Author: Jordan Sherer <jordan@widefido.com>
Date:   Thu Aug 22 22:41:53 2019 -0400
    Allow switching decoders based on submode
commit f8740a23b27e80fa53350e140d4638a27cd6e975
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 21 23:43:18 2019 -0400
    Initial spike of js8 fortran code
commit 31625316639f79246b4a2e3d0cea4507bf0547f9
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 21 23:09:00 2019 -0400
    Remove fix contest message
commit c0e0862afa8ae2d47e9577562399b8c9bc929c6a
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 21 21:05:05 2019 -0400
    Cleanup unused text files and batch files
commit 1b3aa55869f0c310e6c911a7cbb3fe269bc7421a
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 21 21:00:38 2019 -0400
    Removed fast_decode and dx
commit 49e5cabff25c13620a9d2c6fc6ddd4988f1be217
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 21 20:54:39 2019 -0400
    Cleaning up msk stuff
commit 8bde6f391f4b23d2a2e9d55685d96bc647a462f6
Author: Jordan Sherer <jordan@widefido.com>
Date:   Wed Aug 21 20:44:39 2019 -0400
    Initial cleanup pass of qra, ftrsd, and wsprd
		
	
			
		
			
				
	
	
		
			1038 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Fortran
		
	
	
	
	
	
			
		
		
	
	
			1038 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Fortran
		
	
	
	
	
	
| module packjt
 | |
| 
 | |
| ! These variables are accessible from outside via "use packjt":
 | |
|   integer jt_itype,jt_nc1,jt_nc2,jt_ng,jt_k1,jt_k2
 | |
|   character*6 jt_c1,jt_c2,jt_c3
 | |
|   
 | |
|   contains
 | |
| 
 | |
| subroutine packbits(dbits,nsymd,m0,sym)
 | |
| 
 | |
|  ! Pack 0s and 1s from dbits() into sym() with m0 bits per word.
 | |
|  ! NB: nsymd is the number of packed output words.
 | |
| 
 | |
|    integer sym(:)
 | |
|    integer*1 dbits(:)
 | |
| 
 | |
|    k=0
 | |
|    do i=1,nsymd
 | |
|       n=0
 | |
|       do j=1,m0
 | |
|          k=k+1
 | |
|          m=dbits(k)
 | |
|          n=ior(ishft(n,1),m)
 | |
|       enddo
 | |
|       sym(i)=n
 | |
|    enddo
 | |
| 
 | |
|    return
 | |
|  end subroutine packbits
 | |
| 
 | |
|  subroutine unpackbits(sym,nsymd,m0,dbits)
 | |
| 
 | |
|  ! Unpack bits from sym() into dbits(), one bit per byte.
 | |
|  ! NB: nsymd is the number of input words, and m0 their length.
 | |
|  ! there will be m0*nsymd output bytes, each 0 or 1.
 | |
| 
 | |
|    integer sym(:)
 | |
|    integer*1 dbits(:)
 | |
| 
 | |
|    k=0
 | |
|    do i=1,nsymd
 | |
|       mask=ishft(1,m0-1)
 | |
|       do j=1,m0
 | |
|          k=k+1
 | |
|          dbits(k)=0
 | |
|          if(iand(mask,sym(i)).ne.0) dbits(k)=1
 | |
|          mask=ishft(mask,-1)
 | |
|       enddo
 | |
|    enddo
 | |
| 
 | |
|    return
 | |
|  end subroutine unpackbits
 | |
| 
 | |
|  subroutine packcall(callsign,ncall,text)
 | |
| 
 | |
|  ! Pack a valid callsign into a 28-bit integer.
 | |
| 
 | |
|    parameter (NBASE=37*36*10*27*27*27)
 | |
|    character callsign*6,c*1,tmp*6
 | |
|    logical text
 | |
| 
 | |
|    text=.false.
 | |
| 
 | |
|  ! Work-around for Swaziland prefix:
 | |
|    if(callsign(1:4).eq.'3DA0') callsign='3D0'//callsign(5:6)
 | |
| 
 | |
|  ! Work-around for Guinea prefixes:
 | |
|    if(callsign(1:2).eq.'3X' .and. callsign(3:3).ge.'A' .and.          &
 | |
|         callsign(3:3).le.'Z') callsign='Q'//callsign(3:6)
 | |
|    
 | |
|    if(callsign(1:3).eq.'CQ ') then
 | |
|       ncall=NBASE + 1
 | |
|       if(callsign(4:4).ge.'0' .and. callsign(4:4).le.'9' .and.        &
 | |
|            callsign(5:5).ge.'0' .and. callsign(5:5).le.'9' .and.      &
 | |
|            callsign(6:6).ge.'0' .and. callsign(6:6).le.'9') then
 | |
|          read(callsign(4:6),*) nfreq
 | |
|          ncall=NBASE + 3 + nfreq
 | |
|       endif
 | |
|       return
 | |
|    else if(callsign(1:4).eq.'QRZ ') then
 | |
|       ncall=NBASE + 2
 | |
|       return
 | |
|    else if(callsign(1:3).eq.'DE ') then
 | |
|       ncall=267796945
 | |
|       return
 | |
|    endif
 | |
| 
 | |
|    tmp='      '
 | |
|    if(callsign(3:3).ge.'0' .and. callsign(3:3).le.'9') then
 | |
|       tmp=callsign
 | |
|    else if(callsign(2:2).ge.'0' .and. callsign(2:2).le.'9') then
 | |
|       if(callsign(6:6).ne.' ') then
 | |
|          text=.true.
 | |
|          return
 | |
|       endif
 | |
|       tmp=' '//callsign(:5)
 | |
|    else
 | |
|       text=.true.
 | |
|       return
 | |
|    endif
 | |
| 
 | |
|    do i=1,6
 | |
|       c=tmp(i:i)
 | |
|       if(c.ge.'a' .and. c.le.'z')                                &
 | |
|            tmp(i:i)=char(ichar(c)-ichar('a')+ichar('A'))
 | |
|    enddo
 | |
| 
 | |
|    n1=0
 | |
|    if((tmp(1:1).ge.'A'.and.tmp(1:1).le.'Z').or.tmp(1:1).eq.' ') n1=1
 | |
|    if(tmp(1:1).ge.'0' .and. tmp(1:1).le.'9') n1=1
 | |
|    n2=0
 | |
|    if(tmp(2:2).ge.'A' .and. tmp(2:2).le.'Z') n2=1
 | |
|    if(tmp(2:2).ge.'0' .and. tmp(2:2).le.'9') n2=1
 | |
|    n3=0
 | |
|    if(tmp(3:3).ge.'0' .and. tmp(3:3).le.'9') n3=1
 | |
|    n4=0
 | |
|    if((tmp(4:4).ge.'A'.and.tmp(4:4).le.'Z').or.tmp(4:4).eq.' ') n4=1
 | |
|    n5=0
 | |
|    if((tmp(5:5).ge.'A'.and.tmp(5:5).le.'Z').or.tmp(5:5).eq.' ') n5=1
 | |
|    n6=0
 | |
|    if((tmp(6:6).ge.'A'.and.tmp(6:6).le.'Z').or.tmp(6:6).eq.' ') n6=1
 | |
| 
 | |
|    if(n1+n2+n3+n4+n5+n6 .ne. 6) then
 | |
|       text=.true.
 | |
|       return 
 | |
|    endif
 | |
| 
 | |
|    ncall=nchar(tmp(1:1))
 | |
|    ncall=36*ncall+nchar(tmp(2:2))
 | |
|    ncall=10*ncall+nchar(tmp(3:3))
 | |
|    ncall=27*ncall+nchar(tmp(4:4))-10
 | |
|    ncall=27*ncall+nchar(tmp(5:5))-10
 | |
|    ncall=27*ncall+nchar(tmp(6:6))-10
 | |
| 
 | |
|    return
 | |
|  end subroutine packcall
 | |
| 
 | |
|  subroutine unpackcall(ncall,word,iv2,psfx)
 | |
| 
 | |
|    parameter (NBASE=37*36*10*27*27*27)
 | |
|    character word*12,c*37,psfx*4
 | |
| 
 | |
|    data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ '/
 | |
| 
 | |
|    word='......' 
 | |
|    psfx='    '
 | |
|    n=ncall
 | |
|    iv2=0
 | |
|    if(n.ge.262177560) go to 20
 | |
|    word='......'
 | |
|  !  if(n.ge.262177560) go to 999            !Plain text message ...
 | |
|    i=mod(n,27)+11
 | |
|    word(6:6)=c(i:i)
 | |
|    n=n/27
 | |
|    i=mod(n,27)+11
 | |
|    word(5:5)=c(i:i)
 | |
|    n=n/27
 | |
|    i=mod(n,27)+11
 | |
|    word(4:4)=c(i:i)
 | |
|    n=n/27
 | |
|    i=mod(n,10)+1
 | |
|    word(3:3)=c(i:i)
 | |
|    n=n/10
 | |
|    i=mod(n,36)+1
 | |
|    word(2:2)=c(i:i)
 | |
|    n=n/36
 | |
|    i=n+1
 | |
|    word(1:1)=c(i:i)
 | |
|    do i=1,4
 | |
|       if(word(i:i).ne.' ') go to 10
 | |
|    enddo
 | |
|    go to 999
 | |
|  10 word=word(i:)
 | |
|    go to 999
 | |
| 
 | |
|  20 if(n.ge.267796946) go to 999
 | |
| 
 | |
|  ! We have a JT65v2 message
 | |
|    if((n.ge.262178563) .and. (n.le.264002071)) then
 | |
|  ! CQ with prefix
 | |
|       iv2=1
 | |
|       n=n-262178563
 | |
|       i=mod(n,37)+1
 | |
|       psfx(4:4)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(3:3)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(2:2)=c(i:i)
 | |
|       n=n/37
 | |
|       i=n+1
 | |
|       psfx(1:1)=c(i:i)
 | |
| 
 | |
|    else if((n.ge.264002072) .and. (n.le.265825580)) then
 | |
|  ! QRZ with prefix
 | |
|       iv2=2
 | |
|       n=n-264002072
 | |
|       i=mod(n,37)+1
 | |
|       psfx(4:4)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(3:3)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(2:2)=c(i:i)
 | |
|       n=n/37
 | |
|       i=n+1
 | |
|       psfx(1:1)=c(i:i)
 | |
| 
 | |
|    else if((n.ge.265825581) .and. (n.le.267649089)) then
 | |
|  ! DE with prefix
 | |
|       iv2=3
 | |
|       n=n-265825581
 | |
|       i=mod(n,37)+1
 | |
|       psfx(4:4)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(3:3)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(2:2)=c(i:i)
 | |
|       n=n/37
 | |
|       i=n+1
 | |
|       psfx(1:1)=c(i:i)
 | |
| 
 | |
|    else if((n.ge.267649090) .and. (n.le.267698374)) then
 | |
|  ! CQ with suffix
 | |
|       iv2=4
 | |
|       n=n-267649090
 | |
|       i=mod(n,37)+1
 | |
|       psfx(3:3)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(2:2)=c(i:i)
 | |
|       n=n/37
 | |
|       i=n+1
 | |
|       psfx(1:1)=c(i:i)
 | |
| 
 | |
|    else if((n.ge.267698375) .and. (n.le.267747659)) then
 | |
|  ! QRZ with suffix
 | |
|       iv2=5
 | |
|       n=n-267698375
 | |
|       i=mod(n,37)+1
 | |
|       psfx(3:3)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(2:2)=c(i:i)
 | |
|       n=n/37
 | |
|       i=n+1
 | |
|       psfx(1:1)=c(i:i)
 | |
| 
 | |
|    else if((n.ge.267747660) .and. (n.le.267796944)) then
 | |
|  ! DE with suffix
 | |
|       iv2=6
 | |
|       n=n-267747660
 | |
|       i=mod(n,37)+1
 | |
|       psfx(3:3)=c(i:i)
 | |
|       n=n/37
 | |
|       i=mod(n,37)+1
 | |
|       psfx(2:2)=c(i:i)
 | |
|       n=n/37
 | |
|       i=n+1
 | |
|       psfx(1:1)=c(i:i)
 | |
| 
 | |
|    else if(n.eq.267796945) then
 | |
|  ! DE with no prefix or suffix
 | |
|       iv2=7
 | |
|       psfx = '    '
 | |
|    endif
 | |
| 
 | |
| 999 if(word(1:3).eq.'3D0') word='3DA0'//word(4:)
 | |
|    if(word(1:1).eq.'Q' .and. word(2:2).ge.'A' .and.                 &
 | |
|         word(2:2).le.'Z') word='3X'//word(2:)
 | |
| 
 | |
|    return
 | |
|  end subroutine unpackcall
 | |
| 
 | |
|  subroutine packgrid(grid,ng,text)
 | |
| 
 | |
|    parameter (NGBASE=180*180)
 | |
|    character*4 grid
 | |
|    character*1 c1
 | |
|    logical text
 | |
| 
 | |
|    text=.false.
 | |
|    if(grid.eq.'    ') go to 90               !Blank grid is OK
 | |
| 
 | |
|  ! First, handle signal reports in the original range, -01 to -30 dB
 | |
|    if(grid(1:1).eq.'-') then
 | |
|       read(grid(2:3),*,err=800,end=800) n
 | |
|       if(n.ge.1 .and. n.le.30) then
 | |
|          ng=NGBASE+1+n
 | |
|          go to 900
 | |
|       endif
 | |
|       go to 10
 | |
|    else if(grid(1:2).eq.'R-') then
 | |
|       read(grid(3:4),*,err=800,end=800) n
 | |
|       if(n.ge.1 .and. n.le.30) then
 | |
|          ng=NGBASE+31+n
 | |
|          go to 900
 | |
|       endif
 | |
|       go to 10
 | |
|  ! Now check for RO, RRR, or 73 in the message field normally used for grid
 | |
|    else if(grid(1:4).eq.'RO  ') then
 | |
|       ng=NGBASE+62
 | |
|       go to 900
 | |
|    else if(grid(1:4).eq.'RRR ') then
 | |
|       ng=NGBASE+63
 | |
|       go to 900
 | |
|    else if(grid(1:4).eq.'73  ') then
 | |
|       ng=NGBASE+64
 | |
|       go to 900
 | |
|    endif
 | |
| 
 | |
|  ! Now check for extended-range signal reports: -50 to -31, and 0 to +49.
 | |
|  10 n=99
 | |
|    c1=grid(1:1)
 | |
|    read(grid,*,err=20,end=20) n
 | |
|    go to 30
 | |
|  20 read(grid(2:4),*,err=30,end=30) n
 | |
|  30 if(n.ge.-50 .and. n.le.49) then
 | |
|       if(c1.eq.'R') then
 | |
|          write(grid,1002) n+50
 | |
|  1002    format('LA',i2.2)
 | |
|       else
 | |
|          write(grid,1003) n+50
 | |
|  1003    format('KA',i2.2)
 | |
|       endif
 | |
|       go to 40
 | |
|    endif
 | |
| 
 | |
|  ! Maybe it's free text ?
 | |
|    if(grid(1:1).lt.'A' .or. grid(1:1).gt.'R') text=.true.
 | |
|    if(grid(2:2).lt.'A' .or. grid(2:2).gt.'R') text=.true.
 | |
|    if(grid(3:3).lt.'0' .or. grid(3:3).gt.'9') text=.true.
 | |
|    if(grid(4:4).lt.'0' .or. grid(4:4).gt.'9') text=.true.
 | |
|    if(text) go to 900
 | |
| 
 | |
|  ! OK, we have a properly formatted grid locator
 | |
|  40 call grid2deg(grid//'mm',dlong,dlat)
 | |
|    long=int(dlong)
 | |
|    lat=int(dlat+ 90.0)
 | |
|    ng=((long+180)/2)*180 + lat
 | |
|    go to 900
 | |
| 
 | |
|  90 ng=NGBASE + 1
 | |
|    go to 900
 | |
| 
 | |
|  800 text=.true.
 | |
|  900 continue
 | |
| 
 | |
|    return
 | |
|  end subroutine packgrid
 | |
| 
 | |
|  subroutine unpackgrid(ng,grid)
 | |
| 
 | |
|    parameter (NGBASE=180*180)
 | |
|    character grid*4,grid6*6
 | |
| 
 | |
|    grid='    '
 | |
|    if(ng.ge.32400) go to 10
 | |
|    dlat=mod(ng,180)-90
 | |
|    dlong=(ng/180)*2 - 180 + 2
 | |
|    call deg2grid(dlong,dlat,grid6)
 | |
|    grid=grid6(:4)
 | |
|    if(grid(1:2).eq.'KA') then
 | |
|       read(grid(3:4),*) n
 | |
|       n=n-50
 | |
|       write(grid,1001) n
 | |
|  1001 format(i3.2)
 | |
|       if(grid(1:1).eq.' ') grid(1:1)='+'
 | |
|    else if(grid(1:2).eq.'LA') then
 | |
|       read(grid(3:4),*) n
 | |
|       n=n-50
 | |
|       write(grid,1002) n
 | |
|  1002 format('R',i3.2)
 | |
|       if(grid(2:2).eq.' ') grid(2:2)='+'
 | |
|    endif
 | |
|    go to 900
 | |
| 
 | |
|  10 n=ng-NGBASE-1
 | |
|    if(n.ge.1 .and.n.le.30) then
 | |
|       write(grid,1012) -n
 | |
|  1012 format(i3.2)
 | |
|    else if(n.ge.31 .and.n.le.60) then
 | |
|       n=n-30
 | |
|       write(grid,1022) -n
 | |
|  1022 format('R',i3.2)
 | |
|    else if(n.eq.61) then
 | |
|       grid='RO'
 | |
|    else if(n.eq.62) then
 | |
|       grid='RRR'
 | |
|    else if(n.eq.63) then
 | |
|       grid='73'
 | |
|    endif
 | |
| 
 | |
|  900 return
 | |
|  end subroutine unpackgrid
 | |
| 
 | |
|  subroutine packmsg(msg0,dat,itype,bcontest)
 | |
| 
 | |
|  ! Packs a JT4/JT9/JT65 message into twelve 6-bit symbols
 | |
| 
 | |
|  ! itype Message Type
 | |
|  !--------------------
 | |
|  !   1   Standardd message
 | |
|  !   2   Type 1 prefix
 | |
|  !   3   Type 1 suffix
 | |
|  !   4   Type 2 prefix
 | |
|  !   5   Type 2 suffix
 | |
|  !   6   Free text
 | |
|  !  -1   Does not decode correctly
 | |
| 
 | |
|    parameter (NBASE=37*36*10*27*27*27)
 | |
|    parameter (NBASE2=262178562)
 | |
|    character*22 msg0,msg
 | |
|    integer dat(:)
 | |
|    character*12 c1,c2
 | |
|    character*4 c3
 | |
|    character*6 grid6
 | |
|    logical text1,text2,text3,bcontest
 | |
| 
 | |
|    itype=1
 | |
|    if(bcontest) then
 | |
|       !call to_contest_msg(msg0,msg)
 | |
|       ! this causes problems with freetext ala, KN4CRD DE KN4CRD -13 R
 | |
|       msg=msg0
 | |
|    else
 | |
|       msg=msg0
 | |
|    end if
 | |
| 
 | |
|    call fmtmsg(msg,iz)
 | |
|    if(msg(1:3).eq.'CQ ' .and. msg(4:4).ge.'0' .and. msg(4:4).le.'9'   &
 | |
|         .and. msg(5:5).eq.' ') msg='CQ 00'//msg(4:)
 | |
| 
 | |
|    if(msg(1:6).eq.'CQ DX ') msg(3:3)='9'
 | |
|    if(msg(1:3).eq.'CQ ' .and.                                         &
 | |
|         msg(4:4).ge.'A' .and. msg(4:4).le.'Z' .and.                   &
 | |
|         msg(5:5).ge.'A' .and. msg(5:5).le.'Z' .and.                   &
 | |
|         msg(6:6).eq.' ') msg='E9'//msg(4:)
 | |
|    
 | |
|  ! See if it's a CQ message
 | |
|    if(msg(1:3).eq.'CQ ') then
 | |
|       i=3
 | |
|  ! ... and if so, does it have a reply frequency?
 | |
|       if(msg(4:4).ge.'0' .and. msg(4:4).le.'9' .and.                  &
 | |
|            msg(5:5).ge.'0' .and. msg(5:5).le.'9' .and.                &
 | |
|            msg(6:6).ge.'0' .and. msg(6:6).le.'9') i=7
 | |
|       go to 1
 | |
|    endif
 | |
| 
 | |
|    do i=1,22
 | |
|       if(msg(i:i).eq.' ') go to 1       !Get 1st blank
 | |
|    enddo
 | |
|    go to 10                             !Consider msg as plain text
 | |
| 
 | |
|  1 ia=i
 | |
|    c1=msg(1:ia-1)
 | |
|    do i=ia+1,22
 | |
|       if(msg(i:i).eq.' ') go to 2       !Get 2nd blank
 | |
|    enddo
 | |
|    go to 10                             !Consider msg as plain text
 | |
| 
 | |
|  2 ib=i
 | |
|    c2=msg(ia+1:ib-1)
 | |
| 
 | |
|    do i=ib+1,22
 | |
|       if(msg(i:i).eq.' ') go to 3       !Get 3rd blank
 | |
|    enddo
 | |
|    go to 10                             !Consider msg as plain text
 | |
| 
 | |
|  3 ic=i
 | |
|    c3='    '
 | |
|    if(ic.ge.ib+1) c3=msg(ib+1:ic)
 | |
|    if(c3.eq.'OOO ') c3='    '           !Strip out the OOO flag
 | |
|    call getpfx1(c1,k1,nv2a)
 | |
|    if(nv2a.ge.4) go to 10
 | |
|    call packcall(c1,nc1,text1)
 | |
|    if(text1) go to 10
 | |
|    call getpfx1(c2,k2,nv2b)
 | |
|    call packcall(c2,nc2,text2)
 | |
|    if(text2) go to 10
 | |
|    if(nv2a.eq.2 .or. nv2a.eq.3 .or. nv2b.eq.2 .or. nv2b.eq.3) then
 | |
|       if(k1.lt.0 .or. k2.lt.0 .or. k1*k2.ne.0) go to 10
 | |
|       if(k2.gt.0) k2=k2+450
 | |
|       k=max(k1,k2)
 | |
|       if(k.gt.0) then
 | |
|          call k2grid(k,grid6)
 | |
|          c3=grid6(:4)
 | |
|       endif
 | |
|    endif
 | |
|    call packgrid(c3,ng,text3)
 | |
| 
 | |
|    if(nv2a.lt.4 .and. nv2b.lt.4 .and. (.not.text1) .and. (.not.text2) .and.  &
 | |
|         (.not.text3)) go to 20
 | |
| 
 | |
|    nc1=0
 | |
|    if(nv2b.eq.4) then
 | |
|       if(c1(1:3).eq.'CQ ' .and. (.not.text3))  nc1=262178563 + k2
 | |
|       if(c1(1:4).eq.'QRZ ' .and. (.not.text3)) nc1=264002072 + k2
 | |
|       if(c1(1:3).eq.'DE ' .and. (.not.text3))  nc1=265825581 + k2
 | |
|    else if(nv2b.eq.5) then
 | |
|       if(c1(1:3).eq.'CQ ' .and. (.not.text3))  nc1=267649090 + k2
 | |
|       if(c1(1:4).eq.'QRZ ' .and. (.not.text3)) nc1=267698375 + k2
 | |
|       if(c1(1:3).eq.'DE ' .and. (.not.text3))  nc1=267747660 + k2
 | |
|    endif
 | |
|    if(nc1.ne.0) go to 20
 | |
| 
 | |
|  ! The message will be treated as plain text.
 | |
|  10 itype=6
 | |
|    call packtext(msg,nc1,nc2,ng)
 | |
|    ng=ng+32768
 | |
| 
 | |
|  ! Encode data into 6-bit words
 | |
| 20 continue
 | |
|    if(itype.ne.6) itype=max(nv2a,nv2b)
 | |
|    jt_itype=itype
 | |
|    jt_c1=c1(1:6)
 | |
|    jt_c2=c2(1:6)
 | |
|    jt_c3=c3
 | |
|    jt_k1=k1
 | |
|    jt_k2=k2
 | |
|    jt_nc1=nc1
 | |
|    jt_nc2=nc2
 | |
|    jt_ng=ng
 | |
|    dat(1)=iand(ishft(nc1,-22),63)                !6 bits
 | |
|    dat(2)=iand(ishft(nc1,-16),63)                !6 bits
 | |
|    dat(3)=iand(ishft(nc1,-10),63)                !6 bits
 | |
|    dat(4)=iand(ishft(nc1, -4),63)                !6 bits
 | |
|    dat(5)=4*iand(nc1,15)+iand(ishft(nc2,-26),3)  !4+2 bits
 | |
|    dat(6)=iand(ishft(nc2,-20),63)                !6 bits
 | |
|    dat(7)=iand(ishft(nc2,-14),63)                !6 bits
 | |
|    dat(8)=iand(ishft(nc2, -8),63)                !6 bits
 | |
|    dat(9)=iand(ishft(nc2, -2),63)                !6 bits
 | |
|    dat(10)=16*iand(nc2,3)+iand(ishft(ng,-12),15) !2+4 bits
 | |
|    dat(11)=iand(ishft(ng,-6),63)
 | |
|    dat(12)=iand(ng,63)
 | |
| 
 | |
|    return
 | |
|  end subroutine packmsg
 | |
| 
 | |
|  subroutine unpackmsg(dat,msg,bcontest,mygrid)
 | |
| 
 | |
|    parameter (NBASE=37*36*10*27*27*27)
 | |
|    parameter (NGBASE=180*180)
 | |
|    integer dat(:)
 | |
|    character c1*12,c2*12,grid*4,msg*22,grid6*6,psfx*4,junk2*4,mygrid*6
 | |
|    logical cqnnn,bcontest
 | |
| 
 | |
|    cqnnn=.false.
 | |
|    nc1=ishft(dat(1),22) + ishft(dat(2),16) + ishft(dat(3),10)+         &
 | |
|         ishft(dat(4),4) + iand(ishft(dat(5),-2),15)
 | |
| 
 | |
|    nc2=ishft(iand(dat(5),3),26) + ishft(dat(6),20) +                   &
 | |
|         ishft(dat(7),14) + ishft(dat(8),8) + ishft(dat(9),2) +         &
 | |
|         iand(ishft(dat(10),-4),3)
 | |
| 
 | |
|    ng=ishft(iand(dat(10),15),12) + ishft(dat(11),6) + dat(12)
 | |
| 
 | |
|    if(ng.ge.32768) then
 | |
|       call unpacktext(nc1,nc2,ng,msg)
 | |
|       go to 100
 | |
|    endif
 | |
| 
 | |
|    call unpackcall(nc1,c1,iv2,psfx)
 | |
|    if(iv2.eq.0) then
 | |
|  ! This is an "original JT65" message
 | |
|       if(nc1.eq.NBASE+1) c1='CQ    '
 | |
|       if(nc1.eq.NBASE+2) c1='QRZ   '
 | |
|       nfreq=nc1-NBASE-3
 | |
|       if(nfreq.ge.0 .and. nfreq.le.999) then
 | |
|          write(c1,1002) nfreq
 | |
|  1002    format('CQ ',i3.3)
 | |
|          cqnnn=.true.
 | |
|       endif
 | |
|    endif
 | |
| 
 | |
|    call unpackcall(nc2,c2,junk1,junk2)
 | |
|    call unpackgrid(ng,grid)
 | |
| 
 | |
|    if(iv2.gt.0) then
 | |
|  ! This is a JT65v2 message
 | |
|       do i=1,4
 | |
|          if(ichar(psfx(i:i)).eq.0) psfx(i:i)=' '
 | |
|       enddo
 | |
| 
 | |
|       n1=len_trim(psfx)
 | |
|       n2=len_trim(c2)
 | |
|       if(iv2.eq.1) msg='CQ '//psfx(:n1)//'/'//c2(:n2)//' '//grid
 | |
|       if(iv2.eq.2) msg='QRZ '//psfx(:n1)//'/'//c2(:n2)//' '//grid
 | |
|       if(iv2.eq.3) msg='DE '//psfx(:n1)//'/'//c2(:n2)//' '//grid
 | |
|       if(iv2.eq.4) msg='CQ '//c2(:n2)//'/'//psfx(:n1)//' '//grid
 | |
|       if(iv2.eq.5) msg='QRZ '//c2(:n2)//'/'//psfx(:n1)//' '//grid
 | |
|       if(iv2.eq.6) msg='DE '//c2(:n2)//'/'//psfx(:n1)//' '//grid
 | |
|       if(iv2.eq.7) then
 | |
|          grid6=grid//'ma'
 | |
|          call grid2k(grid6,k)
 | |
|          if(k.ge.451 .and. k.le.900) then
 | |
|             call getpfx2(k,c2)
 | |
|             n2=len_trim(c2)
 | |
|             msg='DE '//c2(:n2)
 | |
|          else
 | |
|             msg='DE '//c2(:n2)//' '//grid
 | |
|          endif
 | |
|       endif
 | |
|       if(iv2.eq.8) msg=' '
 | |
|       go to 100
 | |
|    else
 | |
| 
 | |
|    endif
 | |
| 
 | |
|    grid6=grid//'ma'
 | |
|    call grid2k(grid6,k)
 | |
|    if(k.ge.1 .and. k.le.450)   call getpfx2(k,c1)
 | |
|    if(k.ge.451 .and. k.le.900) call getpfx2(k,c2)
 | |
| 
 | |
|    i=index(c1,char(0))
 | |
|    if(i.ge.3) c1=c1(1:i-1)//'            '
 | |
|    i=index(c2,char(0))
 | |
|    if(i.ge.3) c2=c2(1:i-1)//'            '
 | |
| 
 | |
|    msg='                      '
 | |
|    j=0
 | |
|    if(cqnnn) then
 | |
|       msg=c1//'          '
 | |
|       j=7                                  !### ??? ###
 | |
|       go to 10
 | |
|    endif
 | |
| 
 | |
|    do i=1,12
 | |
|       j=j+1
 | |
|       msg(j:j)=c1(i:i)
 | |
|       if(c1(i:i).eq.' ') go to 10
 | |
|    enddo
 | |
|    j=j+1
 | |
|    msg(j:j)=' '
 | |
| 
 | |
|  10 do i=1,12
 | |
|       if(j.le.21) j=j+1
 | |
|       msg(j:j)=c2(i:i)
 | |
|       if(c2(i:i).eq.' ') go to 20
 | |
|    enddo
 | |
|    if(j.le.21) j=j+1
 | |
|    msg(j:j)=' '
 | |
| 
 | |
|  20 if(k.eq.0) then
 | |
|       do i=1,4
 | |
|          if(j.le.21) j=j+1
 | |
|          msg(j:j)=grid(i:i)
 | |
|       enddo
 | |
|       if(j.le.21) j=j+1
 | |
|       msg(j:j)=' '
 | |
|    endif
 | |
| 
 | |
|  100 continue
 | |
|    if(msg(1:6).eq.'CQ9DX ') msg(3:3)=' '
 | |
|    if(msg(1:2).eq.'E9' .and.                                          &
 | |
|         msg(3:3).ge.'A' .and. msg(3:3).le.'Z' .and.                   &
 | |
|         msg(4:4).ge.'A' .and. msg(4:4).le.'Z' .and.                   &
 | |
|         msg(5:5).eq.' ') msg='CQ '//msg(3:)
 | |
| 
 | |
|    if(msg(1:5).eq.'CQ 00' .and. msg(6:6).ge.'0' .and.                 &
 | |
|         msg(6:6).le.'9') msg='CQ '//msg(6:)
 | |
| 
 | |
|    return
 | |
|  end subroutine unpackmsg
 | |
| 
 | |
|  subroutine packtext(msg,nc1,nc2,nc3)
 | |
| 
 | |
|    parameter (MASK28=2**28 - 1)
 | |
|    character*22 msg
 | |
|    character*42 c
 | |
|    data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?'/
 | |
| 
 | |
|    nc1=0
 | |
|    nc2=0
 | |
|    nc3=0
 | |
| 
 | |
|    do i=1,5                                !First 5 characters in nc1
 | |
|       do j=1,42                            !Get character code
 | |
|          if(msg(i:i).eq.c(j:j)) go to 10
 | |
|       enddo
 | |
|       j=37
 | |
|  10   j=j-1                                !Codes should start at zero
 | |
|       nc1=42*nc1 + j
 | |
|    enddo
 | |
| 
 | |
|    do i=6,10                               !Characters 6-10 in nc2
 | |
|       do j=1,42                            !Get character code
 | |
|          if(msg(i:i).eq.c(j:j)) go to 20
 | |
|       enddo
 | |
|       j=37
 | |
|  20   j=j-1                                !Codes should start at zero
 | |
|       nc2=42*nc2 + j
 | |
|    enddo
 | |
| 
 | |
|    do i=11,13                              !Characters 11-13 in nc3
 | |
|       do j=1,42                            !Get character code
 | |
|          if(msg(i:i).eq.c(j:j)) go to 30
 | |
|       enddo
 | |
|       j=37
 | |
|  30   j=j-1                                !Codes should start at zero
 | |
|       nc3=42*nc3 + j
 | |
|    enddo
 | |
| 
 | |
|  ! We now have used 17 bits in nc3.  Must move one each to nc1 and nc2.
 | |
|    nc1=nc1+nc1
 | |
|    if(iand(nc3,32768).ne.0) nc1=nc1+1
 | |
|    nc2=nc2+nc2
 | |
|    if(iand(nc3,65536).ne.0) nc2=nc2+1
 | |
|    nc3=iand(nc3,32767)
 | |
| 
 | |
|    return
 | |
|  end subroutine packtext
 | |
| 
 | |
|  subroutine unpacktext(nc1,nc2,nc3,msg)
 | |
| 
 | |
|    character*22 msg
 | |
|    character*44 c
 | |
|    data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?'/
 | |
| 
 | |
|    nc3=iand(nc3,32767)                      !Remove the "plain text" bit
 | |
|    if(iand(nc1,1).ne.0) nc3=nc3+32768
 | |
|    nc1=nc1/2
 | |
|    if(iand(nc2,1).ne.0) nc3=nc3+65536
 | |
|    nc2=nc2/2
 | |
| 
 | |
|    do i=5,1,-1
 | |
|       j=mod(nc1,42)+1
 | |
|       msg(i:i)=c(j:j)
 | |
|       nc1=nc1/42
 | |
|    enddo
 | |
| 
 | |
|    do i=10,6,-1
 | |
|       j=mod(nc2,42)+1
 | |
|       msg(i:i)=c(j:j)
 | |
|       nc2=nc2/42
 | |
|    enddo
 | |
| 
 | |
|    do i=13,11,-1
 | |
|       j=mod(nc3,42)+1
 | |
|       msg(i:i)=c(j:j)
 | |
|       nc3=nc3/42
 | |
|    enddo
 | |
|    msg(14:22) = '         '
 | |
| 
 | |
|    return
 | |
|  end subroutine unpacktext
 | |
| 
 | |
|  subroutine getpfx1(callsign,k,nv2)
 | |
| 
 | |
|    character*12 callsign0,callsign,lof,rof
 | |
|    character*8 c
 | |
|    character addpfx*8,tpfx*4,tsfx*3
 | |
|    logical ispfx,issfx,invalid
 | |
|    common/pfxcom/addpfx
 | |
|    include 'pfx.f90'
 | |
| 
 | |
|    callsign0=callsign
 | |
|    nv2=1
 | |
|    iz=index(callsign,' ') - 1
 | |
|    if(iz.lt.0) iz=12
 | |
|    islash=index(callsign(1:iz),'/')
 | |
|    k=0
 | |
|  !  if(k.eq.0) go to 10     !Tnx to DL9RDZ for reminder:this was for tests only!
 | |
|    c='   '
 | |
|    if(islash.gt.0 .and. islash.le.(iz-4)) then
 | |
|  ! Add-on prefix
 | |
|       c=callsign(1:islash-1)
 | |
|       callsign=callsign(islash+1:iz)
 | |
|       do i=1,NZ
 | |
|          if(pfx(i)(1:4).eq.c) then
 | |
|             k=i
 | |
|             nv2=2
 | |
|             go to 10
 | |
|          endif
 | |
|       enddo
 | |
|       if(addpfx.eq.c) then
 | |
|          k=449
 | |
|          nv2=2
 | |
|          go to 10
 | |
|       endif
 | |
| 
 | |
|    else if(islash.eq.(iz-1)) then
 | |
|  ! Add-on suffix
 | |
|       c=callsign(islash+1:iz)
 | |
|       callsign=callsign(1:islash-1)
 | |
|       do i=1,NZ2
 | |
|          if(sfx(i).eq.c(1:1)) then
 | |
|             k=400+i
 | |
|             nv2=3
 | |
|             go to 10
 | |
|          endif
 | |
|       enddo
 | |
|    endif
 | |
| 
 | |
|  10 if(islash.ne.0 .and.k.eq.0) then
 | |
|  ! Original JT65 would force this compound callsign to be treated as
 | |
|  ! plain text.  In JT65v2, we will encode the prefix or suffix into nc1.
 | |
|  ! The task here is to compute the proper value of k.
 | |
|       lof=callsign0(:islash-1)
 | |
|       rof=callsign0(islash+1:)
 | |
|       llof=len_trim(lof)
 | |
|       lrof=len_trim(rof)
 | |
|       ispfx=(llof.gt.0 .and. llof.le.4)
 | |
|       issfx=(lrof.gt.0 .and. lrof.le.3)
 | |
|       invalid=.not.(ispfx.or.issfx)
 | |
|       if(ispfx.and.issfx) then
 | |
|          if(llof.lt.3) issfx=.false.
 | |
|          if(lrof.lt.3) ispfx=.false.
 | |
|          if(ispfx.and.issfx) then
 | |
|             i=ichar(callsign0(islash-1:islash-1))
 | |
|             if(i.ge.ichar('0') .and. i.le.ichar('9')) then
 | |
|                issfx=.false.
 | |
|             else
 | |
|                ispfx=.false.
 | |
|             endif
 | |
|          endif
 | |
|       endif
 | |
| 
 | |
|       if(invalid) then
 | |
|          k=-1
 | |
|       else
 | |
|          if(ispfx) then
 | |
|             tpfx=lof(1:4)
 | |
|             k=nchar(tpfx(1:1))
 | |
|             k=37*k + nchar(tpfx(2:2))
 | |
|             k=37*k + nchar(tpfx(3:3))
 | |
|             k=37*k + nchar(tpfx(4:4))
 | |
|             nv2=4
 | |
|             i=index(callsign0,'/')
 | |
|             callsign=callsign0(:i-1)
 | |
|             callsign=callsign0(i+1:)
 | |
|          endif
 | |
|          if(issfx) then
 | |
|             tsfx=rof(1:3)
 | |
|             k=nchar(tsfx(1:1))
 | |
|             k=37*k + nchar(tsfx(2:2))
 | |
|             k=37*k + nchar(tsfx(3:3))
 | |
|             nv2=5
 | |
|             i=index(callsign0,'/')
 | |
|             callsign=callsign0(:i-1)
 | |
|          endif
 | |
|       endif
 | |
|    endif
 | |
| 
 | |
|    return
 | |
|  end subroutine getpfx1
 | |
| 
 | |
|  subroutine getpfx2(k0,callsign)
 | |
| 
 | |
|    character callsign*12
 | |
|    include 'pfx.f90'
 | |
|    character addpfx*8
 | |
|    common/pfxcom/addpfx
 | |
| 
 | |
|    k=k0
 | |
|    if(k.gt.450) k=k-450
 | |
|    if(k.ge.1 .and. k.le.NZ) then
 | |
|       iz=index(pfx(k),' ') - 1
 | |
|       callsign=pfx(k)(1:iz)//'/'//callsign
 | |
|    else if(k.ge.401 .and. k.le.400+NZ2) then
 | |
|       iz=index(callsign,' ') - 1
 | |
|       callsign=callsign(1:iz)//'/'//sfx(k-400)
 | |
|    else if(k.eq.449) then
 | |
|       iz=index(addpfx,' ') - 1
 | |
|       if(iz.lt.1) iz=8
 | |
|       callsign=addpfx(1:iz)//'/'//callsign
 | |
|    endif
 | |
| 
 | |
|    return
 | |
|  end subroutine getpfx2
 | |
| 
 | |
|  subroutine grid2k(grid,k)
 | |
| 
 | |
|    character*6 grid
 | |
| 
 | |
|    call grid2deg(grid,xlong,xlat)
 | |
|    nlong=nint(xlong)
 | |
|    nlat=nint(xlat)
 | |
|    k=0
 | |
|    if(nlat.ge.85) k=5*(nlong+179)/2 + nlat-84
 | |
| 
 | |
|    return
 | |
|  end subroutine grid2k
 | |
| 
 | |
|  subroutine k2grid(k,grid)
 | |
|    character grid*6
 | |
| 
 | |
|    nlong=2*mod((k-1)/5,90)-179
 | |
|    if(k.gt.450) nlong=nlong+180
 | |
|    nlat=mod(k-1,5)+ 85
 | |
|    dlat=nlat
 | |
|    dlong=nlong
 | |
|    call deg2grid(dlong,dlat,grid)
 | |
| 
 | |
|    return
 | |
|  end subroutine k2grid
 | |
| 
 | |
|  subroutine grid2n(grid,n)
 | |
|    character*4 grid
 | |
| 
 | |
|    i1=ichar(grid(1:1))-ichar('A')
 | |
|    i2=ichar(grid(3:3))-ichar('0')
 | |
|    i=10*i1 + i2
 | |
|    n=-i - 31
 | |
| 
 | |
|    return
 | |
|  end subroutine grid2n
 | |
| 
 | |
|  subroutine n2grid(n,grid)
 | |
|    character*4 grid
 | |
| 
 | |
|    if(n.gt.-31 .or. n.lt.-70) stop 'Error in n2grid'
 | |
|    i=-(n+31)                           !NB: 0 <= i <= 39
 | |
|    i1=i/10
 | |
|    i2=mod(i,10)
 | |
|    grid(1:1)=char(ichar('A')+i1)
 | |
|    grid(2:2)='A'
 | |
|    grid(3:3)=char(ichar('0')+i2)
 | |
|    grid(4:4)='0'
 | |
| 
 | |
|    return
 | |
|  end subroutine n2grid
 | |
| 
 | |
|  function nchar(c)
 | |
| 
 | |
|  ! Convert ascii number, letter, or space to 0-36 for callsign packing.
 | |
| 
 | |
|    character c*1
 | |
| 
 | |
|    n=0                                    !Silence compiler warning
 | |
|    if(c.ge.'0' .and. c.le.'9') then
 | |
|       n=ichar(c)-ichar('0')
 | |
|    else if(c.ge.'A' .and. c.le.'Z') then
 | |
|       n=ichar(c)-ichar('A') + 10
 | |
|    else if(c.ge.'a' .and. c.le.'z') then
 | |
|       n=ichar(c)-ichar('a') + 10
 | |
|    else if(c.ge.' ') then
 | |
|       n=36
 | |
|    else
 | |
|       Print*,'Invalid character in callsign ',c,' ',ichar(c)
 | |
|       stop
 | |
|    endif
 | |
|    nchar=n
 | |
| 
 | |
|    return
 | |
|  end function nchar
 | |
| 
 | |
|  subroutine pack50(n1,n2,dat)
 | |
| 
 | |
|    integer*1 dat(:),i1
 | |
| 
 | |
|    i1=iand(ishft(n1,-20),255)                !8 bits
 | |
|    dat(1)=i1
 | |
|    i1=iand(ishft(n1,-12),255)                 !8 bits
 | |
|    dat(2)=i1
 | |
|    i1=iand(ishft(n1, -4),255)                 !8 bits
 | |
|    dat(3)=i1
 | |
|    i1=16*iand(n1,15)+iand(ishft(n2,-18),15)   !4+4 bits
 | |
|    dat(4)=i1
 | |
|    i1=iand(ishft(n2,-10),255)                 !8 bits
 | |
|    dat(5)=i1
 | |
|    i1=iand(ishft(n2, -2),255)                 !8 bits
 | |
|    dat(6)=i1
 | |
|    i1=64*iand(n2,3)                           !2 bits
 | |
|    dat(7)=i1
 | |
|    dat(8)=0
 | |
|    dat(9)=0
 | |
|    dat(10)=0
 | |
|    dat(11)=0
 | |
| 
 | |
|    return
 | |
|  end subroutine pack50
 | |
| 
 | |
| subroutine packpfx(call1,n1,ng,nadd)
 | |
| 
 | |
|   character*12 call1,call0
 | |
|   character*3 pfx
 | |
|   logical text
 | |
| 
 | |
|   i1=index(call1,'/')
 | |
|   if(call1(i1+2:i1+2).eq.' ') then
 | |
| ! Single-character add-on suffix (maybe also fourth suffix letter?)
 | |
|      call0=call1(:i1-1)
 | |
|      call packcall(call0,n1,text)
 | |
|      nadd=1
 | |
|      nc=ichar(call1(i1+1:i1+1))
 | |
|      if(nc.ge.48 .and. nc.le.57) then
 | |
|         n=nc-48
 | |
|      else if(nc.ge.65 .and. nc.le.90) then
 | |
|         n=nc-65+10
 | |
|      else
 | |
|         n=38
 | |
|      endif
 | |
|      nadd=1
 | |
|      ng=60000-32768+n
 | |
|   else if(call1(i1+3:i1+3).eq.' ') then
 | |
| ! Two-character numerical suffix, /10 to /99
 | |
|      call0=call1(:i1-1)
 | |
|      call packcall(call0,n1,text)
 | |
|      nadd=1
 | |
|      n=10*(ichar(call1(i1+1:i1+1))-48) + ichar(call1(i1+2:i1+2)) - 48
 | |
|      nadd=1
 | |
|      ng=60000 + 26 + n
 | |
|   else
 | |
| ! Prefix of 1 to 3 characters
 | |
|      pfx=call1(:i1-1)
 | |
|      if(pfx(3:3).eq.' ') pfx=' '//pfx(1:2)
 | |
|      if(pfx(3:3).eq.' ') pfx=' '//pfx(1:2)
 | |
|      call0=call1(i1+1:)
 | |
|      call packcall(call0,n1,text)
 | |
| 
 | |
|      ng=0
 | |
|      do i=1,3
 | |
|         nc=ichar(pfx(i:i))
 | |
|         if(nc.ge.48 .and. nc.le.57) then
 | |
|            n=nc-48
 | |
|         else if(nc.ge.65 .and. nc.le.90) then
 | |
|            n=nc-65+10
 | |
|         else
 | |
|            n=36
 | |
|         endif
 | |
|         ng=37*ng + n
 | |
|      enddo
 | |
|      nadd=0
 | |
|      if(ng.ge.32768) then
 | |
|         ng=ng-32768
 | |
|         nadd=1
 | |
|      endif
 | |
|   endif
 | |
| 
 | |
|   return
 | |
| end subroutine packpfx
 | |
| 
 | |
| end module packjt
 |