Index: firmware_eclairexl/a800/mainmenu.c
===================================================================
--- firmware_eclairexl/a800/mainmenu.c	(revision 970)
+++ firmware_eclairexl/a800/mainmenu.c	(revision 971)
@@ -748,6 +748,10 @@
 	int tv;
 	int scanlines;
 	int csync;
+#ifdef PLL_SUPPORT
+	int resolution;
+	int scaler;
+#endif
 
 #ifndef NO_FLASH
 	int flashid1;
@@ -762,6 +766,10 @@
 	menuData2->tv = get_tv();
 	menuData2->scanlines = get_scanlines();
 	menuData2->csync = get_csync();
+#ifdef PLL_SUPPORT
+	menuData2->resolution = get_resolution();
+	menuData2->scaler = get_scaler();
+#endif
 }
 
 void updateMenuDataFlashInfo(struct MenuData * menuData2)
@@ -907,6 +915,48 @@
 	menuData2->tv = !menuData2->tv;
 }
 
+#ifdef PLL_SUPPORT
+void menuPrintScaler(void * menuData, void * itemData)
+{
+	struct MenuData * menuData2 = (struct MenuData *)menuData;
+	printf("Scaler:");
+	if (menuData2->scaler)
+		printf("Polyphasic");
+	else
+		printf("Area");
+}
+
+void menuScaler(void * menuData, struct joystick_status * joy)
+{
+	struct MenuData * menuData2 = (struct MenuData *)menuData;
+	menuData2->scaler = !menuData2->scaler;
+}
+
+void menuPrintResolution(void * menuData, void * itemData)
+{
+	struct MenuData * menuData2 = (struct MenuData *)menuData;
+
+	readFlash(romstart+0x30000,2048,SCRATCH_MEM);
+	uint8_t * addr = SCRATCH_MEM;
+	int mode = menuData2->resolution;
+	if (menuData2->tv == TV_NTSC)
+		mode = mode+4;
+	addr = addr + (mode<<8);
+
+	printf("Resolution:%s", addr); /*get_resolution(menuData2->resolution));*/
+}
+
+void menuResolution(void * menuData, struct joystick_status * joy)
+{
+	struct MenuData * menuData2 = (struct MenuData *)menuData;
+	menuData2->resolution = menuData2->resolution + joy->x_;
+	if (menuData2->resolution > 3)
+		menuData2->resolution = 3;
+	if (menuData2->resolution < 0)
+		menuData2->resolution = 0;
+}
+#endif
+
 void menuApplyVideo(void * menuData, struct joystick_status * joy)
 {
 	struct MenuData * menuData2 = (struct MenuData *)menuData;
@@ -915,7 +965,24 @@
 	set_scanlines(menuData2->scanlines);
 	set_csync(menuData2->csync);
 #ifdef PLL_SUPPORT
-	set_pll(get_tv()==TV_PAL, get_video()>=VIDEO_HDMI && get_video()<VIDEO_COMPOSITE);
+	set_resolution(menuData2->resolution);
+	set_scaler(menuData2->scaler);
+	if (get_video()>=VIDEO_HDMI && get_video()<VIDEO_COMPOSITE)
+	{
+		int mode = menuData2->resolution;
+		if (get_tv()==TV_NTSC)
+			mode = mode+4;
+
+		set_scaler_mode(mode);
+	}
+	else
+	{
+		if (get_tv()==TV_PAL)
+			set_pll(MODE_PAL_ORIG);
+		else
+			set_pll(MODE_NTSC_ORIG);
+
+	}
 #endif
 }
 
@@ -1092,6 +1159,10 @@
 		{&menuPrintTVStandard,0,&menuTVStandard,MENU_FLAG_FIRE},
 		{&menuPrintScanlines,0,&menuScanlines,MENU_FLAG_FIRE},
 		{&menuPrintCompositeSync,0,&menuCompositeSync,MENU_FLAG_FIRE},
+#ifdef PLL_SUPPORT
+		{&menuPrintScaler,0,&menuScaler,MENU_FLAG_FIRE},
+		{&menuPrintResolution,0,&menuResolution,MENU_FLAG_MOVE},
+#endif
 		{0,"Apply video",&menuApplyVideo,MENU_FLAG_FIRE},
 		{0,0,0,0}, //blank line
 #endif
Index: firmware_eclairexl/clkgen/pll2.c
===================================================================
--- firmware_eclairexl/clkgen/pll2.c	(revision 970)
+++ firmware_eclairexl/clkgen/pll2.c	(revision 971)
@@ -1,7 +1,9 @@
 #include "pll2.h"
 #include "Si5351A-RevB-Registers.h"
 #include "regs.h"
+#include "pll.h"
 #include "integer.h"
+#include "spibase.h"
 
 void set_pll2()
 {
@@ -26,3 +28,74 @@
 	}
 }
 
+void program_i2c_lh(unsigned int slave, int reg, uint8_t l, uint8_t h)
+{
+	unsigned int write = 0x0;
+	*zpu_i2c_0 = (slave<<9) | write<<8 | 0xf0 | reg;  // write addr (blocks until accepted)
+	*zpu_i2c_0 = (slave<<9) | write<<8 | l; // write data (blocks until accepted)
+	*zpu_i2c_0 = (slave<<9) | write<<8 | h; // write data (blocks until accepted)
+
+	while ((*zpu_i2c_0)&0x100); // wait until busy not asserted
+}
+
+void read16(uint16_t const * addr, uint8_t * l, uint8_t * h)
+{
+	uint8_t const * addr8 = (uint8_t const *)addr;
+	*l = addr8[1];
+	*h = addr8[0];
+}
+
+void program_i2c_videomode(unsigned int slave, uint16_t const * regs, unsigned int from, unsigned int noRegs)
+{
+	int i;
+	for (i=from;i!=noRegs;++i)
+	{
+		uint8_t l,h;
+		read16(regs+i,&l,&h);
+
+		program_i2c_lh(slave, i, l, h);
+	}
+}
+
+void set_crtc(uint16_t const * crtc_regs)
+{
+	program_i2c_lh(2,12,0,0); // disable576p
+
+
+	uint8_t l,h;
+	read16(crtc_regs+11,&l,&h);
+
+	program_i2c_lh(2,11,l,h); // set the clock!
+	program_i2c_lh(2,11,l,h); // set the clock again (looks like this transaction is lost after a clock change)
+
+	program_i2c_videomode(2,crtc_regs,0,10);
+	//program_i2c_lh(2,10,crtc_regs[10]); // set scaler and mode*/
+	int scal = get_scaler();
+	read16(crtc_regs+10,&l,&h);
+	program_i2c_lh(2,10,l,scal); // set scaler and mode*/
+	program_i2c_lh(2,12,1,0); // enable
+}
+
+void set_scale(uint16_t const * scale_regs)
+{
+	program_i2c_videomode(1,scale_regs,0,6);
+	program_i2c_videomode(3,scale_regs+6,0,3);
+}
+
+void set_scaler_mode(int mode)
+{
+	readFlash(romstart+0x30000,2048,SCRATCH_MEM);
+	uint8_t * addr = SCRATCH_MEM;
+	addr = addr + (mode<<8);
+
+	set_pll((video_pll_mode)*(addr+192));
+	set_crtc(addr+64);
+	set_scale(addr+128);
+/* mode layout
+ * 0  :name
+   64 :crtc
+   128:scaler
+   192:freq
+ */
+}
+
Index: firmware_eclairexl/clkgen/pll2.h
===================================================================
--- firmware_eclairexl/clkgen/pll2.h	(revision 970)
+++ firmware_eclairexl/clkgen/pll2.h	(revision 971)
@@ -3,5 +3,18 @@
 
 void set_pll2();
 
+void set_scaler(int type);
+
+void set_scaler_mode(int modeno);
+/*
+ * 0-3 PAL,4-7 NTSC
+ * 0=1400x576i
+ * 1=720x576p
+ * 2=1280x720p
+ * 3=1920x1080i
+ * etc
+ * Note that 720 and 1280 are <100% horiz scaling, so skip every other pixel
+ */
+
 #endif
 
Index: firmware_eclairexl/main.h
===================================================================
--- firmware_eclairexl/main.h	(revision 970)
+++ firmware_eclairexl/main.h	(revision 971)
@@ -7,6 +7,7 @@
 #include "joystick.h"
 #include "freeze.h"
 #include "vidi2c.h"
+#include "pll.h"
 
 #include "simpledir.h"
 #include "simplefile.h"
@@ -96,10 +97,12 @@
 BIT_REG(,0x07,28,turbo_drive,zpu_out1) 
 BIT_REG(,0x01,31,turbo_6502_vblank_only,zpu_out1) 
 
-BIT_REG(,0x07,0,video,zpu_out6)
+BIT_REG(,0x07,0,video,zpu_out6) // 4 bits,3 used... what to do...
 BIT_REG(,0x01,4,tv,zpu_out6)
 BIT_REG(,0x01,5,scanlines,zpu_out6)
 BIT_REG(,0x01,6,csync,zpu_out6)
+BIT_REG(,0x07,7,resolution,zpu_out6)
+BIT_REG(,0x07,10,scaler,zpu_out6) // 3 bits to allow multiple polyphasic filters
 
 #ifdef DEBUG_SUPPORT
 BIT_REG(,0xffff,0,debug_addr,zpu_out7)
@@ -502,7 +505,21 @@
 	*zpu_out6 = settings[1];
 		
 #ifdef PLL_SUPPORT
-	set_pll(get_tv()==TV_PAL, get_video()>=VIDEO_HDMI && get_video()<VIDEO_COMPOSITE);
+	if (get_video()>=VIDEO_HDMI && get_video()<VIDEO_COMPOSITE)
+	{
+		int mode = get_resolution();
+                if (get_tv()==TV_NTSC)
+                        mode = mode+4;
+
+                set_scaler_mode(mode);
+	}
+	else
+	{
+		if (get_tv()==TV_PAL)
+			set_pll(MODE_PAL_ORIG);
+		else
+			set_pll(MODE_NTSC_ORIG);
+	}
 #endif
 }
 
Index: firmware_eclairexl/pll/pll.c
===================================================================
--- firmware_eclairexl/pll/pll.c	(revision 970)
+++ firmware_eclairexl/pll/pll.c	(revision 971)
@@ -15,16 +15,17 @@
 	*pll_go = 1;
 }
 
-void set_pll(int pal, int hdmi)
+
+void set_pll(video_pll_mode mode)
 {
-	switch (pal<<1 | hdmi)
+	switch (mode)
 	{
-	case 0:
+	case MODE_NTSC_ORIG:
 		//ntsc_svideo
 		setVideoPLL(0x909,0x404,0x40404,0x80808,0xc1010,0x2,0x7,0x53c7fe31);
 		break;
 
-	case 1:
+	case MODE_NTSC_5994:
 		//ntsc_5994
 		//5994! Should be 2700000/525/858 (60/1001) 
 		//setVideoPLL(0x20f0e,0x20706,0x60706,0x80d0d,0xc1a1a,0x2,0x7,0xca571058);
@@ -31,7 +32,12 @@
 		//RAM fails!M=29?? Too high FVCO? setVideoPLL(0x20f0e,0x20706,0x60706,0x80d0d,0xc1a1a,0x2,0x7,0xca590425);
 		setVideoPLL(0xa0a,0x20504,0x60504,0x80909,0xc1212,0x2,0x7,0x9fc77906);
 		break;
-	case 2:
+
+	case MODE_NTSC_60:
+		// ntsc_6000 (for 720p)
+		setVideoPLL(0xa0a,0x20504,0x60504,0x80909,0xc1212,0x2,0x7,0xA50F18A2);
+		break;
+	case MODE_PAL_ORIG:
 		//pal_svideo
 		//RAM fails!!M=29?? Too high FVCO? setVideoPLL(0x20f0e,0x20706,0x60706,0x80d0d,0xc1a1a,0x2,0x7,0x829a43e4);
 		//Works, but less accurate setVideoPLL(0x20504,0x202,0x40202,0x80404,0xc0808,0x2,0x7,0x147e3bf0);
@@ -38,7 +44,7 @@
 		setVideoPLL(0xa0a,0x20504,0x60504,0x80909,0xc1212,0x2,0x7,0x6e1c079e);
 		break;
 
-	case 3:
+	case MODE_PAL_50:
 		//pal_50
 		setVideoPLL(0x20605,0x20302,0x60302,0x80505,0xc0a0a,0x3,0x8,0x61bb05fb);
 		break;
Index: firmware_eclairexl/pll/pll.h
===================================================================
--- firmware_eclairexl/pll/pll.h	(revision 970)
+++ firmware_eclairexl/pll/pll.h	(revision 971)
@@ -1,7 +1,8 @@
 #ifndef PLL_H
 #define PLL_H
 
-void set_pll(int pal, int hdmi);
+typedef enum {MODE_NTSC_5994=0,MODE_NTSC_60=1,MODE_PAL_50=2,MODE_PAL_ORIG=3,MODE_NTSC_ORIG=4} video_pll_mode;
+void set_pll(video_pll_mode mode);
 
 #endif
 
