Welcome, Guest. Please login or register.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - TomH

Pages: [1] 2
Apologies; editing seems not to be working. So, briefly to add:

... though there is perhaps a clue in the document that "[the actual display] clocks out on screen a bit later". If it were at least a two-column delay on fetched pixels getting into the video stream and no delay on reaction to the colour burst signal then I guess that would satisfy all the constraints simultaneously.

Yes, but according to the linked document it is completely incompatible with the standard composite signal format. I guess, Tom would like to know if composite and RGB video differs when display area width is larger than 42 cycles or how does NICK corrupts signal generation if it looks the same?

Yes, exactly that.

For now, for the purposes of my emulator, I have a colour burst being generated when in composite mode through until the end of column 9. So pixels can start in column 10 at the earliest. In RGB mode pixels can start in column 8, the first eight output being four cycles of sync and then four of blank. Though that's under-spec for PAL timing, regardless of the colour burst issue.

It's definitely possible that somebody pulled sync and the burst backwards by two or three cycles, to overlap the refresh fetches in the final three columns of the display, but if that's what happened then it's weird that there's no documentary evidence.

Quick summary: new release available, in the same locations as before: macOS, Snapcraft, repository.


The issue with Chase HQ is that there's a timing calibration routine around $680 which compares Dave's 50Hz counter and the rate at which the INT1 input changes. It dynamically reprograms the values loaded to B prior to the DJNZ busy loops in the assembly above, e.g. it'd write a suitable constant to $0BA0 in the first case.

I had bit 4 of $B4 reflecting the state of the input as active low. It appears that active high is correct. From this flowed all timing issues.

There is now only one weirdness that I know of in Enterprise emulation: outputting an entire frame of sync doesn't cause any visible output — my GPU handler, I think both the Metal and OpenGL versions, thinks that frame skipping must be afoot and leaves up what is currently on screen rather than blanking it out. This has probably been a bug in my display simulation for this emulator's entire lifespan, it just so happens that I've never realised.

I'll fix it in the near future.

Alas, no, things have actually gone the other way; since eliminating the '[not video] + [no wait states] + [M1 cycle] = [wait for video]' bug, Chase HQ now exhibits two faults:

  • the added introductary music plays way too fast, as do and did the sampled sound effects; and
  • the game occasionally pauses for several frames, which I think correlate to where the Spectrum and MSX would play speaker sound effects (and, honestly, I'm not sure what the CPC does).

I added a 6MHz CPU option in the hope of getting more input data, but it didn't reveal much. Though SIDBasic does correctly detect a 6MHz CPU and then output at a higher rate, so that's nice and reassuring.

So I'm extremely grateful for your having dug out the relevant routines. I note that, luckily for me, they're running from no-wait-state memory, and interacting only with Dave ports, so I think the smart thing to do next is to get pen and paper, figure out how many cycles I think the full loop should take, then see how many the emulator seems to think it should take.

The exact same Z80 has passed relevant timing tests on the ZX80/81, CPC and ZX Spectrum with the relevant WAIT and clock-stretching schemes in place, so I'm at least mildly optimistic that the problem is small and local. But we'll see. Almost a 100% chance it's a dumb coding error very specific to me rather than an Enteprise comprehension error that I could reasonably expect somebody else to know about.

This post contains the main source file, if you need more, i can send you.

Thanks again for this! The main emulation bugs affecting SIDBasic were:
  • a very faulty conditional meant that for M1 cycles 'not video' + 'no wait states' => wait for a video slot. Hence the low CPU speed detection (and, it seems, the flickering ship in R-Type); and
  • I wasn't applying ring modulation to channels in sync mode, hence the lack of audio production subsequently.

So: fixed, and here's the YouTube proof.

Time to start worrying about Chase HQ, I guess. I'll aim for a new binary release this weekend, most likely, as I'm sure more corrections will be identified before then.

This post contains the main source file, if you need more, i can send you.

Oh, fantastic! You're a hero!

I hope to be suitably ashamed about whatever my dumb error was, soon.

EDIT: after reading that, especially the speedts routine, and taking another look at the Dave documentation I can already see a flaw; my B4 b0 is toggling at the rate of the attached tone generator, or correspondingly at 2KHz or 100Hz for 1KHz and 50Hz interrupts, with the interrupt occurring on the downward toggle. So it's the exact same logic as for the external inputs. And ditto the 1Hz bit toggles at 2Hz.

But clearly the relevant bit is supposed to toggle at 1KHz or 50Hz or only upon the tone generator's downward stroke — the documentation is completely straightforward now that I review: "two flip-flops toggling off the timer interrupts". I dare imagine SIDBasic's false clock-speed conclusion is a direct result of that.

It also strikes me as I'm writing this that my implementation of the 1Hz input as completely disjoint from the 1KHz/50Hz, and the latter two as another programmable counter with limited reload options, is probably wrong. There's probably just some sort of internal cascading clock division going on, such that all three remain exactly in-phase for as long as the machine runs?

Anyway, thanks again! That's already really helped.

SIDBasic can be downloaded from the forum from downloads.
I hope it contains the sources also
Latest release

No, no sources included. A .com and a .rom and nothing more. And since it's described as working on an unmodified Enterprise, I've not even been using the .rom.

Cool :-)
I will try to test it next week if i have time.
what i saw in the video i r-type, the ship is flashing when crane lift it up, it does not flash on a 4MHz Ep, left 1-2 column is not visible of the demo end screen, as i remember it has 46 char width.

I guess I need to take another swing at video access timing; probably I have some sort of error in the way that fractional offsets between the two clocks pan out.

Otherwise: for now I'm still taking the official documentation as the best reference on column visibility; it has the colour burst active until the beginning of column 10 so in composite mode my emulator is producing a colour burst until column 10. R-Type tries to display pixels prior to column 10, so those pixels are usurped.

SidBasic plays digi from Dave interrupt, and interrupt frequency is set by frequency of  tone channel 1 or 2, and this frequency is calculated by CPU speed, which is get by number of 1KHz Dave interrupts within a 50Hz video interrupt. Probably there is small problem in Dave emulation.

I spoke too soon; SIDBasic is indeed receiving those interrupts and responding to them by adjusting the channel 0 volume, but since the last thing it wrote to port A7 was $65, it has channel 0 in sync mode, i.e. held at level 0, and hasn't activated direct-output mode. Therefore its adjustments of the channel 0 volume have no effect per my current implementation.

So I guess my next task is to figure out why $65 doesn't mean what I think it means, or else figure out what my emulator is doing incorrectly such that SIDBasic ends up writing $65.

It's a shame that the SIDBasic repository appears to contain the Spectrum player only.

Other thing, Let's go driver, and speccy emulated beeps are played by cpu (no interrupt is used for playback) as i remember, so it is very strange one is fast, the other is slow.

Yeah, that one remains a mystery to me too. I'm going to focus on SIDBasic first, I think, and maybe I'll get lucky and the same fix will fix both. If not, more work to do.

Very minor: I've added Enterprise emulation to the emulator that I write, Clock Signal, for macOS and other Unixes.

GitHub; macOS binary releases; Linux binary releases via Snapcraft.

On macOS it's a fully-native, signed application using Metal and the native UI. Elsewhere it is available both as a Qt GUI application and as an SDL build that's more useful for command-line invocation and for file associations.

Probably its most interesting feature is that it can simulate composite video by generating and then decoding the actual composite video stream. No post hoc blur-it-up-a-bit filters here. It also does audio by sampling internally at a sensible native rate for the emulated machine and then low-pass filtering down to whatever your host machine can output. So e.g. on any garden-variety Mac from the last decade or so you can listen to your Enterprise at 96 kHz.

That all being said, Enterprise support is very provisional and known to be imperfect. So tolerate it only as far as you can.

  • it supports IMG files only, there's presently no other way to load software; and
  • something is definitely off in terms of timing.

Notable software issues of which I'm aware include the conversion of the CPC version of Chase HQ playing its sampled sound (like 'Let's go, Mr Driver!' way too quickly, but then weirdly slowing way down every time it would make a sound effect that the Spectrum would use its toggle speaker for; and SIDBASIC reporting a 3MHz CPU And then just not playing any audio. Like, no Dave writes at all, not like I'm processing the audio incorrectly.

Any other feedback would be greatly appreciated. Some screenshots are attached. Alternatively, here it is on YouTube.


Some random technical details, in case they're interesting:

In this implementation Nick runs 40434603/11360000ths as fast as the CPU, which is currently always 4Mhz. So I've clocked Nick at around 14.2375Mhz.

If the Z80 performs a Nick access it must wait to start the final clock cycle of its machine cycle until it is in the first two Nick cycles of the six-cycle block allocated for Z80 access. I should read mode on this. I observed that the entire six-cycle window is only around 1.68 Z80 cycles long, but of course the Z80 is paused in half-cycle increments so the maximum it could depend upon getting is 1.18 cycles of clear space. Hence fitting the final cycle into that window.

Nick's interrupt output is adjusted immediately after reading that byte of the mode line.

I wasn't clear on the correct way to transition between noise polynomials on Dave, so that's probably inaccurate. But the LFSRs all use IstvanV's documented polynomials, at least.

lgb.hu mentions that "There is some odd behaviour that you can read the (Nick's) bus state on these I/O ports. In theory it can be used for some video effects. I can't say I can understand that very well though :)"; through a lack of further information reads from my Dave return the last byte fetched, if any, otherwise 0xff. That's permitting for the fact that I haven't read up on how the refresh addresses are generated though.

As per my reading of the documentation, column 10 is the first one output in composite mode. The colour burst covers columns 8 and 9. Output starts at column 8 in RGB mode, even on lines in which a mode line isn't read.

There's a simulated spinning platter for disks, so floppy access should be approximately real time.

Because the simulated CRT runs a couple of phase-locked loops to track discriminated syncs, you'll get some screen bouncing during phase-breaking display transitions.

It's likely I'll add tape image support before figuring out a way to bridge to the local filing system, though for the latter I'm thinking of maybe implementing an IDE drive and mapping FAT back and forth. That'd be more reusable with other machines I implement, e.g. the MSX and Atari ST both also use FAT12 and FAT16.

I forgot I hadn't yet implemented the 8/12MHz Dave divider. It'll be in the next release. I don't think it factors into any of the known incompatibilities.

Slightly to answer my own question on this, I'm pretty confident that Time's Hand (and, I've subsequently discovered, also SIDBASIC) do indeed just specify more graphics than can be expected to appear.

The pre-release technical information is the most explicit, stating that "In practice this value will not be below 10 for the left-hand edge of the CRT"; the final, 1985-era documentation is slightly more oblique but stipulates that "a practical limit to the display width is 42 slots, using a left margin value of 10 and a right margin of 52", although some of that's implied to be due to overscan rather than the front and back porches.

So, no, it probably wouldn't have appeared odd to the authors if they tried their code on a real machine with a composite connection and noticed left clipping.

Oh, and at the time of writing this post both links in you OP point to the same demo. Furthermore, my guess would be that this place has more demos than Pouët.

Copying and pasting is apparently very hard for me. This is Scroll Demo.

I couldn't quite figure it out how these things work but you should give a try to the NICK Internal timing document. There are detailed diagrams how, when and what and parts of video signal composition are triggered.

That's one of my sources — check out the top of page 12. /BURST is depicted running from the start of slot 6 to the end of slot 9. Conversely, Time's Hand starts graphics at the beginning of slot 9.

(Unless I've misunderstood the way the comparitors work for effecting left and right margin values)

So I guess probably the answer is that a composite output will not display column 9, since the colour burst is still ongoing, but if you've covered the entire display in pixels then it's not a surprise that some are off-screen. I guess the RGB path ignores the colour burst trigger and can generate pixels from column 8.

Alternatively, it does seem strange to me that there are 11 slots occupied by non-pixel fetches, and — in composite — 10 slots in which pixels cannot be output, but per the documentation the 10 is not wholly inside the 11. There's only 8 slots of overlap.

Apologies; this'll probably just reveal that I've misread or misunderstood documentation. But here we go. These are a couple of demos that superficially appear to be doing nonsensical or incorrect things, to this observer.

The relevant parts of my understanding of a single Nick line are:
  • slots 0–9 are unusable for pixel output because that's where sync and the colour burst occur; and
  • mode line parameters are fetched during slots 0–7.

So then can anybody explain how Scroll Demo is acting correctly in defining its vertical sync mode line as being two scan lines long, with a left margin of 0 and a right margin of 63? That's given that the mode line is entered from a region of the border colour.

To my understanding that should produce only a single line of the sync level. By the time the left margin has been read from the mode line, Nick is in column 1. Therefore at no point on the first line will the current column be equal to the left margin, so sync output won't begin. It'll begin at the start of the second line but then end slightly less than a line later when the next mode line is read in, with a different mode byte.

Therefore total sync time will surely be less than a line, not enough to trigger vertical sync on most screens? The PAL standard is 2.5 lines.

My question for The Time's Hand is somewhat more straightforward: it defines a left margin of 9. So am I correct to conclude that its first column simply isn't visible on composite and RF connections? That column should be occupied by colour burst.

I guess an underlying question is whether the numbers given for Nick above were true in production. In theory you could have moved up the sync to overlap the three slots at the end of each line reserved for refresh, and then have finished the colour burst before the mode line is even done. Which would explain Time's Hand, albeit make the problem slightly worse for Scroll Demo. Though an alternative explanation for the former could just be that the developer used an RGB connection, and that route gets pixels from slot 8 onwards, having no colour burst to include?

Knee-jerk observation: most of the polynomials listed don't actually look maximal in terms of states. Which is interesting, at least.

I withdraw this comment; there's two ways around you can implement these things — shifting left or shifting right — and I misunderstood which is being used. The automatic translation of IstvánV's comments has clarified my muddled reasoning.

To record them here, if you're talking in terms of LFSR polynomials written down in the same same form as those given at this resource then IstvánV lists:
  • 0xc
  • 0x14
  • 0x60
  • 0x110
  • 0x500
  • 0x6000
  • 0x12000

All of which are on the maximal-length polynomial lists as linked.

Audio is the next thing I have to implement, so my gratitude towards IstvánV is about to multiply by a thousand.

It is not a matter of a fight between emulators, but to add and complete the information we have about the hardware.

Oh, absolutely. I doubt I'm going to bring much to the table to be honest — other than perhaps providing a maintained, native-UI macOS option. If anything that might even take some other functionality off the table, since I actually quite like the sandbox as a user and therefore tolerate it as a developer, though e.g. it means not exposing the local filing system to the emulated Enterprise.

IstvánV (author of ep128emu) wrote so much about undocumented properties of Dave in the Hungarian forum.
These are collected and added to here as addendum ("Néhány kiegészítés a DAVE dokumentációjához").
Sorry it is in Hungarian, try with Chrome/Google translate :oops:

Wow, that hopefully means that I don't even need to go Ep128Emu source diving when relevant questions arise!

I ran it through an automatic translator and captured the resulting HTML here if anybody wants to skip a step. Luckily the output is still relatively clean. I guess I'll apply manual copy edits when I get a chance to inspect in detail, and then try to find somewhere to host the translation more permanently.

Right now I'm still implementing Nick, and already running up against a few queries, mostly to do with continuity between lines, especially when switching between vsync and any non-vsync mode — e.g. if you've set the left border for after the right on a pixel line that rolls into a vsync line, does the line begin in the outputting-vsync state rather than outputting blank? Luckily my CRT emulation seems to be able to sync lock even to my current naive implementation so I'm at least at the point of having stable output for sufficiently conventional line parameters, though it's fairly permissive with regards to vertical sync.

Anyway, I won't bore with the development-blog-level commentary.

Thanks to all for the assistance so far!

Pages: [1] 2