diff -Naur vdr-plugin-osdteletext/menu.c osdteletext/menu.c
--- vdr-plugin-osdteletext/menu.c	2009-10-25 13:39:35.000000000 +0100
+++ osdteletext/menu.c	2009-10-25 13:27:58.000000000 +0100
@@ -19,6 +19,12 @@
 #include "setup.h"
 #include "txtrecv.h"
 
+// begin workaround for #include "tables.h"
+extern unsigned char invtab[];
+extern unsigned char unhamtab[];
+extern unsigned char cct2vtx_table[];
+// end workaround
+
 #define GET_HUNDREDS(x) ( ( (x) - ((x)%256) ) /256 )
 #define GET_TENS(x)  ( (( (x) - ((x)%16) )%256 ) /16 )
 #define GET_ONES(x)   ( (x)%16 )
@@ -59,6 +65,10 @@
    pageBeforeNumberInput=currentPage;
    lastActivity=time(NULL);
    inactivityTimeout=-1;
+   for (int i = 0; i < 4; i++) {
+     flofPage[i]=0x100;
+     flofSubPage[i]=0;
+   }
 }
 
 
@@ -235,7 +245,6 @@
          Display::ShowUpperHalf();
          ShowPage();
          break; 
-         
               
       case kRed: 
       case kGreen: 
@@ -256,6 +265,7 @@
 }
 
 void TeletextBrowser::ExecuteAction(eTeletextAction e) {
+	     int flofIndex = 0;
          switch (e) {
             case Zoom:
                if (selectingChannel) {
@@ -312,6 +322,28 @@
             case DarkScreen:
                ChangeBackground();
                break;
+			case FLOFBlue:
+               flofIndex++;
+            case FLOFYellow:
+               flofIndex++;
+            case FLOFGreen:
+               flofIndex++;
+            case FLOFRed:
+               if (selectingChannel) {
+                  selectingChannel=false;
+                   Display::ClearMessage();
+               }
+               if (cursorPos != 0) {
+                  SetNumber(-3);
+               }
+			   SetPreviousPage(currentPage, currentSubPage, flofPage[flofIndex]);
+			   
+			   currentPage=flofPage[flofIndex];
+			   cursorPos=0;
+			   currentSubPage=flofSubPage[flofIndex];
+			   Display::ShowUpperHalf();
+			   ShowPage();
+			   break;
             default:
                //In osdteletext.c, numbers are thought to be decimal, the setup page
                //entries will display them in this way. It is a lot easier to do the
@@ -571,7 +603,7 @@
 //this is taken and adapted from the teletext plugin since it uses its data
 bool TeletextBrowser::DecodePage() {
    // Load the page and decodes it
-   unsigned char cache[40*24+12];
+   unsigned char cache[40*26+12];
    StorageHandle fd;
    // Take a look if there is a xxx-00 page
    Storage *s=Storage::instance();
@@ -597,6 +629,22 @@
       ShowPageNumber();
       UpdateClock();
       Display::ReleaseFlush();
+	  // update FLOF link pages, see http://pdc.ro.nu/teletext.html
+      unsigned short c[3];
+      int mag, mag8, subno;
+      unsigned char *z = cache + 12 + 25*40 + 1;
+      for (int i=0;i!=4;i++) {
+          for (int j=0;j!=3;j++) {
+              // z = 12 + 25*40 + 1 + i*6 + j*2
+              c[j] = unhamtab[*z++] & 0x0f;
+              c[j] |= (unhamtab[*z++] & 0x0f) << 4;
+          }
+          mag = ((c[1] >> 7) | ((c[2] >> 6) << 1)) ^ (currentPage >> 8);
+          mag8 = mag ?: 8;
+          flofPage[i] = c[0] | (mag8 << 8);
+          subno = (c[1] | (c[2] << 8)) & 0x3f7f;
+          flofSubPage[i] = (subno != 0x3f7f) ? subno : 0;
+      }
    } else {
       // page doesn't exist
       currentSubPage--;
@@ -623,7 +671,7 @@
    
    Storage *s=Storage::instance();
    if ((fd=s->openForReading(PageID(channel, currentPage, currentSubPage), false)) ) {
-      uchar cache[960];
+      uchar cache[1040];
       s->read(cache, 12, fd); //skip
       s->read(cache, sizeof(cache), fd);
       s->close(fd);
diff -Naur vdr-plugin-osdteletext/menu.h osdteletext/menu.h
--- vdr-plugin-osdteletext/menu.h	2009-10-25 13:39:35.000000000 +0100
+++ osdteletext/menu.h	2009-10-25 13:07:13.000000000 +0100
@@ -47,7 +47,7 @@
    void ExecuteAction(eTeletextAction e);
    int nextValidPageNumber(int start, Direction direction);
    char fileName[PATH_MAX];
-   char page[40][24];
+   char page[40][25];
    int cursorPos;
    eTeletextAction TranslateKey(eKeys Key);
    bool pageFound;
@@ -67,6 +67,8 @@
    static tChannelID channel;
    static int currentChannelNumber;
    static TeletextBrowser* self;
+   int flofPage[4];
+   int flofSubPage[4];
 private:
    void ChangeBackground();
 };
diff -Naur vdr-plugin-osdteletext/osdteletext.c osdteletext/osdteletext.c
--- vdr-plugin-osdteletext/osdteletext.c	2009-10-25 13:39:35.000000000 +0100
+++ osdteletext/osdteletext.c	2009-10-25 13:05:52.000000000 +0100
@@ -209,6 +209,10 @@
       tr("Change channel"),
       tr("Switch background"),
       //tr("Suspend receiving"),
+      tr("FLOF Red"),
+      tr("FLOF Green"),
+      tr("FLOF Yellow"),
+      tr("FLOF Blue"),
       tr("Jump to...")
    };
    
diff -Naur vdr-plugin-osdteletext/setup.h osdteletext/setup.h
--- vdr-plugin-osdteletext/setup.h	2009-10-25 13:39:35.000000000 +0100
+++ osdteletext/setup.h	2009-10-25 13:04:12.000000000 +0100
@@ -16,7 +16,9 @@
 //TeletextBrowser::TranslateKey and 
 //the constants in cPluginTeletextosd::initTexts
 enum eTeletextAction { Zoom, HalfPage, SwitchChannel,
-                       DarkScreen, /*SuspendReceiving,*/ LastAction }; //and 100-899 => jump to page
+                       DarkScreen, /*SuspendReceiving,*/ 
+					   FLOFRed, FLOFGreen, FLOFYellow, FLOFBlue,
+					   LastAction }; //and 100-899 => jump to page
 
 enum ActionKeys {
 ActionKeyRed,
diff -Naur vdr-plugin-osdteletext/txtrecv.c osdteletext/txtrecv.c
--- vdr-plugin-osdteletext/txtrecv.c	2009-10-25 13:39:35.000000000 +0100
+++ osdteletext/txtrecv.c	2009-10-25 13:03:15.000000000 +0100
@@ -200,7 +200,7 @@
    failedFreeSpace=false;
 }
 
-#define TELETEXT_PAGESIZE 972
+#define TELETEXT_PAGESIZE 1052
 
 LegacyStorage::LegacyStorage() {
    maxBytes=0;
@@ -485,7 +485,7 @@
       buf=lang; s->write(&buf,1,fd);
       buf=0x00; s->write(&buf,1,fd);
       buf=0x00; s->write(&buf,1,fd);
-      s->write(pagebuf,24*40,fd);
+      s->write(pagebuf,26*40,fd);
       s->close(fd);
    }         
 }
@@ -704,11 +704,19 @@
       TxtPage->SetLine((int)line,(uchar *)ptr);
       break;
       }
-   case 1 ... 25: 
+   case 1 ... 24: 
       {
       if (TxtPage) TxtPage->SetLine((int)line,(uchar *)ptr); 
       break;
       }
+   case 25:
+        // overwrite row 0, but only if not in subtitle mode
+        if (TxtPage && !(flags & 0x30)) TxtPage->SetLine((int)0,(uchar *)ptr);
+        break;
+   case 27:
+        // we only want 27/0, see http://pdc.ro.nu/teletext.html
+        if (TxtPage && !(unham16(ptr) & 0x0f)) TxtPage->SetLine((int)25,(uchar *)ptr);
+        break;
    /*case 23: 
       {
       if (TxtPage) {
diff -Naur vdr-plugin-osdteletext/txtrender.c osdteletext/txtrender.c
--- vdr-plugin-osdteletext/txtrender.c	2009-10-25 13:39:35.000000000 +0100
+++ osdteletext/txtrender.c	2009-10-25 13:15:46.000000000 +0100
@@ -285,7 +285,7 @@
     // Reserved for later use:
     // enumCharsets FirstG2=GetG2Charset(LocalG0CodePage);
     
-    for (y=0;y<24;(EmptyNextLine?y+=2:y++)) {
+    for (y=0;y<25;(EmptyNextLine?y+=2:y++)) {
         // Start of line: Set start of line defaults
         
         // Hold Mosaics mode: Remember last mosaic char/charset 
@@ -410,7 +410,7 @@
             }
             
             // Handle double-height and double-width extremes
-            if (y>=23) {
+            if (y>=24) {
                 if (Size==sizeDoubleHeight) Size=sizeNormal;
                 if (Size==sizeDoubleSize) Size=sizeDoubleWidth;
             }
@@ -429,7 +429,7 @@
                 case sizeNormal:
                     // Normal sized
                     SetChar(x,y,c2);
-                    if (EmptyNextLine && y<23) {
+        		    if (EmptyNextLine && y<24) {
                         // Clean up next line
                         SetChar(x,y+1,c2.ToChar(' ').ToCharset(FirstG0));
                     }
@@ -438,7 +438,7 @@
                     // Double width
                     SetChar(x,y,c2.ToDblWidth(dblw_Left));
                     SetChar(x+1,y,c2.ToDblWidth(dblw_Right));
-                    if (EmptyNextLine && y<23) {
+                    if (EmptyNextLine && y<24) {						
                         // Clean up next line
                         SetChar(x  ,y+1,c2.ToChar(' ').ToCharset(FirstG0));
                         SetChar(x+1,y+1,c2.ToChar(' ').ToCharset(FirstG0));
@@ -525,7 +525,7 @@
             }
         } // end for x
     } // end for y
-    
+    /*
     for (x=0;x<40;x++) {
         // Clean out last line
         cTeletextChar c;
@@ -537,7 +537,8 @@
             c.SetBoxedOut(true);    
         }
         SetChar(x,24,c);
-    }       
+    }     
+	*/
 }
 
 
