diff --git a/common.h b/common.h
index 471c170..c7af27f 100644
--- a/common.h
+++ b/common.h
@@ -15,6 +15,8 @@ extern guchar *StoredLum;
extern pthread_t thread1;
extern guchar VISmap[];
+#define VIS_PARITY_ODD (1 << 7)
+
typedef struct _FFTStuff FFTStuff;
struct _FFTStuff {
double *in;
@@ -93,12 +95,12 @@ extern PicMeta CurrentPic;
// SSTV modes
enum {
UNKNOWN=0,
- M1, M2, M3, M4,
- S1, S2, SDX,
- R72, R36, R24, R24BW, R12BW, R8BW,
- PD50, PD90, PD120, PD160, PD180, PD240, PD290,
- P3, P5, P7,
- W2120, W2180
+ M1, M2, M3, M4,
+ S1, S2, SDX,
+ R72, R36, R24, R24BW, R12BW, R8BW,
+ PD50, PD90, PD120, PD160, PD180, PD240, PD290,
+ P3, P5, P7,
+ W260, W2120, W2180
};
// Color encodings
diff --git a/modespec.c b/modespec.c
index ff9d7b4..5ff0059 100644
--- a/modespec.c
+++ b/modespec.c
@@ -204,7 +204,22 @@ _ModeSpec ModeSpec[] = {
.NumLines = 120,
.LineHeight = 2,
.ColorEnc = BW },
-
+
+ [W260] = {
+ // Reverse-engineered by taking half the W2120 pixel time as an educated guess then
+ // tweaking the generated image timings until QSSTV decoded them without slant. -- VK4MSL
+ .Name = "Wraase SC-2 60",
+ .ShortName = "W260",
+ .SyncTime = 5.5225e-3,
+ .PorchTime = 0.0e-3,
+ .SeptrTime = 0.5e-3,
+ .PixelTime = 0.2425859375e-3,
+ .LineTime = 240.405e-3,
+ .ImgWidth = 320,
+ .NumLines = 256,
+ .LineHeight = 1,
+ .ColorEnc = RGB },
+
[W2120] = { // KB4YZ, 1999
.Name = "Wraase SC-2 120",
.ShortName = "W2120",
@@ -371,15 +386,26 @@ _ModeSpec ModeSpec[] = {
*
*/
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
-
-guchar VISmap[] = { 0, 0, R8BW, 0, R24, 0, R12BW,0, R36, 0, R24BW,0, R72, 0, 0, 0, // 0
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
- M4, 0, 0, 0, M3, 0, 0, 0, M2, 0, 0, 0, M1, 0, 0, 0, // 2
- 0, 0, 0, 0, 0, 0, 0, W2180,S2, 0, 0, 0, S1, 0, 0, W2120, // 3
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SDX, 0, 0, 0, // 4
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PD50,PD290,PD120, // 5
- PD180,PD240,PD160,PD90,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
- 0, P3, P5, P7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 7
-
-// 0 1 2 3 4 5 6 7 8 9 A B C D E F
+// 0 1 2 3 4 5 6 7 8 9 A B C D E F
+
+guchar VISmap[] = {
+ // Normal (even) parity
+ 0, 0, R8BW, 0, R24, 0, 0, 0, R36, 0, R24BW,0, R72, 0, 0, 0, // 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
+ M4, 0, 0, 0, M3, 0, 0, 0, M2, 0, 0, 0, M1, 0, 0, 0, // 2
+ 0, 0, 0, 0, 0, 0, 0, W2180,S2, 0, 0, 0, S1, 0, 0, W2120, // 3
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SDX, 0, 0, 0, // 4
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PD50,PD290,PD120, // 5
+ PD180,PD240,PD160,PD90,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
+ 0, P3, P5, P7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
+ // Inverted (odd) parity
+ 0, 0, 0, 0, 0, 0, R12BW,0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W260, 0, 0, 0, 0, // B
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // F
+
+// 0 1 2 3 4 5 6 7 8 9 A B C D E F
diff --git a/slowrx.ui b/slowrx.ui
index 85e5d62..8125b7e 100644
--- a/slowrx.ui
+++ b/slowrx.ui
@@ -638,6 +638,7 @@
- Pasokon P3
- Pasokon P5
- Pasokon P7
+ - Wraase SC-2 60
- Wraase SC-2 120
- Wraase SC-2 180
diff --git a/vis.c b/vis.c
index 6f7eb26..0adf3bd 100644
--- a/vis.c
+++ b/vis.c
@@ -7,6 +7,14 @@
#include "common.h"
+/* Handle selection of the VIS mode in the GUI */
+static void onGotVis(guchar VIS) {
+ gdk_threads_enter();
+ gtk_combo_box_set_active (GTK_COMBO_BOX(gui.combo_mode), VISmap[VIS]-1);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(gui.spin_shift), CurrentPic.HedrShift);
+ gdk_threads_leave();
+}
+
/*
*
* Detect VIS & frequency shift
@@ -113,19 +121,24 @@ guchar GetVIS () {
Parity = Bit[0] ^ Bit[1] ^ Bit[2] ^ Bit[3] ^ Bit[4] ^ Bit[5] ^ Bit[6];
- if (VISmap[VIS] == R12BW) Parity = !Parity;
-
if (Parity != ParityBit) {
- printf(" Parity fail\n");
- gotvis = FALSE;
+ // Maybe this mode uses odd parity?
+ printf(" Parity inconclusive, trying odd parity\n");
+ if (VISmap[VIS | VIS_PARITY_ODD] == UNKNOWN) {
+ // Nope!
+ printf(" Parity fail\n");
+ gotvis = FALSE;
+ } else {
+ // Yep, that was it. Inverted parity.
+ VIS |= VIS_PARITY_ODD;
+ onGotVis(VIS);
+ break;
+ }
} else if (VISmap[VIS] == UNKNOWN) {
printf(" Unknown VIS\n");
gotvis = FALSE;
} else {
- gdk_threads_enter();
- gtk_combo_box_set_active (GTK_COMBO_BOX(gui.combo_mode), VISmap[VIS]-1);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(gui.spin_shift), CurrentPic.HedrShift);
- gdk_threads_leave();
+ onGotVis(VIS);
break;
}
}