Previous Thread
Next Thread
Print Thread
Page 4 of 5 1 2 3 4 5
#112463 - 02/02/18 06:02 PM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: Feb 2018
Posts: 4
Cesar Hernandez Offline
Member
Cesar Hernandez  Offline
Member

Joined: Feb 2018
Posts: 4
Of course you will also need to add per-scanline drawing. If you only add contended memory, you will only notice a normal slowdown on some games, but the flicker on games will be almost the same. To fix flickering, you will need that per-scanline drawing

#112464 - 02/02/18 06:07 PM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: May 2004
Posts: 1,484
Haze Offline
Very Senior Member
Haze  Offline
Very Senior Member

Joined: May 2004
Posts: 1,484
per-scanline drawing isn't difficult (in fact the code might already support finer grained than that, as I said, some stuff was added for the russian clone demos to work where there are no contended memory issues at least)

#112472 - 02/03/18 10:45 AM Re: FireFly on the ZX Spectrum - Missing graphics [Re: Haze]  
Joined: Apr 2013
Posts: 41
geecab Offline
Member
geecab  Offline
Member

Joined: Apr 2013
Posts: 41
Thanks Haze & Cesar!

Originally Posted by Haze
per-scanline drawing isn't difficult (in fact the code might already support finer grained than that, as I said, some stuff was added for the russian clone demos to work where there are no contended memory issues at least)


Any chance you could let me know the Russian clone that does the partial screen update (Or even point me to the code). I've had a look but I couldn't find it (But am most probably looking in the wrong place / looking for the wrong thing!). Basically, I trying to come up with a nice way that the src/devices/cpu/z80.z80.cpp can call a routine in the src/mame/video/spectrum.cpp to build up screen display line by line, and I'm hoping the code written for the Russian clone will help.

Many thanks!

#112473 - 02/03/18 11:02 AM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: Jun 2001
Posts: 42
Osso Offline
Member
Osso  Offline
Member

Joined: Jun 2001
Posts: 42
Italy
I believe it's the Pentagon.
Here's the commit that added partial screen updates: https://git.redump.net/mame/commit/?id=128ba6317b7cb4cbdaea584be650b9ac29d289b9

#112476 - 02/03/18 02:18 PM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: Apr 2013
Posts: 41
geecab Offline
Member
geecab  Offline
Member

Joined: Apr 2013
Posts: 41
That's excellent, thanks Osso!

#112603 - 02/13/18 10:46 AM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: Apr 2013
Posts: 41
geecab Offline
Member
geecab  Offline
Member

Joined: Apr 2013
Posts: 41
Hi there!

I decided to hack something in try out my suggestion. Basically, execute_run() (In src/devices/cpu/z80/z80.cpp) directly calls spectrum_plot_screen (A function I wrote in src/mame/video/spectrum.cpp) each time an opcode is processed. spectrum_plot_screen() keeps a running total of the tstates gone by since the vblank interrupt occurred, and with that draws a certain about of pixels up to the imagined position of the raster. After I did this, I then realised machine->first_screen()->vpos() and hpos() could give me the precise pixel position of the imagined raster position, so me working out the x and y based on tstate all felt a little pointless :p

Anyway, despite the ugliness of my hack, the results were pretty spectacular (OMG see what I did there!). Flicker gone completely on Stormlord and Marauder. Firefly now fully playable. Amaurote 'Traal Welcomes You' colour effect looks spot on.

Here is an image containing screenshots showing the aforementioned games with and without my hack so you can spot the difference (Top row of screen shots are without the hack, bottom row screen shots are with the hack)...
zx game screenshots before and after hack

Here is a diff of my hack...
my diff

So my thoughts are now, can the spectrum driver have a timed callback for every machine cycle (Similar to, say, the device_timer() function that is there already), and that each time it is triggered, the function calls the existing spectrum_UpdateScreenBitmap() function? I think that would achieve the same result as what I have done with much less ugliness?

Thanks for reading!

#112605 - 02/13/18 03:08 PM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: Apr 2013
Posts: 41
geecab Offline
Member
geecab  Offline
Member

Joined: Apr 2013
Posts: 41
Now implemented using a timed callback for every CPU cycle. A lot less code changes for the same benefit. I don't fully understand how the emu_timers work, so might have broken something in the process, but all the games I tried previous work & look as good as they did with my original hack.

Code
diff --git a/src/mame/drivers/spectrum.cpp b/src/mame/drivers/spectrum.cpp
index 39c7974919..9a26903325 100644
--- a/src/mame/drivers/spectrum.cpp
+++ b/src/mame/drivers/spectrum.cpp
@@ -285,7 +285,6 @@ SamRam
 #include "screen.h"
 #include "softlist.h"
 #include "speaker.h"
-
 #include "formats/tzx_cas.h"
 
 
@@ -445,6 +444,7 @@ static ADDRESS_MAP_START (spectrum_io, AS_IO, 8, spectrum_state )
 	AM_RANGE(0x01, 0x01) AM_READ(spectrum_port_ula_r) AM_MIRROR(0xfffe)
 ADDRESS_MAP_END
 
+
 /* Input ports */
 
 /****************************************************************************************************/
@@ -643,13 +643,25 @@ GFXDECODE_END
 
 void spectrum_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
 {
-	m_maincpu->set_input_line(0, CLEAR_LINE);
+	switch (id)
+	{
+	case TIMER_IRQ_OFF:
+		m_maincpu->set_input_line(0, CLEAR_LINE);
+		break;
+	case TIMER_CPU_CYCLE:
+		timer_set(m_maincpu->cycles_to_attotime(1), TIMER_CPU_CYCLE);
+		spectrum_UpdateScreenBitmap();
+		break;
+	default:
+		printf("Unknown device_timer id=%d\n", id);
+		exit(0);
+	}
 }
 
 INTERRUPT_GEN_MEMBER(spectrum_state::spec_interrupt)
 {
 	m_maincpu->set_input_line(0, HOLD_LINE);
-	timer_set(attotime::from_ticks(32, m_maincpu->clock()), 0, 0);
+	timer_set(attotime::from_ticks(32, m_maincpu->clock()), TIMER_IRQ_OFF, 0);
 }
 
 MACHINE_CONFIG_START(spectrum_state::spectrum_common)
diff --git a/src/mame/includes/spectrum.h b/src/mame/includes/spectrum.h
index d227e10e58..ad654c14d2 100644
--- a/src/mame/includes/spectrum.h
+++ b/src/mame/includes/spectrum.h
@@ -63,6 +63,12 @@ struct EVENT_LIST_ITEM
 class spectrum_state : public driver_device
 {
 public:
+        enum
+        {
+                TIMER_IRQ_ON,
+                TIMER_IRQ_OFF,
+                TIMER_CPU_CYCLE
+        };
 	spectrum_state(const machine_config &mconfig, device_type type, const char *tag)
 		: driver_device(mconfig, type, tag),
 		m_video_ram(*this, "video_ram"),
@@ -110,6 +116,8 @@ public:
 
 	int m_ROMSelection;
 
+	emu_timer *m_cpu_cycle_timer;
+
 
 	EVENT_LIST_ITEM *m_pCurrentItem;
 	int m_NumEvents;
diff --git a/src/mame/video/spectrum.cpp b/src/mame/video/spectrum.cpp
index 2a26f0f209..9ccab4428d 100644
--- a/src/mame/video/spectrum.cpp
+++ b/src/mame/video/spectrum.cpp
@@ -37,6 +37,9 @@ VIDEO_START_MEMBER(spectrum_state,spectrum)
 	machine().first_screen()->register_screen_bitmap(m_screen_bitmap);
 
 	m_screen_location = m_video_ram;
+
+	m_cpu_cycle_timer = timer_alloc(TIMER_CPU_CYCLE);
+	timer_set(m_maincpu->cycles_to_attotime(1), TIMER_CPU_CYCLE);
 }
 
 VIDEO_START_MEMBER(spectrum_state,spectrum_128)
@@ -53,6 +56,9 @@ VIDEO_START_MEMBER(spectrum_state,spectrum_128)
 	machine().first_screen()->register_screen_bitmap(m_screen_bitmap);
 
 	m_screen_location = m_ram->pointer() + (5 << 14);
+
+	m_cpu_cycle_timer = timer_alloc(TIMER_CPU_CYCLE);
+	timer_set(m_maincpu->cycles_to_attotime(1), TIMER_CPU_CYCLE);
 }
 
 
@@ -73,7 +79,7 @@ WRITE_LINE_MEMBER(spectrum_state::screen_vblank_spectrum)
 	if (state)
 	{
 		spectrum_UpdateBorderBitmap();
-		spectrum_UpdateScreenBitmap(true);
+		//spectrum_UpdateScreenBitmap(true);
 
 		m_frame_number++;
 
@@ -122,7 +128,7 @@ uint32_t spectrum_state::screen_update_spectrum(screen_device &screen, bitmap_in
 	if (m_border_bitmap.valid())
 		copyscrollbitmap(bitmap, m_border_bitmap, 0, nullptr, 0, nullptr, cliprect);
 
-	spectrum_UpdateScreenBitmap();
+	//spectrum_UpdateScreenBitmap();
 	if (m_screen_bitmap.valid())
 		copyscrollbitmap(bitmap, m_screen_bitmap, 0, nullptr, 0, nullptr, rect);

#112606 - 02/13/18 03:10 PM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: Mar 2001
Posts: 15,851
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,851
USA
Ok, that second patch is much nicer. If it gets all the benefits, I'd be inclined to apply it. How badly does it hurt performance?

#112607 - 02/13/18 03:14 PM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: Feb 2004
Posts: 1,906
Vas Crabb Online content
Very Senior Member
Vas Crabb  Online Content
Very Senior Member

Joined: Feb 2004
Posts: 1,906
Sydney, Australia
Timers are very inefficient if you're running them at these kinds of frequencies. Wouldn't you be better of making something that inherits `device_execute_interface` running at CPU clock and setting perfect interleave on it? Then you'll get your `execute_run` callback every time the Z80 yields, and you can just do your update and finish your timeslice.

#112608 - 02/13/18 03:48 PM Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab]  
Joined: Mar 2001
Posts: 15,851
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,851
USA
I agree, but this is a very low-performance system already so I'd like to see numbers before trying to force someone off-list into doing something even Haze is terrified of.

Page 4 of 5 1 2 3 4 5

Who's Online Now
5 registered members (MarkBielman, R. Belmont, elcondor, Vas Crabb, Dorando), 23 guests, and 1 spider.
Key: Admin, Global Mod, Mod
Shout Box
Forum Statistics
Forums9
Topics8,496
Posts110,806
Members4,781
Most Online225
May 26th, 2014
Powered by UBB.threads™ PHP Forum Software 7.6.0
Page Time: 0.032s Queries: 15 (0.007s) Memory: 5.0255 MB (Peak: 5.2773 MB) Zlib enabled. Server Time: 2018-02-22 16:13:26 UTC