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

Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab] #112464
02/02/18 06:07 PM
02/02/18 06:07 PM
Joined: May 2004
Posts: 1,509
H
Haze Offline
Very Senior Member
Haze  Offline
Very Senior Member
H
Joined: May 2004
Posts: 1,509
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)

Re: FireFly on the ZX Spectrum - Missing graphics [Re: Haze] #112472
02/03/18 10:45 AM
02/03/18 10:45 AM
Joined: Apr 2013
Posts: 71
G
geecab Offline OP
Member
geecab  Offline OP
Member
G
Joined: Apr 2013
Posts: 71
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!

Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab] #112473
02/03/18 11:02 AM
02/03/18 11:02 AM
Joined: Jun 2001
Posts: 42
Italy
O
Osso Offline
Member
Osso  Offline
Member
O
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

Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab] #112476
02/03/18 02:18 PM
02/03/18 02:18 PM
Joined: Apr 2013
Posts: 71
G
geecab Offline OP
Member
geecab  Offline OP
Member
G
Joined: Apr 2013
Posts: 71
That's excellent, thanks Osso!

Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab] #112603
02/13/18 10:46 AM
02/13/18 10:46 AM
Joined: Apr 2013
Posts: 71
G
geecab Offline OP
Member
geecab  Offline OP
Member
G
Joined: Apr 2013
Posts: 71
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!

Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab] #112605
02/13/18 03:08 PM
02/13/18 03:08 PM
Joined: Apr 2013
Posts: 71
G
geecab Offline OP
Member
geecab  Offline OP
Member
G
Joined: Apr 2013
Posts: 71
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);

Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab] #112606
02/13/18 03:10 PM
02/13/18 03:10 PM
Joined: Mar 2001
Posts: 15,988
USA
R
R. Belmont Offline
Very Senior Member
R. Belmont  Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 15,988
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?

Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab] #112607
02/13/18 03:14 PM
02/13/18 03:14 PM
Joined: Feb 2004
Posts: 1,981
Sydney, Australia
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member
Joined: Feb 2004
Posts: 1,981
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.

Re: FireFly on the ZX Spectrum - Missing graphics [Re: geecab] #112608
02/13/18 03:48 PM
02/13/18 03:48 PM
Joined: Mar 2001
Posts: 15,988
USA
R
R. Belmont Offline
Very Senior Member
R. Belmont  Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 15,988
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 6 1 2 3 4 5 6

Who's Online Now
1 registered members (Carbon), 45 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
Shout Box
Forum Statistics
Forums9
Topics8,566
Posts111,888
Members4,805
Most Online225
May 26th, 2014
Powered by UBB.threads™ PHP Forum Software 7.6.1.1
(Release build 20180111)
Page Time: 0.048s Queries: 14 (0.019s) Memory: 5.7312 MB (Peak: 5.9518 MB) Zlib enabled. Server Time: 2018-08-17 13:31:52 UTC