| 
     
      
      
      From: Jonathan N. <js...@sp...> - 2003-11-06 13:58:30
       
   | 
Hi all,
Phil's been helping me debug an RZX problem on Spectaculator and, as it =
turns out, we've (or rather Paul Collins) found a game that can't be =
RZXed without adding a new 'special case' to the specs.
The game in question is Rockfall 2. what happens (normally after 10 or =
so minutes playing) is this:
; we're at cycle 69886
EI
; we're now at cycle 69890.
; The end of the frame as been reached since we've executed
; >=3D 69888 cycles so the RZX writes an RZX input recording
; frame.
; we're now at the start of the next frame (cycle 00002)
; the Z80 doesn't yet take the interrupt since the last
; instruction executed was an EI
HALT
; After the first pass through the HALT, the Z80 then takes
; the interrupt so the RZX recorder writes a new frame. In
; this case it's a 1 instruction frame, HALT.
This is now a big problem because during playback, two interrupts will =
be forced when there was only actually one during recording. Playback =
thus fails at some point soon.
In Spectaculator, I've worked around this by doing this at the end of =
each frame:
if( m_fRzxRecording && m_chLastOpCode =3D=3D EI )
    Execute();    // executes 1 additional instruction.
.
[Other end of frame code]
.
.
if( m_fRzxRecording && m_chLastOpCode =3D=3D EI )
{
     // forces interrupt even though it shouldn't really be taken
    ForceInterrupt();
}
else
    DoNormalInterrupts();
This gives the Z80 one last chance to execute an instruction following =
an EI.
If we've still executed an EI (long sequence of EIs?), we force an =
interrupt anyway so that playback will still mirror recording. Any =
errors due to interrupts taken in the wrong place would show up during =
recording, which is probably be a good thing.
Phil also mentioned that a real Z80 would not take interrupts during a =
long sequence of FD DD prefixes. This many not be too much of a problem =
since we haven't found a game yet that does this.
Any comments or better solutions?
Cheers,
Jon.
--
  Jonathan Needle
  Spectaculator Creator
  http://www.spectaculator.com/
 | 
| 
     
      
      
      From: Erik K. <Eri...@ph...> - 2003-11-07 14:05:53
       
   | 
Hello, can someone confirm that the RZX file at http://www.deconstruction.f9.co.uk/rick/demos/south-america.rzx is corrupt or is it Fuse's fault: > fuse south-america.rzx The Free Unix Spectrum Emulator (Fuse) version 0.6.1.1. ... fuse: error: libspectrum: corrupt gzip data fuse: error initalising -- giving up! And why does the emulator exits? -- Dipl.-Ing. Erik Kunze Phone: +49 - 89 - 32 14 07 41 PHILOSYS Software GmbH Fax: +49 - 89 - 32 14 07 12 Edisonstr. 6 Email: Eri...@ph... D-85716 Unterschleissheim WWW: www.philosys.de/~kunze PGP-Key: http://blackhole.pca.dfn.de:11371/pks/lookup?op=get&search=0xD5759581  | 
| 
     
      
      
      From: Philip K. <pa...@sr...> - 2003-11-07 14:16:47
       
   | 
> can someone confirm that the RZX file at > http://www.deconstruction.f9.co.uk/rick/demos/south-america.rzx > is corrupt or is it Fuse's fault: Works for me: $ md5sum south-america.rzx 877bd9f18934da3417d5c238b3e183d2 south-america.rzx $ ./fuse south-america.rzx [ plays fine ] Cheers, Phil -- "Hey, wait till you have an evil twin. See how you handle it." "I handled it fine." Xander and Willow: Buffy: The Replacement  | 
| 
     
      
      
      From: Darren S. <ds...@yo...> - 2003-11-08 00:33:50
       
   | 
I demand that Philip Kendall may or may not have written... >> can someone confirm that the RZX file at >> http://www.deconstruction.f9.co.uk/rick/demos/south-america.rzx is corrupt >> or is it Fuse's fault: > Works for me: [snip] <AOL>, though I note that the server thinks that it's of type text/plain. Maybe something performed line-ending conversion... -- | Darren Salt | nr. Ashington, | RISC OS, | ds...@yo... | Northumberland | Linux | ds...@za... | *Toon Army* | | I don't ask for much, just untold riches... Your business will go through a period of considerable expansion.  | 
| 
     
      
      
      From: Philip K. <pa...@sr...> - 2003-11-07 15:12:39
       
   | 
On Thu, Nov 06, 2003 at 02:01:04PM -0000, Jonathan Needle wrote:
> 
> Phil's been helping me debug an RZX problem on Spectaculator and, as it turns out, we've (or rather Paul Collins) found a game that can't be RZXed without adding a new 'special case' to the specs.
[ ... ]
> Any comments or better solutions?
A side-effect (not entirely intentional) of Fuse's new interrupt
retriggering code is that Paul's RZX plays back perfectly[1]: how this
works is just by not doing a Z80 interrupt after the EI (because the
last instruction was an EI), even though an RZX frame ended at this
point. It then does the interrupt after one iteration of the HALT, both
because it's the end of an RZX frame and because it's a retriggered
interrupt (it obviously executes only one interrupt, though!).
[1] at least, gets further than it did previously. I got bored at the
    end of level 5.
The fundamental problem here is that the RZX format doesn't really
distinguish between 'end of frame' and 'interrupt'. While these two
events are normally related, they're not necessarily the same thing, so
I think any solution we come up with which doesn't acknowledge this
difference is always going to break in one corner case or another.
Cheers,
Phil
-- 
"You have more talent in your little finger than anyone else in this
town."
"Which one?"                        Liz and Maria: Roswell: Ch-Ch-Changes
 | 
| 
     
      
      
      From: Jonathan N. <js...@sp...> - 2003-11-07 15:29:08
       
   | 
----- Original Message ----- From: "Philip Kendall" <pa...@sr...> To: "Jonathan Needle" <js...@sp...> Cc: "Ramsoft staff" <ra...@bb...>; "Mark Woodmass" <mar...@nt...>; <fus...@li...> Sent: Friday, November 07, 2003 3:12 PM Subject: Re: [fuse-emulator-devel] RZX Problems > A side-effect (not entirely intentional) of Fuse's new interrupt > retriggering code is that Paul's RZX plays back perfectly[1]: how this > works is just by not doing a Z80 interrupt after the EI (because the > last instruction was an EI), even though an RZX frame ended at this > point. It then does the interrupt after one iteration of the HALT, both > because it's the end of an RZX frame and because it's a retriggered > interrupt (it obviously executes only one interrupt, though!). > > [1] at least, gets further than it did previously. I got bored at the > end of level 5. I think I did this sort of thing in my original implementation of RZX but it broke a few recordings.. as in they played for a few minutes until they failed. Can't be sure for definite though. > The fundamental problem here is that the RZX format doesn't really > distinguish between 'end of frame' and 'interrupt'. While these two > events are normally related, they're not necessarily the same thing, so > I think any solution we come up with which doesn't acknowledge this > difference is always going to break in one corner case or another. Another problem is that you can't make an RZX of a program using the AMX mouse since the hardware generates a maskable interrupt for every mouse 'micky' and puts a different value on the bus at ack time depending on wether it's the vertical or horizontal axis that there was movement. So the address jumped to might be I:$50 for X and I:$80 for Y.... and you get lots of these per frame, depending on how aggressive you are with the mouse ;-) Cheers, Jon. -- Jonathan Needle Spectaculator Creator http://www.spectaculator.com/  | 
| 
     
      
      
      From: Philip K. <pa...@sr...> - 2003-11-10 18:03:57
       
   | 
On Fri, Nov 07, 2003 at 03:28:41PM -0000, Jonathan Needle wrote:
> 
> From: "Philip Kendall" <pa...@sr...>
[ Description of Fuse's new RZX bits ]
> I think I did this sort of thing in my original implementation of RZX but it
> broke a few recordings.. as in they played for a few minutes until they
> failed. Can't be sure for definite though.
Well, it certainly breaks some recordings made with earlier versions of
Fuse :-(
Notably, check out beachhead.rzx from the RZX Archive: this starts with
a simple EI/RET interrupt handler, and then goes into a tight loop
containing an IN. With the new code, we immediately get a retriggered
interrupt, putting us behind where we 'should' be, and end up doing one
less iteration of the IN loop than we should, causing the RZX playback
to bomb on the very first frame.
I think the solution to this is not to implement retriggered interrupts
while doing RZX playback, but this will require a few more modifications
to the RZX recording logic so that we do record an RZX frame for
retriggered interrupts... and I haven't done these yet :-)
Cheers,
Phil
-- 
"Oh, I feel just like Santa Claus, except thinner and younger, and
female, and, well, Jewish [...] Buffy, I have this for you."
"Homework? Ehh... I don't believe in tiny Jewish Santa anymore."
                                      Willow and Buffy: Listening to Fear
 | 
| 
     
      
      
      From: Philip K. <pa...@sr...> - 2003-11-11 16:10:47
       
   | 
On Mon, Nov 10, 2003 at 06:03:41PM +0000, Philip Kendall wrote: > > I think the solution to this is not to implement retriggered interrupts > while doing RZX playback, but this will require a few more modifications > to the RZX recording logic so that we do record an RZX frame for > retriggered interrupts... and I haven't done these yet :-) Changes now done, and the current Fuse will now replay Beachhead as recording with old versions of Fuse, Beachhead as recorded the current version of Fuse and Paul's rockfal2.rzx. This still won't be perfect, as we still have no way of knowing whether the recording emulator intended for an interrupt to be accepted when writing an RZX frame. Essentially, Fuse currently makes a best guess, but this will be wrong for something somewhere... I think the new code is better than the old code, though. Cheers, Phil -- "Enjoying yourself?" "Oh yeah. Marching through a smelly, bug-infested jungle. If this is your idea of a good time, I bet you don't get a lot of second dates." Aeryn and Crichton: Farscape: Throne for a Loss  | 
| 
     
      
      
      From: Ramsoft s. <ra...@bb...> - 2003-11-09 20:05:58
       
   | 
Hi all, first of all many thanks for your mails!
Hehe, I was pretty sure that we didn't think of all the possible problems 
at the time ;-)
While Jonathan's practical approach is ok of course, we'd like to propose 
an alternative solution which refines the RZX philosophy.
Let me recall that the basic principle of RZX is to provide a 
timing-independent way to signal discontinuities in the Z80 program flow, 
i.e. whenever the normal flow control of the program (which includes jump 
and call instructions) is interrupted by the acknowledgemnt of an external 
interrupt request. Instead of letting the emulator decide when such 
interruptions should occur by counting TSTATES till the end of the frame, 
we specify how many instruction fetches must be executed between two 
consecutive interrupt requests. This gives us all the good stuff which 
makes RZX so "portable" and blah blah... :-)
Ok, now let me stress the point that what we actually need to know is when 
an interrupt is *accepted* by the Z80 and consequently PC jumps to the INT 
handler. We are not interested to know, instead, that an INT has been 
requested but it was not acknowledged (e.g. interrupts were disabled) and 
so PC continued to follow the program flow normally.
In other words, I'm suggesting that if a program runs with interrupts 
disabled during all the time, for our purposes the RZX file can actually 
store only a single, long recording frame with all the I/O data; we don't 
actually need to "segment" the I/O stream if the programs flow has not been 
interrupted.
In the current RZX implementation, instead, we write an RZX frame for each 
interrupt requests, also for those not accepted. Not only this is redundant 
to achieve our goal of playback/record consistency, but it leads to the 
EI/HALT issue too - and there are other problematic scenarios as well.
For this reason we propose to modify the RZX semantics slightly in this 
way: input recording frames are written to the RZX file either when an 
interrupt is accepted by Z80 (and so PC jumps to the int handler), or when 
the fetch counter has reached 65536 (to avoid overflow of the 16-bit counter).
In the latter case, however, the RZX frame header contains a fetch count of 
0, which we interpret as "do not force interrupt at the end of this frame, 
and continue with the next one". Note that a "regular" frame cannot contain 
0 fetches, so this value is safe to be used for this special purpose.
Apart from solving problems such as EI/HALT or long sequences of DD/ED 
prefixes, reducing the number of rzx frames (slightly) decreases the file 
length and improves compressability.
Besides, implementing this new policy should require a very small change to 
the code: basically we just have to move the call to write rzx frames from 
one place to another, and add another when the fetch counter reaches 65536.
Concerning the support for AMX mouse, two options come to my mind: either 
add one more byte to the rzx frame header which contains the LSB of the 
interrupt vector put on the byte, or put it into a special data entry at 
the beginning of the frame's I/O (marked in some way). If we decide to 
extend the frame header, we could take the opportunity to introduce also a 
bit to distinguish between NMI and maskable interrupts, and other things we 
might need.
What do you think guys? We are pretty favourable to change the frames 
recording logic because it not only solves several problems, but it also 
gets the RZX philosophy closer to its real essence.
Cheers,
Luca
Ramsoft staff         <ra...@bb...>
---------------------------------------
RAMSOFT - ZX Spectrum demogroup    ////
    http://www.ramsoft.bbk.org    ////
Home of RealSpectrum and MakeTZX ////
------------------------------------  
 | 
| 
     
      
      
      From: Philip K. <pa...@sr...> - 2003-11-10 17:58:01
       
   | 
On Sun, Nov 09, 2003 at 07:03:02PM +0100, Ramsoft staff wrote:
> 
> Ok, now let me stress the point that what we actually need to know is when 
> an interrupt is *accepted* by the Z80 and consequently PC jumps to the INT 
> handler.
Definitely.
> For this reason we propose to modify the RZX semantics slightly in this 
> way: input recording frames are written to the RZX file either when an 
> interrupt is accepted by Z80 (and so PC jumps to the int handler), or when 
> the fetch counter has reached 65536 (to avoid overflow of the 16-bit 
> counter).
I very much like the idea of writing an 'event' to the RZX file every
time an interrupt is accepted. However, I'd also argue that storing 'end
of frame' events is also a useful thing to do, as it allows a
(moderately crude) form of resynchronisation between what the two
emulators think is occuring.
If the above isn't obvious, consider what would happen if we took a
recording made on an emulator which supported memory contention, but
then played it back on one without. After executing what the recording
emulator thought was one frame's worth of instructions, the playback
emulator would have its tstate count slightly less than 69888, and thus
would be slightly late displaying any rainbow effects or the like on the
screen for the next frame. This disparity would get worse and worse as
time went on. Having an 'end of frame' event allows the playback
emulator to not get too far removed from 'reality'.
This is a trade-off between file size/emulator peformance and accuracy
of playback: we _could_ store the tstate count after every instruction,
but that's is (IMO) overkill. Doing things once per frame won't make the
file much bigger and shouldn't hurt performance much, if at all.
Cheers,
Phil
-- 
"Willow, grow up. Not everything is about kissing."
"Yeah. Some stuff's about groping."
                                       Buffy and Xander: When She Was Bad
 | 
| 
     
      
      
      From: Jonathan N. <js...@sp...> - 2003-11-10 21:40:49
       
   | 
----- Original Message ----- From: "Philip Kendall" <pa...@sr...> To: "Ramsoft staff" <ra...@bb...> Cc: "Jonathan Needle" <js...@sp...>; "Mark Woodmass" <mar...@nt...>; <fus...@li...> Sent: Monday, November 10, 2003 5:57 PM Subject: Re: [fuse-emulator-devel] Re: RZX Problems > > For this reason we propose to modify the RZX semantics slightly in this > > way: input recording frames are written to the RZX file either when an > > interrupt is accepted by Z80 (and so PC jumps to the int handler), or when > > the fetch counter has reached 65536 (to avoid overflow of the 16-bit > > counter). > > I very much like the idea of writing an 'event' to the RZX file every > time an interrupt is accepted. However, I'd also argue that storing 'end > of frame' events is also a useful thing to do, as it allows a > (moderately crude) form of resynchronisation between what the two > emulators think is occuring. I like this too as it aids debugging. You spot quite quickly exactly where two emulators take different paths through the code. I'd prefer a couple of markers in the recording like Phil: [End of Frame] - we don't take int here. [Interrupt, low byte is $xx (for AMX mouse)] (there could be dozens of these within a frame before we reach the [End of Frame] marker. Regards, Jon. -- Jonathan Needle Spectaculator Creator http://www.spectaculator.com/  |