Iron Maiden chiptune musicdisc + 26 kHz mod/ahx player

Announce (tech) demos or games releases

Moderator: Mask of Destiny

gasega68k
Very interested
Posts: 141
Joined: Thu Aug 22, 2013 3:47 am
Location: Venezuela - Caracas
Contact:

Post by gasega68k » Tue Dec 02, 2014 4:32 am

This sounds amazing! :)

How accurate is the emulator Regen in this demo compared to the real Genesis? (I tried several emulators and Regen is the one that sounds good).

twosixonetwo
Very interested
Posts: 58
Joined: Tue Feb 25, 2014 3:38 pm

Post by twosixonetwo » Tue Dec 02, 2014 3:26 pm

Kabuto wrote:I'm writing 2 samples at once. I mix one sample (-> 16 bits), then use "swap" to shift the word to the upper half of its register, then mix another sample, and then write both at once to z80. I only hog the z80 bus for this short time frame so the z80 code does not get halted for too long which would degrade audio quality (jitter).
I find this very interesting, as I would have thought that even this short time is enough to have noticable jitter at 26khz, but nope, the audio sounds perfectly clear.

Also, as I am currently looking into how hard it would be to write a custom "OS" for the (standard) everdrive this made me think: It would be awesome to be able to just put mods on the sd card and play them on the mega drive, without having to put them in a binary and flash them first...

Kabuto
Interested
Posts: 27
Joined: Sun Aug 25, 2013 6:56 pm

Post by Kabuto » Wed Dec 03, 2014 12:21 am

Regarding jitter, I remember doing tests for how much delay is acceptable before jitter becomes an issue, and guess what, different values for real hardware and all emulators tested (regen and exodus). But I didn't do any measurements in this case here, maybe there is some jitter and it's just difficult to hear. Needs more tests for sure!

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Wed Dec 03, 2014 1:05 am

Just an off-the-cuff calculation on stopping the Z80, writing a long, then releasing the Z80 says any jitter would be over 70 kHz... well out of the audible range of hearing. As long as this wasn't in a tight loop, it's really negligible.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Wed Dec 03, 2014 11:23 am

Do you know how much time it requires to request Z80 BUS from 68000 ? i know it does take a bunch of cycles... how many exactly no idea though.

Mask of Destiny
Very interested
Posts: 615
Joined: Thu Nov 30, 2006 6:30 am

Post by Mask of Destiny » Wed Dec 03, 2014 9:04 pm

According to the Z80 manual, the bus request line is sampled on the rising edge of the clock at the beginning of the last t-state of an M cycle and busack will go low sometime before the falling edge of the clock on the following t-state. So in the best case, it will take around 1.5 Z80 cycles which is ~3.25 68K cycles which would be effectively instantaneous given the length of a 68K memory cycle. In the worst case, you just miss the sampling point before a 6 t-state m-cycle which would be something like a 7 Z80 cycle delay. That translates to 15 68K cycles.

Of course this assumes the Z80 manual is correct (which is questionable given some of the obvious errors in other parts) and ignores any propagation delays created by the Genesis bus arbiter hardware. I should probably measure it at some point.

Kabuto
Interested
Posts: 27
Joined: Sun Aug 25, 2013 6:56 pm

Post by Kabuto » Wed Dec 03, 2014 11:27 pm

Very interesting. I thought it was about whole instructions, but that makes my life easier a bit :)

Just had a look at some z80 docs I found on the web, and made this list of 6T instructions:
* all that transfer from or to the SP register
* INC/DEC 16-bit-reg

and 5T instructions:
* all that use (IX+d) / (IY+d) addressing modes
* all that transfer from or to the I or R register
* EX (SP), 16-bit-reg
* PUSH
* JR (unless condition is not met)
* DJNZ
* conditional RET
* RST
* all repeatable opcodes, whether repeated or not

and checking my z80 code, I'm not using any of them, so assuming no further delays I'd have a delay of 11 68k cycles :D

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Thu Dec 04, 2014 12:45 am

Mask of Destiny wrote:According to the Z80 manual, the bus request line is sampled on the rising edge of the clock at the beginning of the last t-state of an M cycle and busack will go low sometime before the falling edge of the clock on the following t-state. So in the best case, it will take around 1.5 Z80 cycles which is ~3.25 68K cycles which would be effectively instantaneous given the length of a 68K memory cycle. In the worst case, you just miss the sampling point before a 6 t-state m-cycle which would be something like a 7 Z80 cycle delay. That translates to 15 68K cycles.

Of course this assumes the Z80 manual is correct (which is questionable given some of the obvious errors in other parts) and ignores any propagation delays created by the Genesis bus arbiter hardware. I should probably measure it at some point.
That sounds really short O_o ? at least compared to what i observed when i developed Gens (it was more about 40 to 80 68000 cycles as far i remember) but as the emulator was really off on many timings maybe it was one of them :p

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Thu Dec 04, 2014 2:16 am

Stef wrote:
Mask of Destiny wrote:According to the Z80 manual, the bus request line is sampled on the rising edge of the clock at the beginning of the last t-state of an M cycle and busack will go low sometime before the falling edge of the clock on the following t-state. So in the best case, it will take around 1.5 Z80 cycles which is ~3.25 68K cycles which would be effectively instantaneous given the length of a 68K memory cycle. In the worst case, you just miss the sampling point before a 6 t-state m-cycle which would be something like a 7 Z80 cycle delay. That translates to 15 68K cycles.

Of course this assumes the Z80 manual is correct (which is questionable given some of the obvious errors in other parts) and ignores any propagation delays created by the Genesis bus arbiter hardware. I should probably measure it at some point.
That sounds really short O_o ? at least compared to what i observed when i developed Gens (it was more about 40 to 80 68000 cycles as far i remember) but as the emulator was really off on many timings maybe it was one of them :p
Even if it was 80 cycles, it's only 20 to store a long from memory, and another 12 to release the Z80... meaning at most 112 cycles, or 68 kHz jitter. Like I said, a rough calculation of worst case jitter is well above the hearing threshold.

Mask of Destiny
Very interested
Posts: 615
Joined: Thu Nov 30, 2006 6:30 am

Post by Mask of Destiny » Thu Dec 04, 2014 2:55 am

Stef wrote:That sounds really short O_o ? at least compared to what i observed when i developed Gens (it was more about 40 to 80 68000 cycles as far i remember) but as the emulator was really off on many timings maybe it was one of them :p
Well, 3.25-15 68K cycles is just the time from the write to busreq until busack changes. Realistic 68K code to set busreq and wait for busack will be longer than that and as mentioned there may be other delays introduced by hardware in between the 68K and the Z80's busreq/busack lines.

@Kabuto: Yeah, 6T instructions are quite easy to avoid and even 5T is only a relatively small subest. 4T and 3T m cycles are much more common.

Another thing I failed to take into account are accesses to the banked area. I believe that adds an extra 2 cycles to the m-cycle that does the read. Those are typically only 3T cycles though so it only jumps up to 5T.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Thu Dec 04, 2014 9:01 am

Chilly Willy wrote: Even if it was 80 cycles, it's only 20 to store a long from memory, and another 12 to release the Z80... meaning at most 112 cycles, or 68 kHz jitter. Like I said, a rough calculation of worst case jitter is well above the hearing threshold.
Yeah indeed 112 cycles is not enough to be noticeable, hopefully ;)

bastien
Very interested
Posts: 208
Joined: Mon Jun 25, 2007 7:19 pm
Location: Besançon,France
Contact:

Post by bastien » Thu Dec 04, 2014 7:27 pm

Woah ! that's an Amazing Things really :twisted:
Thanks you very much to all for your works.
I can't stop to listen it :D

Kabuto
Interested
Posts: 27
Joined: Sun Aug 25, 2013 6:56 pm

Post by Kabuto » Fri Dec 05, 2014 8:34 pm

Guess I'll be able solve the IRQ troubles in a neat way, no more timing shenanigans ;)

Basically, there have been 2 issues that made me block IRQs for longer timeframes. One is that I need to halt the z80 for writing to its memory (IRQs would prolong that too much and cause well audible glitches), the other issue being that I just ran out of registers in the mixer code and even repurposed the a7 register. I could trade it for 8 additional cycles per sample mixed though that would already be 3% of the precious CPU time.

And fixed both... almost :)

For the address register: The 68k supports separate user/hypervisor modes. (68k boots up in supervisor mode, though when you clear the S flag it restricts which opcodes you may use, including setting the S flag again. No memory protection whatsoever, that would have to be done with external circuitry, which the MD didn't do.)

The neat thing is that these 2 modes have separate a7 registers, and interrupts always user supervisor mode, so to abuse this simply make your background thread run in user mode, freely repurpose the a7 register without any need to disable IRQs, and any interrupts will switch back to the original a7 register before they write to the stack, and restore things back to normal afterwards.

Then, there's still the issue: how to deal with interrupts that interrupt a Z80 access? There's a solution for that too:

Code: Select all

; interrupt start
    bclr #0, $a11100   ; unpause z80, Z flag will tell whether it has been paused
    move.w sr, -(a7)   ; push Z flag to stack, we don't need it right now
    ...interrupt code...
    move.w (a7)+, sr  ; get Z flag back
    bne.s @rte\@  ; if it's set, the z80 was running upon IRQ entry, so no action needed
    move.w #$100, $A11100 ; if it was clear it was paused, so pause it again
@rte: rte
Last thing to do is to carefully tweak the z80 code to be more tolerant to additional pauses (entering a IRQ handler takes 44 cycles - add more unavoidable worst case delays, and get like 80 to 90 cycles). To avoid jitter there's a timeframe of 144 cycles (iirc), within which the sample must be written. Some testing is required to hit that timeframe precisely - early testing already revealed that neither regen nor exodus gets that totally right.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Fri Dec 05, 2014 9:59 pm

It was commonplace on the Atari ST to repurpose the user sp for pseudo-dma of pcm data. It made int-driven pcm use much less overhead. The same could be done on the Genesis if you wished the 68000 to do the pcm playback with less overhead.

Mask of Destiny
Very interested
Posts: 615
Joined: Thu Nov 30, 2006 6:30 am

Post by Mask of Destiny » Fri Dec 05, 2014 11:13 pm

Any plans for an NTSC compatible version? I gave it a try on my Genesis and it locked up shortly after the crowd appeared. Not a huge surprise given the warning screen of course.

Testing it in BlastEm revealed a crash bug in my handling of retranslating modified instructions. After fixing that it works (both in PAL and NTSC mode which I suppose is a bug on my part), but the sound quality is poor. I've done a fair bit of work on getting the timing right for the Z80 accessing the 68K's bus, but I haven't done much for the reverse. Haven't had time to confirm that's the problem though.

Post Reply