diff --git a/lib/jt65code.f90 b/lib/jt65code.f90 index 961ffe557..e20166b8a 100644 --- a/lib/jt65code.f90 +++ b/lib/jt65code.f90 @@ -1,85 +1,101 @@ -program JT65code - -! Provides examples of message packing, bit and symbol ordering, -! Reed Solomon encoding, and other necessary details of the JT65 -! protocol. - - use packjt - character*22 msg,msg0,msg1,decoded,cok*3,bad*1,msgtype*10 - integer dgen(12),sent(63),tmp(63),recd(12),era(51) - include 'testmsg.f90' - - nargs=iargc() - if(nargs.ne.1) then - print*,'Usage: jt65code "message"' - print*,' jt65code -t' - go to 999 - endif - - call getarg(1,msg) !Get message from command line - nmsg=1 - if(msg(1:2).eq."-t") then - testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO" - testmsg(NTEST+2)="KA1ABC WB9XYZ OOO" - testmsg(NTEST+3)="RO" - testmsg(NTEST+4)="RRR" - testmsg(NTEST+5)="73" - nmsg=NTEST+5 - endif - - write(*,1010) -1010 format(" Message Decoded Err? Type"/ & - 74("-")) - - do imsg=1,nmsg - if(nmsg.gt.1) msg=testmsg(imsg) - - call fmtmsg(msg,iz) !To upper, collapse mult blanks - msg0=msg !Input message - call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report - msg1=msg !Message without "OOO" - - if(nspecial.gt.0) then !or is a shorthand message - if(nspecial.eq.2) decoded="RO" - if(nspecial.eq.3) decoded="RRR" - if(nspecial.eq.4) decoded="73" - itype=-1 - msgtype="Shorthand" - go to 10 - endif - - call packmsg(msg1,dgen,itype) !Pack message into 12 six-bit bytes - msgtype="" - if(itype.eq.1) msgtype="Std Msg" - if(itype.eq.2) msgtype="Type 1 pfx" - if(itype.eq.3) msgtype="Type 1 sfx" - if(itype.eq.4) msgtype="Type 2 pfx" - if(itype.eq.5) msgtype="Type 2 sfx" - if(itype.eq.6) msgtype="Free text" - - call rs_encode(dgen,sent) !RS encode - call interleave63(sent,1) !Interleave channel symbols - call graycode(sent,63,1,sent) !Apply Gray code - - call graycode(sent,63,-1,tmp) !Remove Gray code - call interleave63(tmp,-1) !Remove interleaving - call rs_decode(tmp,era,0,recd,nerr) !Decode the message - call unpackmsg(recd,decoded) !Unpack the user message - if(cok.eq."OOO") decoded(20:22)=cok - call fmtmsg(decoded,iz) - -10 bad=" " - if(decoded.ne.msg0) bad="*" - write(*,1020) imsg,msg0,decoded,bad,itype,msgtype -1020 format(i2,'.',2x,a22,2x,a22,3x,a1,i3,": ",a13) - enddo - - if(nmsg.eq.1 .and. nspecial.eq.0) then - write(*,1030) dgen -1030 format(/'Packed message, 6-bit symbols ',12i3) !Display packed symbols - - write(*,1040) sent -1040 format(/'Information-carrying channel symbols'/(i5,20i3)) - endif - -999 end program JT65code +program JT65code + +! Provides examples of message packing, bit and symbol ordering, +! Reed Solomon encoding, and other necessary details of the JT65 +! protocol. + + use packjt + character*22 msg,msgchk,msg0,msg1,decoded,cok*3,bad*1,msgtype*10,expected + integer dgen(12),sent(63),tmp(63),recd(12),era(51) + include 'testmsg.f90' + + nargs=iargc() + if(nargs.ne.1) then + print*,'Usage: jt65code "message"' + print*,' jt65code -t' + go to 999 + endif + + call getarg(1,msg) !Get message from command line + msgchk=msg + call fmtmsg(msgchk,iz) + nmsg=1 + if(msg(1:2).eq."-t") then + if (NTEST+5 > MAXTEST) then + write(*,*) "NTEST exceed MAXTEST" + endif + testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO" + testmsg(NTEST+2)="KA1ABC WB9XYZ OOO" + testmsg(NTEST+3)="RO" + testmsg(NTEST+4)="RRR" + testmsg(NTEST+5)="73" + testmsgchk(NTEST+1)="KA1ABC WB9XYZ EN34 OOO" + testmsgchk(NTEST+2)="KA1ABC WB9XYZ OOO" + testmsgchk(NTEST+3)="RO" + testmsgchk(NTEST+4)="RRR" + testmsgchk(NTEST+5)="73" + nmsg=NTEST+5 + endif + + write(*,1010) +1010 format(" Message Decoded Err? Type Expected"/ & + 76("-")) + + do imsg=1,nmsg + if(nmsg.gt.1) then + msg=testmsg(imsg) + msgchk=testmsgchk(imsg) + endif + + call fmtmsg(msg,iz) !To upper, collapse mult blanks + msg0=msg !Input message + call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report + msg1=msg !Message without "OOO" + + if(nspecial.gt.0) then !or is a shorthand message + if(nspecial.eq.2) decoded="RO" + if(nspecial.eq.3) decoded="RRR" + if(nspecial.eq.4) decoded="73" + itype=-1 + msgtype="Shorthand" + go to 10 + endif + + call packmsg(msg1,dgen,itype) !Pack message into 12 six-bit bytes + msgtype="" + if(itype.eq.1) msgtype="Std Msg" + if(itype.eq.2) msgtype="Type 1 pfx" + if(itype.eq.3) msgtype="Type 1 sfx" + if(itype.eq.4) msgtype="Type 2 pfx" + if(itype.eq.5) msgtype="Type 2 sfx" + if(itype.eq.6) msgtype="Free text" + + call rs_encode(dgen,sent) !RS encode + call interleave63(sent,1) !Interleave channel symbols + call graycode(sent,63,1,sent) !Apply Gray code + + call graycode(sent,63,-1,tmp) !Remove Gray code + call interleave63(tmp,-1) !Remove interleaving + call rs_decode(tmp,era,0,recd,nerr) !Decode the message + call unpackmsg(recd,decoded) !Unpack the user message + if(cok.eq."OOO") decoded(20:22)=cok + call fmtmsg(decoded,iz) + +10 bad=" " + if(decoded.ne.msgchk) bad="*" + expected = 'EXACT' + if (msg0.ne.msgchk) expected = 'TRUNCATED' + if (nmsg.eq.1) expected = 'UNKNOWN' + write(*,1020) imsg,msg0,decoded,bad,itype,msgtype,expected +1020 format(i2,'.',1x,a22,1x,a22,1x,a1,i3,":",a10,2x,a22) + enddo + + if(nmsg.eq.1 .and. nspecial.eq.0) then + write(*,1030) dgen +1030 format(/'Packed message, 6-bit symbols ',12i3) !Display packed symbols + + write(*,1040) sent +1040 format(/'Information-carrying channel symbols'/(i5,20i3)) + endif + +999 end program JT65code diff --git a/lib/jt9code.f90 b/lib/jt9code.f90 index afdcbd7d0..5a4b4fc83 100644 --- a/lib/jt9code.f90 +++ b/lib/jt9code.f90 @@ -1,47 +1,84 @@ -program jt9code - -! Generate simulated data for testing of WSJT-X - - character msg*22,decoded*22,bad*1,msgtype*13 - integer*4 i4tone(85) !Channel symbols (values 0-8) - include 'testmsg.f90' - include 'jt9sync.f90' - - nargs=iargc() - if(nargs.ne.1) then - print*,'Usage: jt9code "message"' - print*,' jt9code -t' - go to 999 - endif - - call getarg(1,msg) - nmsg=1 - if(msg(1:2).eq."-t") nmsg=NTEST - - write(*,1010) -1010 format(" Message Decoded Err? Type"/ & - 74("-")) - do imsg=1,nmsg - if(nmsg.gt.1) msg=testmsg(imsg) - call fmtmsg(msg,iz) !To upper case, collapse multiple blanks - ichk=0 - call gen9(msg,ichk,decoded,i4tone,itype) !Encode message into tone #s - - msgtype="" - if(itype.eq.1) msgtype="Std Msg" - if(itype.eq.2) msgtype="Type 1 prefix" - if(itype.eq.3) msgtype="Type 1 suffix" - if(itype.eq.4) msgtype="Type 2 prefix" - if(itype.eq.5) msgtype="Type 2 suffix" - if(itype.eq.6) msgtype="Free text" - - bad=" " - if(decoded.ne.msg) bad="*" - write(*,1020) imsg,msg,decoded,bad,itype,msgtype -1020 format(i2,'.',2x,a22,2x,a22,3x,a1,i3,": ",a13) - enddo - - if(nmsg.eq.1) write(*,1030) i4tone -1030 format(/'Channel symbols'/(30i2)) - -999 end program jt9code +program jt9code + +! Generate simulated data for testing of WSJT-X + + character*22 msg,msgchk,msg0,msg1,decoded,cok*3,bad*1,msgtype*10,expected + integer*4 i4tone(85) !Channel symbols (values 0-8) + include 'testmsg.f90' + include 'jt9sync.f90' + + nargs=iargc() + if(nargs.ne.1) then + print*,'Usage: jt9code "message"' + print*,' jt9code -t' + go to 999 + endif + + call getarg(1,msg) + nmsg=1 + if(msg(1:2).eq."-t") then + if (NTEST+5 > MAXTEST) then + write(*,*) "NTEST exceed MAXTEST" + endif + testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO" + testmsg(NTEST+2)="KA1ABC WB9XYZ OOO" + testmsg(NTEST+3)="RO" + testmsg(NTEST+4)="RRR" + testmsg(NTEST+5)="73" + testmsgchk(NTEST+1)="KA1ABC WB9XYZ EN34 OOO" + testmsgchk(NTEST+2)="KA1ABC WB9XYZ OOO" + testmsgchk(NTEST+3)="RO" + testmsgchk(NTEST+4)="RRR" + testmsgchk(NTEST+5)="73" + nmsg=NTEST+5 + endif + + write(*,1010) +1010 format(" Message Decoded Err? Type Expected"/ & + 76("-")) + do imsg=1,nmsg + if(nmsg.gt.1) then + msg=testmsg(imsg) + msgchk=testmsgchk(imsg) + endif + call fmtmsg(msg,iz) !To upper case, collapse multiple blanks + msg0=msg + ichk=0 + call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report + msg1=msg !Message without "OOO" + + if(nspecial.gt.0) then !or is a shorthand message + if(nspecial.eq.2) decoded="RO" + if(nspecial.eq.3) decoded="RRR" + if(nspecial.eq.4) decoded="73" + itype=-1 + msgtype="Shorthand" + go to 10 + endif + + call gen9(msg,ichk,decoded,i4tone,itype) !Encode message into tone #s + + msgtype="" + if(itype.eq.1) msgtype="Std Msg" + if(itype.eq.2) msgtype="Type 1 pfx" + if(itype.eq.3) msgtype="Type 1 sfx" + if(itype.eq.4) msgtype="Type 2 pfx" + if(itype.eq.5) msgtype="Type 2 sfx" + if(itype.eq.6) msgtype="Free text" + + if(cok.eq."OOO") decoded(20:22)=cok + call fmtmsg(decoded,iz) + +10 bad=" " + expected = 'EXACT' + if (msg0.ne.msgchk) expected = 'TRUNCATED' + if (nmsg.eq.1) expected = 'UNKNOWN' + if(decoded.ne.msgchk) bad="*" + write(*,1020) imsg,msg0,decoded,bad,itype,msgtype,expected +1020 format(i2,'.',1x,a22,1x,a22,1x,a1,i3,":",a10,2x,a22) + enddo + + if(nmsg.eq.1) write(*,1030) i4tone +1030 format(/'Channel symbols'/(30i2)) + +999 end program jt9code diff --git a/lib/packjt.f90 b/lib/packjt.f90 index 70df065d5..049af22ee 100644 --- a/lib/packjt.f90 +++ b/lib/packjt.f90 @@ -416,7 +416,7 @@ subroutine packbits(dbits,nsymd,m0,sym) call fmtmsg(msg,iz) if(msg(1:6).eq.'CQ DX ') msg(3:3)='9' - if(msg(1:3).eq."CQ " .and. & + 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:) @@ -478,13 +478,13 @@ subroutine packbits(dbits,nsymd,m0,sym) nc1=0 if(nv2b.eq.4) then - if(c1(1:3).eq.'CQ ') nc1=262178563 + k2 - if(c1(1:4).eq.'QRZ ') nc1=264002072 + k2 - if(c1(1:3).eq.'DE ') nc1=265825581 + k2 + 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 ') nc1=267649090 + k2 - if(c1(1:4).eq.'QRZ ') nc1=267698375 + k2 - if(c1(1:3).eq.'DE ') nc1=267747660 + k2 + 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 @@ -638,7 +638,7 @@ subroutine packbits(dbits,nsymd,m0,sym) subroutine packtext(msg,nc1,nc2,nc3) parameter (MASK28=2**28 - 1) - character*13 msg + character*22 msg character*42 c data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?'/ diff --git a/lib/testmsg.f90 b/lib/testmsg.f90 index 9c4a8a0cb..661c390a3 100644 --- a/lib/testmsg.f90 +++ b/lib/testmsg.f90 @@ -1,30 +1,145 @@ - parameter (MAXTEST=35,NTEST=27) - character*22 testmsg(MAXTEST) - data testmsg(1:NTEST)/ & - "CQ WB9XYZ EN34", & - "CQ DX WB9XYZ EN34", & - "QRZ WB9XYZ EN34", & - "KA1ABC WB9XYZ EN34", & - "KA1ABC WB9XYZ RO", & - "KA1ABC WB9XYZ -21", & - "KA1ABC WB9XYZ R-19", & - "KA1ABC WB9XYZ RRR", & - "KA1ABC WB9XYZ 73", & - "KA1ABC WB9XYZ", & - "CQ 000 WB9XYZ EN34", & - "CQ 999 WB9XYZ EN34", & - "CQ EU WB9XYZ EN34", & - "CQ WY WB9XYZ EN34", & - "ZL/KA1ABC WB9XYZ", & - "KA1ABC ZL/WB9XYZ", & - "KA1ABC/4 WB9XYZ", & - "KA1ABC WB9XYZ/4", & - "CQ ZL4/KA1ABC", & - "DE ZL4/KA1ABC", & - "QRZ ZL4/KA1ABC", & - "CQ WB9XYZ/VE4", & - "HELLO WORLD", & - "ZL4/KA1ABC 73", & - "KA1ABC XL/WB9XYZ", & - "KA1ABC WB9XYZ/W4", & - "123456789ABCDEFGH"/ + parameter (MAXTEST=75,NTEST=68) + character*22 testmsg(MAXTEST) + character*22 testmsgchk(MAXTEST) + ! Test msgs should include the extremes for the different types + ! See pfx.f90 + ! Type 1 P & A + ! Type 1 1A & E5 + data testmsg(1:NTEST)/ & + "CQ WB9XYZ EN34", & + "CQ DX WB9XYZ EN34", & + "QRZ WB9XYZ EN34", & + "KA1ABC WB9XYZ EN34", & + "KA1ABC WB9XYZ RO", & + "KA1ABC WB9XYZ -21", & + "KA1ABC WB9XYZ R-19", & + "KA1ABC WB9XYZ RRR", & + "KA1ABC WB9XYZ 73", & + "KA1ABC WB9XYZ", & + "CQ 000 WB9XYZ EN34", & + "CQ 999 WB9XYZ EN34", & + "CQ EU WB9XYZ EN34", & + "CQ WY WB9XYZ EN34", & + "1A/KA1ABC WB9XYZ", & + "E5/KA1ABC WB9XYZ", & + "KA1ABC 1A/WB9XYZ", & + "KA1ABC E5/WB9XYZ", & + "KA1ABC/P WB9XYZ", & + "KA1ABC/A WB9XYZ", & + "KA1ABC WB9XYZ/P", & + "KA1ABC WB9XYZ/A", & + "CQ KA1ABC/P", & + "CQ WB9XYZ/A", & + "QRZ KA1ABC/P", & + "QRZ WB9XYZ/A", & + "DE KA1ABC/P", & + "DE WB9XYZ/A", & + "CQ 1A/KA1ABC", & + "CQ E5/KA1ABC", & + "DE 1A/KA1ABC", & + "DE E5/KA1ABC", & + "QRZ 1A/KA1ABC", & + "QRZ E5/KA1ABC", & + "CQ WB9XYZ/1A", & + "CQ WB9XYZ/E5", & + "QRZ WB9XYZ/1A", & + "QRZ WB9XYZ/E5", & + "DE WB9XYZ/1A", & + "DE WB9XYZ/E5", & + "CQ A000/KA1ABC FM07", & + "CQ ZZZZ/KA1ABC FM07", & + "QRZ W4/KA1ABC FM07", & + "DE W4/KA1ABC FM07", & + "CQ W4/KA1ABC -22", & + "DE W4/KA1ABC -22", & + "QRZ W4/KA1ABC -22", & + "CQ W4/KA1ABC R-22", & + "DE W4/KA1ABC R-22", & + "QRZ W4/KA1ABC R-22", & + "DE W4/KA1ABC 73", & + "CQ KA1ABC FM07", & + "QRZ KA1ABC FM07", & + "DE KA1ABC/VE6 FM07", & + "CQ KA1ABC/VE6 -22", & + "DE KA1ABC/VE6 -22", & + "QRZ KA1ABC/VE6 -22", & + "CQ KA1ABC/VE6 R-22", & + "DE KA1ABC/VE6 R-22", & + "QRZ KA1ABC/VE6 R-22", & + "DE KA1ABC 73", & + "HELLO WORLD", & + "ZL4/KA1ABC 73", & + "KA1ABC XL/WB9XYZ", & + "KA1ABC WB9XYZ/W4", & + "DE KA1ABC/QRP 2W", & + "KA1ABC/1 WB9XYZ/1", & + "123456789ABCDEFGH"/ + data testmsgchk(1:NTEST)/ & + "CQ WB9XYZ EN34", & + "CQ DX WB9XYZ EN34", & + "QRZ WB9XYZ EN34", & + "KA1ABC WB9XYZ EN34", & + "KA1ABC WB9XYZ RO", & + "KA1ABC WB9XYZ -21", & + "KA1ABC WB9XYZ R-19", & + "KA1ABC WB9XYZ RRR", & + "KA1ABC WB9XYZ 73", & + "KA1ABC WB9XYZ", & + "CQ 000 WB9XYZ EN34", & + "CQ 999 WB9XYZ EN34", & + "CQ EU WB9XYZ EN34", & + "CQ WY WB9XYZ EN34", & + "1A/KA1ABC WB9XYZ", & + "E5/KA1ABC WB9XYZ", & + "KA1ABC 1A/WB9XYZ", & + "KA1ABC E5/WB9XYZ", & + "KA1ABC/P WB9XYZ", & + "KA1ABC/A WB9XYZ", & + "KA1ABC WB9XYZ/P", & + "KA1ABC WB9XYZ/A", & + "CQ KA1ABC/P", & + "CQ WB9XYZ/A", & + "QRZ KA1ABC/P", & + "QRZ WB9XYZ/A", & + "DE KA1ABC/P", & + "DE WB9XYZ/A", & + "CQ 1A/KA1ABC", & + "CQ E5/KA1ABC", & + "DE 1A/KA1ABC", & + "DE E5/KA1ABC", & + "QRZ 1A/KA1ABC", & + "QRZ E5/KA1ABC", & + "CQ WB9XYZ/1A", & + "CQ WB9XYZ/E5", & + "QRZ WB9XYZ/1A", & + "QRZ WB9XYZ/E5", & + "DE WB9XYZ/1A", & + "DE WB9XYZ/E5", & + "CQ A000/KA1ABC FM07", & + "CQ ZZZZ/KA1ABC FM07", & + "QRZ W4/KA1ABC FM07", & + "DE W4/KA1ABC FM07", & + "CQ W4/KA1ABC -22", & + "DE W4/KA1ABC -22", & + "QRZ W4/KA1ABC -22", & + "CQ W4/KA1ABC R-22", & + "DE W4/KA1ABC R-22", & + "QRZ W4/KA1ABC R-22", & + "DE W4/KA1ABC 73", & + "CQ KA1ABC FM07", & + "QRZ KA1ABC FM07", & + "DE KA1ABC/VE6 FM07", & + "CQ KA1ABC/VE6 -22", & + "DE KA1ABC/VE6 -22", & + "QRZ KA1ABC/VE6 -22", & + "CQ KA1ABC/VE6 R-22", & + "DE KA1ABC/VE6 R-22", & + "QRZ KA1ABC/VE6 R-22", & + "DE KA1ABC 73", & + "HELLO WORLD", & + "ZL4/KA1ABC 73", & + "KA1ABC XL/WB9", & + "KA1ABC WB9XYZ", & + "DE KA1ABC/QRP", & + "KA1ABC/1 WB9X", & + "123456789ABCD"/