[hatari-devel] Falcon video counter

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Hi,

Since Laurent moved all Videl register handling to falcon/videl.c
(sometime after Hatari v1.6), several programs have been broken
because that removed support for Falcon video address counter.

Attached is patch adding minimal support for that.  It fixes
"Lasers and Hommes" (DLDH2), that doesn't anymore freeze at
startup.  I assume the patch to fix most, if not all of those
regressions, but I haven't had yet time to test them.


Any comments on the patch?  Additional things that should be
taken into account / fixed (or at least add TODOs for)?


	- Eero

PS. Note that the patch needs to modify few items saved into
memory snapshots, so it breaks memory snapshot compatibility.
diff -r 6a7d5434867f src/falcon/videl.c
--- a/src/falcon/videl.c	Mon Nov 14 23:09:34 2016 +0100
+++ b/src/falcon/videl.c	Wed Nov 16 00:12:53 2016 +0200
@@ -85,7 +85,9 @@
 	bool   bUseSTShifter;			/* whether to use ST or Falcon palette */
 	Uint8  reg_ffff8006_save;		/* save reg_ffff8006 as it's a read only register */
 	Uint8  monitor_type;			/* 00 Monochrome (SM124) / 01 Color (SC1224) / 10 VGA Color / 11 Television ($FFFF8006) */
-	Uint32 videoBaseAddr;			/* Video base address, refreshed after each VBL */
+
+	Uint32 videoRaster;			/* Video raster offset, restarted on each VBL */
+	Uint16 vertFreqCounter;			/* Counter for VFC register $ff82a0, restarted on each VBL */
 
 	Sint16 leftBorderSize;			/* Size of the left border */
 	Sint16 rightBorderSize;			/* Size of the right border */
@@ -103,7 +105,6 @@
 
 static struct videl_s videl;
 
-Uint16 vfc_counter;			/* counter for VFC register $ff82a0 (to be internalized when VIDEL emulation is complete) */
 
 /**
  * Called upon startup (and via VIDEL_reset())
@@ -131,7 +132,7 @@
 	videl.reg_ffff8006_save = IoMem_ReadByte(0xff8006);
 	videl.monitor_type = videl.reg_ffff8006_save & 0xc0;
 
-	vfc_counter = 0;
+	VIDEL_RestartVideoCounter();
 
 	/* Reset IO register (some are not initialized by TOS) */
 	IoMem_WriteWord(0xff820e, 0);    /* Line offset */
@@ -148,7 +149,6 @@
 {
 	/* Save/Restore details */
 	MemorySnapShot_Store(&videl, sizeof(videl));
-	MemorySnapShot_Store(&vfc_counter, sizeof(vfc_counter));
 }
 
 /**
@@ -200,10 +200,7 @@
  */
 void VIDEL_ScreenCounter_ReadByte(void)
 {
-//	Uint32 addr;	// To be used
-	Uint32 addr = 0; // To be removed
-
-	// addr = Videl_CalculateAddress();		/* TODO: get current video address */
+	Uint32 addr = videl.videoRaster;
 	IoMem[0xff8205] = ( addr >> 16 ) & 0xff;
 	IoMem[0xff8207] = ( addr >> 8 ) & 0xff;
 	IoMem[0xff8209] = addr & 0xff;
@@ -216,10 +213,8 @@
  */
 void VIDEL_ScreenCounter_WriteByte(void)
 {
-	Uint32 addr_new = 0;
-	Uint8 AddrByte;
-
-	AddrByte = IoMem[ IoAccessCurrentAddress ];
+	Uint32 addr_new = videl.videoRaster;
+	Uint8 AddrByte = IoMem[ IoAccessCurrentAddress ];
 
 	/* Compute the new video address with one modified byte */
 	if ( IoAccessCurrentAddress == 0xff8205 )
@@ -229,7 +224,8 @@
 	else if ( IoAccessCurrentAddress == 0xff8209 )
 		addr_new = ( addr_new & 0xffff00 ) | ( AddrByte );
 
-	// TODO: save the value in a table for the final rendering
+	videl.videoRaster = addr_new;
+	LOG_TRACE(TRACE_VIDEL, "Videl : $ff8205/07/09 Sync Mode write: 0x%08x\n", addr_new);
 }
 
 /**
@@ -479,8 +475,8 @@
  */
 void VIDEL_VFC_ReadWord(void)
 {
-	IoMem_WriteWord(0xff82a0, vfc_counter);
-	LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a0 Vertical Frequency Counter (VFC) read: 0x%04x\n", vfc_counter);
+	IoMem_WriteWord(0xff82a0, videl.vertFreqCounter);
+	LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a0 Vertical Frequency Counter (VFC) read: 0x%04x\n", videl.vertFreqCounter);
 }
 
 /**
@@ -571,6 +567,31 @@
 	return videoBase;
 }
 
+/**
+ * Reset appropriate registers on VBL etc
+ */
+void VIDEL_RestartVideoCounter(void)
+{
+	videl.videoRaster = VIDEL_getVideoramAddress();
+	/* counter for VFC register $ff82a0 */
+	videl.vertFreqCounter = 0;
+}
+
+/**
+ * Increment appropriate registers on HBL
+ */
+void VIDEL_VideoRasterHBL(void)
+{
+	int lineoffset = IoMem_ReadWord(0xff820e) & 0x01ff; /* 9 bits */
+	int linewidth = IoMem_ReadWord(0xff8210) & 0x03ff;  /* 10 bits */
+
+	videl.videoRaster += linewidth + lineoffset;
+
+	/* TODO: VFC is incremented every half line, here, we increment it every line */
+	videl.vertFreqCounter++;
+}
+
+
 static Uint16 VIDEL_getScreenBpp(void)
 {
 	Uint16 f_shift = IoMem_ReadWord(0xff8266);
@@ -863,7 +884,7 @@
 
 	bool change = false;
 
-	videl.videoBaseAddr = VIDEL_getVideoramAddress(); // Todo: to be removed when all code is in Videl
+	Uint32 videoBase = VIDEL_getVideoramAddress();
 
 	if (vw > 0 && vw != videl.save_scrWidth) {
 		LOG_TRACE(TRACE_VIDEL, "Videl : width change from %d to %d\n", videl.save_scrWidth, vw);
@@ -913,7 +934,7 @@
 
 	VIDEL_UpdateColors();
 
-	Screen_GenConvert(&STRam[videl.videoBaseAddr], videl.XSize, videl.YSize,
+	Screen_GenConvert(&STRam[videoBase], videl.XSize, videl.YSize,
 	                  videl.save_scrBpp, nextline, hscrolloffset,
 	                  videl.leftBorderSize, videl.rightBorderSize,
 	                  videl.upperBorderSize, videl.lowerBorderSize);
diff -r 6a7d5434867f src/falcon/videl.h
--- a/src/falcon/videl.h	Mon Nov 14 23:09:34 2016 +0100
+++ b/src/falcon/videl.h	Wed Nov 16 00:12:53 2016 +0200
@@ -8,9 +8,6 @@
 #ifndef HATARI_VIDEL_H
 #define HATARI_VIDEL_H
 
-/* To be removed when Videl emulation is complete */
-extern Uint16 vfc_counter;			/* counter for VFC register $ff82a0 */
-
 extern bool VIDEL_renderScreen(void);
 
 extern void Videl_Init(void);
@@ -19,6 +16,9 @@
 extern void VIDEL_ZoomModeChanged(bool bForceChange);
 extern void VIDEL_UpdateColors(void);
 
+extern void VIDEL_RestartVideoCounter(void);
+extern void VIDEL_VideoRasterHBL(void);
+
 /* Called from ioMemTabFalcon.c */
 extern void VIDEL_Monitor_WriteByte(void);
 extern void VIDEL_SyncMode_WriteByte(void);
diff -r 6a7d5434867f src/video.c
--- a/src/video.c	Mon Nov 14 23:09:34 2016 +0100
+++ b/src/video.c	Wed Nov 16 00:12:53 2016 +0200
@@ -2773,11 +2773,9 @@
 	}
 
 
-	/* Videl Vertical counter increment (To be removed when Videl emulation is finished) */
-	/* VFC is incremented every half line, here, we increment it every line (should be completed) */
 	if (Config_IsMachineFalcon())
 	{
-		vfc_counter += 1;
+		VIDEL_VideoRasterHBL();
 	}
 
 	
@@ -3908,10 +3906,13 @@
 
 	Video_ResetShifterTimings();
 
-	Video_RestartVideoCounter();
+        if (Config_IsMachineFalcon())
+		VIDEL_RestartVideoCounter();
+	else
+		Video_RestartVideoCounter();
 
 	pSTScreen = pFrameBuffer->pSTScreen;
-
+		 
 	Video_SetScreenRasters();
 	Video_InitShifterLines();
 	Spec512_StartVBL();
@@ -4283,12 +4284,6 @@
 	nVBLs++;
 	/* Set video registers for frame */
 	Video_ClearOnVBL();
-
-	/* Videl Vertical counter reset (To be removed when Videl emulation is finished) */
-	if (Config_IsMachineFalcon())
-	{
-		vfc_counter = 0;
-	}
 	
 	/* Since we don't execute HBL functions in VDI mode, we've got to
 	 * initialize the first HBL palette here when VDI mode is enabled. */


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/