Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

want to talk about MESS/model b/beebem/b-em/electrem/elkulator? do it here!
Coeus
Posts: 463
Joined: Mon Jul 25, 2016 11:05 am

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Coeus » Thu Apr 13, 2017 1:30 pm

So is this composite processing optional?

I can understand the desire to create a BITD experience but for me that was a choice of two output devices: a green screen monitor that was driven from the non-colour-enabled composite out and a TV that had been modified to accept TTL RGB bypassing the tuner and composite video decoder,

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Thu Apr 13, 2017 1:55 pm

Coeus wrote:So is this composite processing optional?

I can understand the desire to create a BITD experience but for me that was a choice of two output devices: a green screen monitor that was driven from the non-colour-enabled composite out and a TV that had been modified to accept TTL RGB bypassing the tuner and composite video decoder,

For the Electron and Oric, yes; one selects either 'television' or 'monitor'. If you're using a monitor then it's the same stuff as to phosphors, syncs and scans — and therefore impliedly as to interlacing — but the RGB values are output raw. Just as if you used the RGB ports on those computers.

On the Atari and Vic, no; those machines do not have RGB outputs on account of never generating RGB internally.

So it's all about recreating the back-in-the-day experience, and back in the day some people had RGB monitors attached to their Acorns.

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Rich Talbot-Watkins » Thu Apr 13, 2017 3:42 pm

ThomasHarte wrote:EDIT: also, in case it's interesting, the minimal unit of screen repainting in my emulator is a straight line raster. A 144Hz monitor should paint 144 separate frames per second. This is part of my effort not falsely to introduce latency, in much the same way that the emulator is happy pumping 96Khz audio even on my lowly computer. But I think it also feels better even just for displaying PAL 50Hz on standard PC issue 60Hz displays now, rather than if you forced yourself to display only a whole frame at a time, in which case you're going to get a stutter after every fifth frame. There's a bunch of blending going on for the phosphor-ish semi-simulation*, so don't picture the harsh rolling edge you'd associate with tearing.

That sounds great, would love to see that in action (on my PC with 144Hz monitor!) one day.

So are lines rastered completely horizontal, or do they take into account the continuous downwards motion as the picture is scanned? For the latter, presumably you need to draw antialiased slightly diagonal-sloping quads to the render target. Higher up the thread you mentioned you were simulating phosphor decay 'properly' (exponential decay), but I can imagine that leading to the sort of artefacts you see when viewing a monitor through a video camera (that kind of banding/flickering) since the rendered image is capturing a precise instant rather than summing contributions across the entire frame.

Also I was wondering how you get away from the scanline 'stripiness' that often happens when rendering separate interlaced fields - presumably the phosphor persistence helps with that, but also is a phosphor dot rendered as bigger than an emulated pixel too?

Anyway, congratulations on this so far. As an absolute purist when it comes to emulation, this is an approach I'm 100% behind!

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Rich Talbot-Watkins » Thu Apr 13, 2017 3:47 pm

Incidentally my first machine was an Oric-1, so I find it amusing that it's one of the machines you chose to support from the start - it's hardly the most popular or well known of the 6502 computers. It also has a truly bizarre graphics system provided by a custom ULA which I'm guessing you've spent far too much time getting acquainted with! (The moment I realised how text/graphics mode selection was achieved by writing control codes into screen memory itself, I ran out of eyebrows to raise.)

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Thu Apr 13, 2017 9:30 pm

Rich Talbot-Watkins wrote:So are lines rastered completely horizontal, or do they take into account the continuous downwards motion as the picture is scanned? For the latter, presumably you need to draw antialiased slightly diagonal-sloping quads to the render target.

They were diagonal but it appears at some point that I broke that. It should be easy to fix, and I will. The GPU deforms a quad to make the scan and has the correct timing information, I've just clearly dropped a ball while transitioning to the current information format from a previous form that required the CPU to spell out each quad in full.

Rich Talbot-Watkins wrote:Higher up the thread you mentioned you were simulating phosphor decay 'properly' (exponential decay), but I can imagine that leading to the sort of artefacts you see when viewing a monitor through a video camera (that kind of banding/flickering) since the rendered image is capturing a precise instant rather than summing contributions across the entire frame.

Also I was wondering how you get away from the scanline 'stripiness' that often happens when rendering separate interlaced fields - presumably the phosphor persistence helps with that, but also is a phosphor dot rendered as bigger than an emulated pixel too?

That's exactly what happened, and what the 'seizure-inducing' part of the title refers to. I've retrenched quite a bit until I can come up with a more convincing model for myself. The phosphors now magically retain their energy perfectly until the electron gun next reaches them, at which point they do a discrete decay. Which is basically the same thing as imposing that each part of the output frame was captured at the same amount of time after the phosphor was last lit. But is also identical to just painting new scans with a certain multiplicative alpha and letting everything happen in the frame buffer. So either everybody who's ever implemented that as a quick way to have things leave a bit of a trail has intuitively hit upon a convincing solution, or I've conveniently reasoned myself into a simple solution. More rigour required, I think, to persuade myself either way.

All mixing is done at your window size. In the original implementation I had a backlog of scans going back to the point where I'd be painting them with an alpha of 0, and to produce each frame I painted them all with a proper individual calculation of decay. Which isn't entirely correct because it fails to allow for saturation. Now it all happens in the frame buffer, so I paint only those scans that are new since the last painting, everything else accumulating in there.

Either way, if you have a 5k or whatever screen, each pixel is a unique product.

The accumulation seems largely to mask the effect of the deinterlacing.

A quad also isn't completely accurate, so for a long time I applied intensity as a function of sine of the vertical offset within the quad and sized them a little larger imagining a TV that just had a slightly larger electron gun. But, again, I'm not sure how accurate that is. So it's absent for now.

It's not a perfect demonstration because I didn't have the GIF editor I'd need to reduce it to the exactly correct 8 frames, but this is a close-up of the Repton loading screen doing all of the appropriate stuff (and then looping at the wrong point to give what looks like a sudden jump down):

Image

Rich Talbot-Watkins wrote:Incidentally my first machine was an Oric-1, so I find it amusing that it's one of the machines you chose to support from the start - it's hardly the most popular or well known of the 6502 computers. It also has a truly bizarre graphics system provided by a custom ULA which I'm guessing you've spent far too much time getting acquainted with! (The moment I realised how text/graphics mode selection was achieved by writing control codes into screen memory itself, I ran out of eyebrows to raise.)

It was actually the fourth machine added, based on a fairly cynical calculation:
  • it uses a 6522 just like the Vic, so that's one more place to test my 6522;
  • the two main disk drive add-ons used a WD 1793, which is a lot like the 1770, so that's one more place to test the majority of that;
  • it uses the 6502 just like the other three machines, which doesn't really need any more testing but therefore is fairly easy; and
  • having an AY implementation would help to test the audio infrastructure.
When I eventually learnt that it uses a ROM to look up composite levels based on colour at four times the colour clock rate, it became the gift that really gave back, becoming the first machine for which I'm not both calculating and consuming the full composite signal. I'm just looking the values up.

Also, in case you've not paid attention to what's going on in Oric land for a while, you should see what they've managed to do with ports like Stormlord. It's like using a different machine.

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Tue May 16, 2017 1:50 pm

Quick note to add: I just made an additional release that was intended to fix a Vic-20 colouring problem — specifically a phase error introduced during intermediate processing for its particular sub pixel alignment — but actually appears also to have fixed all output problems on the 2013 Mac Pro.

My best guess is that because even the 1d composite signal is packed into 2d for the GPU's benefit, I was introducing "vertical phase" errors, effectively jumping an irregular amount of time into the future for certain segments. I'm not completely sure I believe that but the only Mac Pro I have access to is the one that sits on my desk at work so I haven't ever had an opportunity properly to diagnose the problem. I just grab five minutes every so often to test the last thing I uploaded. Therefore a guess from perceived symptoms is as good as it's going to get for now.

And, empirically, the problem is gone. So that's worth mentioning.

Monitor versus television state of play — as a quick reminder, the Electron interlaces all modes, so that's why there's a slight vertical fuzziness even in monitor mode:
Monitor.png
Television.png

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Rich Talbot-Watkins » Wed May 17, 2017 8:41 am

That looks great! Exactly as I remember it!

Out of interest, at what rate are you sampling the luma signal? PAL has a maximum bandwidth of something like 5.5MHz, but I think (if I'm doing the sums right) that only results in an absolute maximum horizontal resolution (including borders) of 572 pixels (52us * 5.5 * 2). What kind of analogue effects are there when encoding the luma for a MODE 0 signal? It should ideally be a square wave, but in practice do you get inbetween-levels being output when sampling near an edge?

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Wed May 17, 2017 1:39 pm

Rich Talbot-Watkins wrote:That looks great! Exactly as I remember it!

Out of interest, at what rate are you sampling the luma signal? PAL has a maximum bandwidth of something like 5.5MHz, but I think (if I'm doing the sums right) that only results in an absolute maximum horizontal resolution (including borders) of 572 pixels (52us * 5.5 * 2). What kind of analogue effects are there when encoding the luma for a MODE 0 signal? It should ideally be a square wave, but in practice do you get inbetween-levels being output when sampling near an edge?

I sample at four times the colour subcarrier because:
  • it's what the standards recommend to broadcasters (secondary source) and what the formal literature tends to focus on (example); and
  • it's the rate at which those machines that I'm aware of that use a discrete function for producing a wave run at — specifically I'm thinking of the Apple II and the Oric — so with a little conspiracy as to phase I can pump their output straight through.

So for PAL that's close to 1135 samples/line, and then less than that just for luminance because of losses during filtering. The input PCM stream contains the closest thing it can describe to a square wave but then even that gets blunted because real square waves require infinite bandwidth and removing the chrominance is a low-pass filtering step.

As discussed above, the television I'm emulating is definitely not the best ever implemented; I'm just aiming for the correct process producing results that are in the correct range, without actually being all that well educated. But I'm definitely askew from the do-it-as-a-post-processing-step "TV filter" school of emulation where they just sort of blur things a lot and hope for the best.

Mode 0 screenshots attached — monitor versus television again, as last time.

Monitor.png
Television.png

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Rich Talbot-Watkins » Wed May 17, 2017 1:52 pm

So if you're synced with the subcarrier, your samples are effectively seeing it as a triangle wave - is that sufficient fidelity for the filtering to work well? I was imagining needing a higher frequency than that in order to extract the chrominance.

By the way, to my eyes, that TV rendering of MODE 0 looks absolutely right! It brings back a fuzzy nostalgia to see that again (given my childhood propensity to do coding in MODE 0 on a TV!). Surprised my eyes still work right to be honest.

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Wed May 17, 2017 7:47 pm

Rich Talbot-Watkins wrote:So if you're synced with the subcarrier, your samples are effectively seeing it as a triangle wave - is that sufficient fidelity for the filtering to work well? I was imagining needing a higher frequency than that in order to extract the chrominance.

By the way, to my eyes, that TV rendering of MODE 0 looks absolutely right! It brings back a fuzzy nostalgia to see that again (given my childhood propensity to do coding in MODE 0 on a TV!). Surprised my eyes still work right to be honest.

We are most definitely in the outer periphery of my ability to make reasoned arguments but I think the logic goes that if you know the input is a waveform with a certain maximum frequency component plus two amplitude modulated sine waves of known frequencies, then four samples per colour cycle is enough information. It's definitely more than you need for the amount of luminance information there can originally have been, and it's enough for the chrominance once you apply what you already know about its shape.

The means of recovering the chrominance is one of those things that was a little surprising for me, at least. The problem is that you've got k(t)*sin(t) and you want to get back just k(t). You can't divide by sin(t) because it goes through zero. So instead you go the other way:

Code: Select all

f(t) = k(t) * sin(t)
=> f(t) * sin(t) = k(t) * sin(t) * sin(t)
=> f(t) * sin(t) = k(t) * 1/2( cos(t - t) - cos(t + t))          ... by applying the trig product identity
=> f(t) * sin(t) = k(t) * 1/2( cos(0) - cos(2t))
=> f(t) * sin(t) = k(t) * 1/2 - k(t) * 1/2 * cos(2t)


But now suppose you know how to filter out the high frequency part of a signal. k(t) had a top frequency quite a bit lower than 2t. So if you perform a lowpass filter, you cut off the k(t) * 1/2 * cos(2t) bit. Then you're at:

Code: Select all

=> filtered[f(t) * sin(t)] = k(t) * 1/2
=> 2*filtered[f(t) * sin(t)] = k(t)


So to get rid of a multiplication by sin(t) you start by... multiplying by sin(t). The assumption that the chrominance is of the form k(t) * sin(t) is where your prior knowledge about the overall shape of the chrominance wave is applied.

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Rich Talbot-Watkins » Wed May 17, 2017 8:10 pm

Fascinating stuff. Yeah, I read up a little on this, and was also boggled to see how the other quadrature subcarrier is added by modulating with cos(t) instead of sin(t), and can then be recovered by multiplying with cos(t) instead (where the sine part ends up cancelling out). It's deviously clever, but I still haven't really quite taken in how filters are used to extract the various components (and probably won't do until I have a chance to try writing some code myself to see how it all works). This is a pretty good dummies' guide.

Signal processing is an area I've spent very little time on (other than a little diversion years ago to try to isolate individual instruments in a song and pitch shift them without affecting everything else - where you soon learn the limitation of sample window size vs accuracy). Do you know of any good books / online resources on how to get started with this kind of stuff? I don't really have any formal background on it, and it's a tricky subject to just 'dip in' to.

User avatar
BigEd
Posts: 1486
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby BigEd » Fri May 19, 2017 10:45 am

ThomasHarte wrote:
Rich Talbot-Watkins wrote:So are lines rastered completely horizontal, or do they take into account the continuous downwards motion as the picture is scanned? For the latter, presumably you need to draw antialiased slightly diagonal-sloping quads to the render target.

They were diagonal but it appears at some point that I broke that. It should be easy to fix, and I will.

Are you quite sure it would be right to make scanlines diagonal? I know they are often diagrammed that way, but considering how easy it would be for the deflection yoke to have a slight rotation to compensate, I would think it likely enough that scanlines on a real CRT television are actually horizontal.

tom_seddon
Posts: 84
Joined: Mon Aug 29, 2005 11:42 pm
Contact:

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby tom_seddon » Fri May 19, 2017 12:12 pm

I wondered the same thing too, but they do appear to be diagonal on the (not exactly brand new, but manufactured in the 21st century...) 14" portable CRT I use with my Master...

Experimental process: *TV0,1, MODE 4, set 6845 R2 to 52, set 6845 R1 to 47 - this gives a display that stretches all the way across the screen from beyond the top left of the glass to beyond the top right. Then fill the top line with _, giving a horizontal line starting from roughly the top left of the screen to the top right. Then take pics of top left and top right...

(Cameraphone pics, but they came out comprehensible, I think. I've uploaded the full-size JPEG originals so you can get a good look)

--Tom
Attachments
IMG_20170519_130740519.jpg
IMG_20170519_130731985.jpg

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Rich Talbot-Watkins » Fri May 19, 2017 12:39 pm

That seems to be demonstrating the curvature of the screen though, rather than a constant vertical movement in the raster beam as it scans horizontally. I don't really understand why else the "top right" picture would show the line going up again.

In any case, any slight vertical offset from the start to the end of the raster line would be very subtle, differing by less than a field line's thickness.

Ed, I guess it would be possible to compensate and make the raster completely horizontal, but would just add extra complexity which I assume wouldn't be worth the effort most of the time.

User avatar
BigEd
Posts: 1486
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby BigEd » Fri May 19, 2017 12:47 pm

Always a good idea to measure! On my 5" Sony, the lines actually go uphill! So, on a sample of 2, I'd say yokes are not so excellently adjusted, and people put up with what they get.

Perhaps the true measure would be the vidicon cameras - are the lines horizontal - and one way to see that is presumably on a test card image.

But an even truer measure would be in some official spec of TV signals - if they've thought there was doubt, they would clarify.

It feels to me right to regard the scan lines as horizontal - certainly it looks like the later digital testcards have fine pixel-perfect horizontal lines. Regarding them as sloping is to read too much into the diagrams we often see which illustrate flyback.

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Rich Talbot-Watkins » Fri May 19, 2017 12:57 pm

By the way, while we're on CRT emulation, here's an interesting memory from the past.

I often used to use MODE 3 for coding, with inverted colours (white background, black foreground) as it was a little easier to read on a TV. But I didn't like the black gaps between rows, so I used to turn them off by setting the CRTC number of scanlines per row to 8 (*).

This would have produced a 250 line PAL screen, which clearly was totally off-spec, but my TV used to deal with it fine. But it had the effect of vertically stretching the scanlines (making them about 10% taller from the best of my memory), which used to further improve the clarity.

Any idea what effect is going on here to cause that to happen? I assume the frame rate went up to 62.5Hz as well, though I never thought to test that back in the day. To be honest, I didn't even realise that what I was doing was potentially monitor-destroying back then!

(*) Basically setting ?&FE00=9:?&FE01=7, but I used to do it all by typing control codes! -
MODE 3
and then
Ctrl+S 0 7 0 0 0 (white background)
Ctrl+S 1 0 0 0 0 (black text)
Ctrl+W Ctrl+@ Tab Ctrl+G and then hold down Ctrl+@ until the screen changed

User avatar
BigEd
Posts: 1486
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby BigEd » Fri May 19, 2017 1:12 pm

on my telly, that loses vertical hold, needs a lot of twiddling to stabilise, and then the frame is not well-placed on the tube. So, yes, probably well out of spec!

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby Rich Talbot-Watkins » Fri May 19, 2017 1:14 pm

Yeah I realise now that my TV was impressively tolerant of strange signals! It was a little 14" TV from the late 80's, nothing fancy.

User avatar
BigEd
Posts: 1486
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby BigEd » Fri May 19, 2017 1:17 pm

Hmm, but those incantations don't get rid of the black scanlines between rows. I'm on a master - but wouldn't expect that to make any difference.

tom_seddon
Posts: 84
Joined: Mon Aug 29, 2005 11:42 pm
Contact:

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby tom_seddon » Fri May 19, 2017 1:22 pm

Rich Talbot-Watkins wrote:In any case, any slight vertical offset from the start to the end of the raster line would be very subtle, differing by less than a field line's thickness.

Yes, the curvature is very visible - the key part is supposed to be the place where the line intersects the border of the TV. But you're right that if everything were perfectly calibrated then the difference would be less than a scanline, and it's a bit more than that here. So chalk this one up to it being a crappy old TV.
Rich Talbot-Watkins wrote:I assume the frame rate went up to 62.5Hz as well, though I never thought to test that back in the day. To be honest, I didn't even realise that what I was doing was potentially monitor-destroying back then!

It does work fine on my CRT, and I get the same effect: no black bars, taller screen, and visibly higher refresh rate - so presumably it's the TV syncing to a 60Hz signal. Perhaps the TV can sync to either rate, and then the internals can be the same for all regions...? There were a number of utilities for the PAL Atari ST that would let you toggle 50Hz and 60Hz, so presumably this was true of TVs in the late 80s/early 90s as well.

--Tom

P.S. my TV also syncs to R7=6, but R7=5 is too much for it

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Sat Jul 15, 2017 8:25 pm

I've released a new version on the GitHub page; for Electron users the main differences are:
  • a risk of occasional visual glitching has been eliminated; and
  • the CSW file format is now supported.
Support for CSW throws the ball back into the tape hardware emulation court however, and strongly suggests that the simple logic I currently use — a sanity bounds check and then a simple fixed threshold test for classifying waves as either short or long — isn't really sufficient. I doubt anybody knows exactly what the real hardware does, but probably throwing an instance of the same PLL used by the disk drives at the problem is appropriate. I'll have a poke around.

I've added another emulated machine, in the Sinclair ZX80 and '81, but that's a little provisional. Unlike the other machines it doesn't quite manage automatically to launch software — it loads it but then leaves you to figure it out. So I'm failing against my own ambition to make the emulator an invisible intermediary for people that just want to try software they haven't seen before, rather than also suffer through researching platform idioms. Which is even more acute with the odd Sinclair typing mechanism.

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Sun Jul 16, 2017 11:42 pm

Update on this, in case anybody is interested: formalising Acorn tape input as a PLL-driven shifter does indeed lead to better results than the hard threshold of old.

So the next release should be able to make sense of even more CSWs than the current.

Tech specifics:

I've set up a PLL with an expected window size of 1/4800th of a second. The PLL is fed with an event at every zero crossing. So it's stretching or compressing the window size according to the timing of zero crossings, and adjusting phase to try to keep crossings in the centre of the window. It has an output shift register that receives either a 0 for no events inside the window, or a 1 for an event inside the window.

If the low four bits of the shift register read 0x5 then that looks like a single wave at 1200Hz. So that's a 0. If the low four bits of the shift register read 0xf then that looks like two waves at 2400Hz. So that's a 1.

If the shift register has anything in the low four bits other than 0x5 or 0xf, or if a 0 or 1 was output less than four shifts ago, then there is no output.

I'm sure that an original real PLL uses an infinite impulse response filter, much like the emulator does for CRT emulation. But in this case I've used a finite impulse response filter, which simply buckets and averages over a 'long' history of zero crossings. I considered being a bit smarter than what amounts to box sampling, but decided not to bother for now.

The exact same PLL is used for disk reading so additional test data is welcome. Add another plus to the column for maximum code sharing in emulation. There's already a reasonable amount of shared work between the disk and tape subsystems because a disk track is basically a circular tape, but prior to this the PLL lived on one side of the boundary only.

User avatar
BigEd
Posts: 1486
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby BigEd » Mon Jul 17, 2017 4:10 am

Interesting, and a great result! One day, perhaps, we'll get the logic circuit of the Elk ULA, and can answer the question as to how cassette demodulation is done. We do already have a high res die photo.

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Mon Jul 31, 2017 4:00 pm

Quick update: a new release has been posted.

As discussed, the primary change is that the fixed threshold approach to tape input sampling has been replaced with a PLL-dictated variable threshold — which makes it sound fancier than perhaps is justified but the key point is: better CSW support.

It's not the sort of emulator where one thing is unnecessarily coupled to another so both slow and fast loading should work exactly as well with a CSW as with a UEF. It's all just tape samples.

Follow-on query: did anyone preserve the archives of Acorn Preservation? My non-synthetic test data is just a few CSWs that I happened to find attached to posts here and it'd be good to expand that set.

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Wed Aug 16, 2017 2:45 pm

Minor announcement: another new version is out.

With regards to the Electron, the main fix is that by repeated overlapping writing you could previously put a floppy disk into an invalid state that, in practice, was likely to prevent visibility of the later part of a track (i.e. higher-numbered sectors, if you formatted normally). It's unlikely in practice but easy to achieve if you know what you're aiming for.

It has also gained provisional support for the Amstrad CPC, which isn't that interesting around here other than that adding a machine that's so heavy on floppy access uncovered the latent Electron-affecting bug. So that's nice.

---

Technical explanation of bug as being potentially interesting for other authors:

The emulator's version of a disk track is that it's just a looping event stream. Events are either (i) passing of the index hole; or (ii) a flux transition, and each event is timestamped. The disk controllers know nothing beyond that, and each file format is free to provide any mechanism for generating events that it desires. It's whatever each, individually, wants to do. There is no forced assumption about the regularity of flux transitions, or their motivation, or anything like that.

When the controllers want to write to a track, they're also free to do what they want, but in practice all fire up something called a PCM-patched track. It's the combination of (i) an underlying track; and (ii) a list of PCM-sampled data segments that have been written on top of it. All implemented controllers have the property that they write data with a fixed clock, so saying that for a period of Q the following flux transition bit stream is serialised at rate X is a complete description. It doesn't impose a track-wide clock rate, or an encoding, or in any other way affect the parts of the track it doesn't touch.

One of the things a controller might do is write such a PCM segment, then later write another segment that overlaps the original. In that case the PCM-patched track does some splicing. It doesn't change the underlying data because it isn't necessarily the case that the splice point aligns with the clock of the thing being trimmed. It just changes the period for which it expects to draw data from that PCM patch.

So you're probably ahead of me, but the mistake was when trimming an existing segment's left. In that case it was correctly recording where it should begin in the underlying data upon entering that segment, but failing to honour it later.

So e.g. if you reformatted a track, then wrote a sector, you: (i) wrote a track-length PCM segment containing the initial contents of all sectors; then (ii) inserted a sector-length PCM segment on top of that where the sector is. Therefore the original PCM segment is now referenced by two periods of track time — the area before the newly-written sector and the area afterwards. Except that it would start again from the beginning of the track-length PCM segment after exiting the sector-length part. So any sectors from before the replaced one would were mirrored, possibly including the original copy of the modified one, and usually some at the end of the track become inaccessible.

This remained latent because in practice it almost never happens. The underlying track receives special treatment because its an unknown quantity. Is it PCM sampled too? Nobody knows. It's whatever is most appropriate when implementing that file format. So it depends on the file format. Disk controllers are fully insulated from file formats so they know nothing. It also has the special property that it will always begin exactly at the index hole and end exactly before the next. So the time calculations are simplified.

Therefore just writing sectors to an underlying track doesn't trigger the mistake. You need newly-written content to end somewhere within other content that you wrote yourself. Hence reformatting-and-writing as a clear failure case.

Other notes:
  • the concept of time, that I've glossed over, also isn't beholden to any particular clock rate. It's all quotients, with a 32-bit numerator and a 32-bit denominator. With no requirement of common denominators, it's all handled and, in practice, usually with exact arithmetic.
  • as implied, disk file formats that want to be modifiable can't actually assume that the representation of a written-to track has any particular relation to how their file format stores data. So they end up doing a from-flux parsing of any modified tracks.

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you [...] like your Electron emulators minimal [...]?

Postby ThomasHarte » Sat Nov 11, 2017 4:59 am

Minor update: I've at least made a genuine attempt at doing something for Linux. If anybody out there reads this and has Linux installed, would they be willing to give it a shot? There's no UI and it doesn't explain itself well being a very rough first effort so Electron instructions in full:

  • extract binary or build from source;
  • into either /usr/share/CLK/Electron or /usr/local/share/CLK/Electron place at least os.rom and basic.rom, and also DFS-1770-2.20.rom, ADFS-E00_1.rom and ADFS-E00_2.rom if you plan on launching DFS or ADFS software;
  • invoke with clksignal yourfile.uef (or .ssd or .adf or...).

If you wanted to build from source: download source or clone from https://github.com/TomHarte/CLK then run scons from within OSBindings/SDL. Prerequisites are SDL 2, ZLib and OpenGL. It uses the core profile so you'll need something that supports at least OpenGL 3.0, I think.

The general aim is first to support a decent complement of command-line options, then possibly to add some sort of kiosk interface, then to try to support at least OpenGL ES 2. I have in mind that it'd be nice to run on a Raspberry Pi and/or in a browser. Right now though, I'm unclear whether it runs at all as either my virtual machine doesn't have the appropriate OpenGL support or I've messed up the linking somehow.

If you try it then let me know?

(also: Mac users might like to update to the latest version on GitHub anyway. It corrects potential end-of-line display errors and runs very slightly faster again because I'd made a logical error in my attempt at proper DWORD alignment when writing pixels)

SteveF
Posts: 439
Joined: Fri Aug 28, 2015 8:34 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby SteveF » Sat Nov 11, 2017 7:19 pm

Great stuff, thanks! I've given it a quick go on Ubuntu 16.04.3 (on x86-64). I get build failures:

Code: Select all

steven@riemann:~/src/CLK/OSBindings/SDL$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o main.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 main.cpp
main.cpp: In lambda function:
main.cpp:202:46: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
    fread(data->data(), 1, data->size(), file);
                                              ^
g++ -o /home/steven/src/CLK/Components/1770/1770.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Components/1770/1770.cpp
g++ -o /home/steven/src/CLK/Components/6522/Implementation/6522Base.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Components/6522/Implementation/6522Base.cpp
g++ -o /home/steven/src/CLK/Components/6522/Implementation/IRQDelegatePortHandler.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Components/6522/Implementation/IRQDelegatePortHandler.cpp
g++ -o /home/steven/src/CLK/Components/6560/6560.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Components/6560/6560.cpp
g++ -o /home/steven/src/CLK/Components/8272/i8272.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Components/8272/i8272.cpp
g++ -o /home/steven/src/CLK/Components/AY38910/AY38910.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Components/AY38910/AY38910.cpp
g++ -o /home/steven/src/CLK/Concurrency/BestEffortUpdater.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Concurrency/BestEffortUpdater.cpp
g++ -o /home/steven/src/CLK/Concurrency/AsyncTaskQueue.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Concurrency/AsyncTaskQueue.cpp
g++ -o /home/steven/src/CLK/Inputs/Keyboard.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/Inputs/Keyboard.cpp
/home/steven/src/CLK/Inputs/Keyboard.cpp: In member function 'virtual void Inputs::Keyboard::set_key_pressed(Inputs::Keyboard::Key, bool)':
/home/steven/src/CLK/Inputs/Keyboard.cpp:16:2: error: 'size_t' was not declared in this scope
  size_t key_offset = static_cast<size_t>(key);
  ^
/home/steven/src/CLK/Inputs/Keyboard.cpp:16:2: note: suggested alternatives:
In file included from /usr/include/c++/5/bits/stl_algobase.h:59:0,
                 from /usr/include/c++/5/vector:60,
                 from /home/steven/src/CLK/Inputs/Keyboard.hpp:12,
                 from /home/steven/src/CLK/Inputs/Keyboard.cpp:9:
/usr/include/x86_64-linux-gnu/c++/5/bits/c++config.h:196:26: note:   'std::size_t'
   typedef __SIZE_TYPE__  size_t;
                          ^
/usr/include/x86_64-linux-gnu/c++/5/bits/c++config.h:196:26: note:   'std::size_t'
/home/steven/src/CLK/Inputs/Keyboard.cpp:17:5: error: 'key_offset' was not declared in this scope
  if(key_offset >= key_states_.size()) {
     ^
/home/steven/src/CLK/Inputs/Keyboard.cpp:20:14: error: 'key_offset' was not declared in this scope
  key_states_[key_offset] = is_pressed;
              ^
/home/steven/src/CLK/Inputs/Keyboard.cpp: In member function 'bool Inputs::Keyboard::get_key_state(Inputs::Keyboard::Key)':
/home/steven/src/CLK/Inputs/Keyboard.cpp:35:2: error: 'size_t' was not declared in this scope
  size_t key_offset = static_cast<size_t>(key);
  ^
/home/steven/src/CLK/Inputs/Keyboard.cpp:35:2: note: suggested alternatives:
In file included from /usr/include/c++/5/bits/stl_algobase.h:59:0,
                 from /usr/include/c++/5/vector:60,
                 from /home/steven/src/CLK/Inputs/Keyboard.hpp:12,
                 from /home/steven/src/CLK/Inputs/Keyboard.cpp:9:
/usr/include/x86_64-linux-gnu/c++/5/bits/c++config.h:196:26: note:   'std::size_t'
   typedef __SIZE_TYPE__  size_t;
                          ^
/usr/include/x86_64-linux-gnu/c++/5/bits/c++config.h:196:26: note:   'std::size_t'
/home/steven/src/CLK/Inputs/Keyboard.cpp:36:5: error: 'key_offset' was not declared in this scope
  if(key_offset >= key_states_.size()) return false;
     ^
/home/steven/src/CLK/Inputs/Keyboard.cpp:37:21: error: 'key_offset' was not declared in this scope
  return key_states_[key_offset];
                     ^
scons: *** [/home/steven/src/CLK/Inputs/Keyboard.o] Error 1
scons: building terminated because of errors.


I didn't spend any time fiddling around to try to make this work (yet). Let me know if you need any more information...

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Sat Nov 11, 2017 7:36 pm

SteveF wrote:Great stuff, thanks! I've given it a quick go on Ubuntu 16.04.3 (on x86-64). I get build failures:...

I didn't spend any time fiddling around to try to make this work (yet). Let me know if you need any more information...

Seems to be just one failure: no visibility of size_t. I guess it probably should be std::size_t since I've fallen into the habit of using e.g. <cstdio> rather than <stdio.h>. I've been building under Ubuntu MATE 17.10 because I don't really need long-term support but I think I can probably figure this out. I'll have a quick poke around. Did you try the binary I posted? I know that's not an ideal or normal way to distribute open source software, just curious as a stop-gap.

Thanks for testing!

ThomasHarte
Posts: 363
Joined: Sat Dec 23, 2000 5:56 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby ThomasHarte » Sat Nov 11, 2017 8:33 pm

SteveF wrote:Great stuff, thanks! I've given it a quick go on Ubuntu 16.04.3 (on x86-64). I get build failures: ...

I've sort of rushed it in, but it might be worth pulling from master now and trying again. I've corrected all references to size_t and am working on the various other C types that I've used without being formal as to namespacing.

SteveF
Posts: 439
Joined: Fri Aug 28, 2015 8:34 pm

Re: Do you own a Mac, and like your Electron emulators minimal and potentially seizure-inducing?

Postby SteveF » Sat Nov 11, 2017 10:12 pm

Thanks for the update, that's helped but I now get a different build failure:

Code: Select all

steven@riemann:~/src/CLK/OSBindings/SDL$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.o -c --std=c++11 -O3 -D_REENTRANT -I/usr/include/SDL2 /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.cpp
In file included from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/../DiskImage.hpp:96:0,
                 from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/MFMSectorDump.hpp:12,
                 from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/AcornADF.hpp:12,
                 from /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.cpp:27:
/home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/../DiskImageImplementation.hpp: In member function 'void Storage::Disk::DiskImageHolder<T>::flush_tracks()':
/home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/../DiskImageImplementation.hpp:28:82: error: no matching function for call to 'std::map<Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> >::insert(std::pair<Storage::Disk::Track::Address, Storage::Disk::Track*>)'
    track_copies->insert(std::make_pair(address, cached_tracks_[address]->clone()));
                                                                                  ^
In file included from /usr/include/c++/5/map:61:0,
                 from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/Disk.hpp:12,
                 from /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.hpp:13,
                 from /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.cpp:9:
/usr/include/c++/5/bits/stl_map.h:612:7: note: candidate: std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Allocator>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const value_type&) [with _Key = Storage::Disk::Track::Address; _Tp = std::shared_ptr<Storage::Disk::Track>; _Compare = std::less<Storage::Disk::Track::Address>; _Alloc = std::allocator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >; typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Allocator>::rebind<std::pair<const _Key, _Tp> >::other>::iterator = std::_Rb_tree_iterator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> >]
       insert(const value_type& __x)
       ^
/usr/include/c++/5/bits/stl_map.h:612:7: note:   no known conversion for argument 1 from 'std::pair<Storage::Disk::Track::Address, Storage::Disk::Track*>' to 'const value_type& {aka const std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> >&}'
/usr/include/c++/5/bits/stl_map.h:620:9: note: candidate: template<class _Pair, class> std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Allocator>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(_Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = Storage::Disk::Track::Address; _Tp = std::shared_ptr<Storage::Disk::Track>; _Compare = std::less<Storage::Disk::Track::Address>; _Alloc = std::allocator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >]
         insert(_Pair&& __x)
         ^
/usr/include/c++/5/bits/stl_map.h:620:9: note:   template argument deduction/substitution failed:
/usr/include/c++/5/bits/stl_map.h:616:32: error: no type named 'type' in 'struct std::enable_if<false, void>'
       template<typename _Pair, typename = typename
                                ^
/usr/include/c++/5/bits/stl_map.h:633:7: note: candidate: void std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::initializer_list<std::pair<const _Key, _Tp> >) [with _Key = Storage::Disk::Track::Address; _Tp = std::shared_ptr<Storage::Disk::Track>; _Compare = std::less<Storage::Disk::Track::Address>; _Alloc = std::allocator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >]
       insert(std::initializer_list<value_type> __list)
       ^
/usr/include/c++/5/bits/stl_map.h:633:7: note:   no known conversion for argument 1 from 'std::pair<Storage::Disk::Track::Address, Storage::Disk::Track*>' to 'std::initializer_list<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >'
/usr/include/c++/5/bits/stl_map.h:662:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, const value_type&) [with _Key = Storage::Disk::Track::Address; _Tp = std::shared_ptr<Storage::Disk::Track>; _Compare = std::less<Storage::Disk::Track::Address>; _Alloc = std::allocator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >; std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> >]
       insert(const_iterator __position, const value_type& __x)
       ^
/usr/include/c++/5/bits/stl_map.h:662:7: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/5/bits/stl_map.h:673:9: note: candidate: template<class _Pair, class> std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, _Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = Storage::Disk::Track::Address; _Tp = std::shared_ptr<Storage::Disk::Track>; _Compare = std::less<Storage::Disk::Track::Address>; _Alloc = std::allocator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >]
         insert(const_iterator __position, _Pair&& __x)
         ^
/usr/include/c++/5/bits/stl_map.h:673:9: note:   template argument deduction/substitution failed:
In file included from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/../DiskImage.hpp:96:0,
                 from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/MFMSectorDump.hpp:12,
                 from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/AcornADF.hpp:12,
                 from /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.cpp:27:
/home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/../DiskImageImplementation.hpp:28:82: note:   cannot convert 'std::make_pair(address, ((Storage::Disk::DiskImageHolder<T>*)this)->Storage::Disk::DiskImageHolderBase::cached_tracks_[address]->.Storage::Disk::Track::clone())' (type 'std::pair<Storage::Disk::Track::Address, Storage::Disk::Track*>') to type 'std::map<Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> >::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >}'
    track_copies->insert(std::make_pair(address, cached_tracks_[address]->clone()));
                                                                                  ^
In file included from /usr/include/c++/5/map:61:0,
                 from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/Disk.hpp:12,
                 from /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.hpp:13,
                 from /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.cpp:9:
/usr/include/c++/5/bits/stl_map.h:688:9: note: candidate: template<class _InputIterator> void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = _InputIterator; _Key = Storage::Disk::Track::Address; _Tp = std::shared_ptr<Storage::Disk::Track>; _Compare = std::less<Storage::Disk::Track::Address>; _Alloc = std::allocator<std::pair<const Storage::Disk::Track::Address, std::shared_ptr<Storage::Disk::Track> > >]
         insert(_InputIterator __first, _InputIterator __last)
         ^
/usr/include/c++/5/bits/stl_map.h:688:9: note:   template argument deduction/substitution failed:
In file included from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/../DiskImage.hpp:96:0,
                 from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/MFMSectorDump.hpp:12,
                 from /home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/AcornADF.hpp:12,
                 from /home/steven/src/CLK/StaticAnalyser/StaticAnalyser.cpp:27:
/home/steven/src/CLK/StaticAnalyser/../Storage/Disk/DiskImage/Formats/../DiskImageImplementation.hpp:28:82: note:   candidate expects 2 arguments, 1 provided
    track_copies->insert(std::make_pair(address, cached_tracks_[address]->clone()));
                                                                                  ^
scons: *** [/home/steven/src/CLK/StaticAnalyser/StaticAnalyser.o] Error 1
scons: building terminated because of errors.


Again, I haven't tried looking into this myself.

I'm happy to give your binary a try but I can't see it; am I missing an attachment or something? Please provide idiot-proof instructions on where to look...


Return to “emulators”

Who is online

Users browsing this forum: No registered users and 5 guests