Sonic and Sega Retro Message Board: Sonic 1 "Mega PCM" driver - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
  • 4 Pages +
  • 1
  • 2
  • 3
  • 4
    Locked
    Locked Forum

Sonic 1 "Mega PCM" driver A new DAC driver for Sonic 1, version 1.1 is out!

#16 User is offline vladikcomper 

Posted 05 August 2012 - 11:27 AM

  • Posts: 182
  • Joined: 13-June 09
  • Gender:Male
  • Location:Russia
  • Project:Sonic Warped
  • Wiki edits:1
Mega PCM v.1.1

  • Added a small code-fix to prevent noise and memory access errors on playing empty/broken samples

    Now if the game attempts to play empty or not existing DAC sample slot, you won't hear anything. For example, if you imported an SMPS song and few DACs are missing in your driver. The previous Mega PCM version along with most of the drivers would give out random noise here due to playback errors.

    This also helps if a slot of random broken bytes somehow gets playing. Random offsets now won't cause errors on accessing prohibited memory areas, because they are fixed as well.

  • Fixed synchronization code issue in PCM and DPCM playback loops.

    While I've been counting every cycles in my code, I slightly miscalculated in calculating synchronization code cycle worth, which caused playback loop to work 4 cycles faster when the last bank reached. Therefore, sample's last bank played slightly faster then the rest. Despite 4 cycles (NOP opcode worth) being extremely small time period for Z80, playback speed up was noticeable on high sample rates (22 kHz and higher).

  • Mega PCM now supports up to 8 MB ROMs!

    The previous version was limited to 4 MB, but that wasn't the maximum of Mega PCM addressing capabilities though. I decided to push the limit to what the driver's bank switching system was really capable of, 8 MB. This means you can fit twice as much music and samples!

    I must warn though, very few emulators support big ROMs yet. But if you're still interested in this possibility, I'll try to clue you in (see below for the list of emulators):

    So, many people think that SMD is strictly limited to 4 MB in ROM storage. Actually, the console is capable of more. But the fact is, all the official game cartridges were designed with this limit in mind, their boards just weren't meant to address more than 4 MB of ROM-space, while the console allowed to do so. It was cartridges' limit, not the console's.

    For instance, some SMD flash-cartridges (like Mega Everdrive) support ROMs above 4 MB already, showing what the console is really capable of. However, emulators have very poor support for this.

    The matter is, that limit was tied by the official Genesis manual, where the memory map for 68K had only 4 MB of memory marked for ROM and the rest memory space up to 8 MB was marked as 'reserved'. It's interesting that in the earliest versions of this manual (1988-1989 years) the ROM limit was 1 MB. Many emulators' creators decided to strictly follow the manual and intentionally limited ROM-space to 4 MB. In principle, this makes sense and none of the official games suffered, but it would be rather good if more emulators got rid of this nasty limit, this will surely open up new horizons for SMD developing, bringing console a new life.

    As for now, there are quite few emulators with big ROMs support.
    Some of them are just hacked versions of popular emulators. You can find them here:
    http://umk3.hacking-...ng/download.htm


How to update my Mega PCM to version 1.1

Piece of cake.
Download this: https://dl.dropbox.c...aPCM_v11_Bin.7z
Replace MegaPCM.z80 file in your disassembly with a new one from the archive.
That's it.

Mega PCM v.1.1 Source code

https://dl.dropbox.c...1_SourceCode.7z

* * *

If you don't have Mega PCM yet, but you decided to use it, just follow the first post's instructions. Links in the post and the info is up to date as well.

* * *

Still coming soon (guides):

  • How to improve sample playback quality
  • How to play digital songs with "Mega PCM"


#17 User is offline Chilly Willy 

Posted 06 August 2012 - 05:24 PM

  • Posts: 746
  • Joined: 10-April 09
  • Gender:Male
  • Project:Doom 32X

View Postvladikcomper, on 05 August 2012 - 11:27 AM, said:

Mega PCM now supports up to 8 MB ROMs!

The previous version was limited to 4 MB, but that wasn't the maximum of Mega PCM addressing capabilities though. I decided to push the limit to what the driver's bank switching system was really capable of, 8 MB. This means you can fit twice as much music and samples!

I must warn though, very few emulators support big ROMs yet. But if you're still interested in this possibility, I'll try to clue you in (see below for the list of emulators):

So, many people think that SMD is strictly limited to 4 MB in ROM storage. Actually, the console is capable of more. But the fact is, all the official game cartridges were designed with this limit in mind, their boards just weren't meant to address more than 4 MB of ROM-space, while the console allowed to do so. It was cartridges' limit, not the console's.

For instance, some SMD flash-cartridges (like Mega Everdrive) support ROMs above 4 MB already, showing what the console is really capable of. However, emulators have very poor support for this.

The matter is, that limit was tied by the official Genesis manual, where the memory map for 68K had only 4 MB of memory marked for ROM and the rest memory space up to 8 MB was marked as 'reserved'. It's interesting that in the earliest versions of this manual (1988-1989 years) the ROM limit was 1 MB. Many emulators' creators decided to strictly follow the manual and intentionally limited ROM-space to 4 MB. In principle, this makes sense and none of the official games suffered, but it would be rather good if more emulators got rid of this nasty limit, this will surely open up new horizons for SMD developing, bringing console a new life.


The upper "reserved" 4MBytes is for the CD. Big roms don't work with either the CD or the 32X. It's not that Sega carts couldn't address more than 4MB, it's that the bus controller in the MD doesn't supply DTACK for the reserved areas. Simply adding in more rom results in a hang if you try to use it. Big rom capable boards add extra circuitry to the cart to generate its own select and dtack signals to keep the MD from hanging. This conflicts with the CD and 32X, and so only works on the MD by itself with nothing else plugged in.

Not that I'm saying you shouldn't support it, just adding some extra info on why there is only one big rom game (a Mortal Kombat hack), and why big roms don't work with the CD or 32X.

#18 User is offline Hivebrain 

Posted 06 August 2012 - 11:13 PM

  • Posts: 2744
  • Joined: 15-January 03
  • Gender:Male
  • Location:53.4N, 1.5W
  • Project:HivePal 2.0
  • Wiki edits:6,176
Isn't the limit 10MB? There's an extra 2MB reserved for 32X addresses ($800000-$9FFFFF).

#19 User is offline Chilly Willy 

Posted 08 August 2012 - 12:29 AM

  • Posts: 746
  • Joined: 10-April 09
  • Gender:Male
  • Project:Doom 32X

View PostHivebrain, on 06 August 2012 - 11:13 PM, said:

Isn't the limit 10MB? There's an extra 2MB reserved for 32X addresses ($800000-$9FFFFF).


Yep! That's the absolute largest a rom can be without resorting to bank selection. The hardware IO starts at 10MB, so you cannot go any higher.

#20 User is offline vladikcomper 

Posted 28 October 2012 - 11:09 AM

  • Posts: 182
  • Joined: 13-June 09
  • Gender:Male
  • Location:Russia
  • Project:Sonic Warped
  • Wiki edits:1
How to increase playback quality with Mega PCM

We all know what the SEGA screen sounds like in the original Sonic 1 title:

https://dl.dropbox.c...1/SEGA_Good.wav

But what if we try playing it during game? When massive data transfers take place between different parts of the system, the same sample will sound like this instead:

https://dl.dropbox.c...01/SEGA_Bad.wav

This sample quality loss occurs with all samples during the game; this means that all of your kicks, snares, whatever, all playback scratchy.

In this guide, I'll teach you how to solve this complex technical problem to achieve the best playback quality possible.
There is also an attachment at the end of this post; a clean disassembly with this guide applied + a little bonus.

After following this guide you can achieve impressive sample playback quality on Sega Genesis, like so:


But first, in order to fix the quality loss, we must first understand why it occurs.

The following text will contain a fair amount of theory and technical terminology. If you don't want to dive into incredible (!) shocking (!!) details, skip the next part and go straight to the second one.

1. Theoretical explanation

The problem here is not Mega PCM's fault, but Sonic 1's.

As you might know, there are two processors in the Sega Genesis; the Motorola 68000 and the Zilog "Z80". The game engine itself is processed on the M68K which controls most of the system features, though the other processor (the Z80), is used in Sonic 1 for digital samples playback. My driver (Mega PCM) works solely on the Z80.

As mentioned above, during the game, the engine has to communicate with different parts of the system, like the sound and video chips to update audio and video output. The console architecture, in turn, sets some limitations on accessing its own resources. For example, when accessing the YM2612 sound chip using the M68K, because the YM2612 is access within the Z80 memory space, the Z80 must be suspended to allow the M68K to access it.

During the game, Sonic 1 tends to stop Z80 under the following conditions:
  • When SMPS engine is running, as it needs access to the YM2612
  • During DMA-transfers to VRAM or CRAM

SMPS and DMA-transfers occur constantly at the end of every frame, and their execution can take some time. Hence, the Z80 is being stopped for quite a few times and for quite a while, and with this, Mega PCM execution stops, which means updating DAC (which is controlled entirely by Mega PCM) interrupts, causing distorted sound outputs.

As an example, pretend that we're playing a simple sine wave. Normally, it would look like this:

Posted Image

But in Sonic 1, the Z80 is being stopped quite a lot and during the stops Mega PCM isn't processing, so the wave isn't updated. If the sound chip does not receive a new wave signal, it will use the last one that was sent for playback, thus making the wave look like this instead:

Posted Image

The grey areas here are the periods when the Z80 is stopped and the sound isn't being updated. If they were cut off in the graph, you'd get a proper sine wave like in the first graph, but long-lasting stops cause the wave to become deformed.

This guide aims to shorten the times the Z80 is stopped. Unfortunately, there is no way to prevent the Z80 from being stopped, as you will need to stop it in order to allow the M68K to access the YM2612. This is why achieving a good playback quality of digital samples on a SEGA Genesis is a difficult task, that requires a lot of work.
But here I have done everything for you, the only thing you need to do is follow my instructions below:

We need to optimize these two mentioned factors the best way possible:
  • SMPS
  • DMA-transfers

Let's start!

2. Optimizing Z80 stops in SMPS

Sonic 1 prefers to stop the Z80 as soon as SMPS starts and hold it stopped until the very end. This is understandable, since the sound engine may need access to the YM2612 or Z80 memory (to control Mega PCM) at anytime. However, this doesn't happen too often - most of the time SMPS is just updating its internal events and timers, as reading song files. Running their scripts takes considerably longer.
So it tuns out that the Z80 is being stopped most of the time for no reason: access to the YM2612 occurs very rarely.

If you stop Z80 at the very moment when certain SMPS routines need an access to YM or Z80 memory (but not for the whole time SMPS is running), you can get decent optimization. That's what this part of the guide is about.

At first, you need to add some new macros into your disassembly. They noticeably simplify the process of changing the code, as they help to get rid of long parts of repeating code.

; =============================================================
stopZ80        macro
        move.w    #$100,($A11100).l
        nop
        nop
        nop

@wait\@:    btst    #0,($A11100).l
        bne.s    @wait\@
        endm

; =============================================================

startZ80    macro
        move.w    #0,($A11100).l    ; start the Z80
        endm

; =============================================================

waitYM        macro
@wait\@:    move.b    ($A04000).l,d2
        btst    #7,d2
        bne.s    @wait\@
        endm



Add these at the beginning of Sonic1.asm or where you like to keep your macros.
Now, here we go!

Go to label "sub_71B4C". At the very beginning, you will see the following code:

        move.w    #$100,($A11100).l    ; stop the Z80
        nop
        nop
        nop



This is the code to stop Z80. Thus, SMPS stops it at the beginning of its main routine execution and starts it at the end.
You won't need this code anymore, so delete or comment it out.

Now, go to label "loc_71C44":

loc_71C44:
        move.b    ($A04000).l,d2        ;++
        btst    #7,d2            ;++
        bne.s    loc_71C44        ;++
        move.b    #$2A,($A04000).l    ;++
        move.w    #0,($A11100).l        ; start the Z80
        rts



Assuming you have installed Mega PCM already, this code will look as shown above. At the end there is a command to start Z80. The lines marked with (++) are the extra lines of code used for Mega PCM. It pulls a little trick required for Mega PCM (the description of the trick you may find in the first post). We'll need this one, but not here.

Delete the whole code, except for the label name and an rts.

From now on, SMPS no longer stops Z80 during its execution. But there are few places, where it's required to stop Z80.

The first place is where SMPS sends Mega PCM a number of the sample to play. As I said, when M68K accesses Z80 memory, the Z80 itself must be stopped.

Go to label "loc_71C88" and find the following line in the code:

        move.b    d0,($A01FFF).l


We need the Z80 to be stopped before this command executes and to be started directly afterwards. Macros will help us to do so easily. Just replace it with:

        stopZ80
        move.b    d0,($A01FFF).l
        startZ80


Another place is where SMPS commands Mege PCM to pause, unpause and stop playback.

Go to the label "loc_71E7C" and find this line:

        move.b    #$7F,($A01FFF).l; pause DAC


Append this command in the same way, so it will look like this:

        stopZ80
        move.b    #$7F,($A01FFF).l; pause DAC
        startZ80


Now, find the label "loc_71EFE". Right above it, you'll see:

        move.b    #0,($A01FFF).l    ; unpause DAC


Again, append this command as shown above.

And finally, go find label "loc_725B6" and do this line:

        move.b    #$80,($A01FFF).l ; stop DAC playback


The last thing left to do regarding SMPS, are the routines that access the YM2612.
This time, the code replacement will be a little larger, plus we're going to add that extra code for Mega PCM, we took out in the beginning.

Find the routine "sub_7272E" and replace the whole code with this:

sub_7272E:                ; XREF: loc_71E6A
        stopZ80
        waitYM
        move.b    d0,($A04000).l
        waitYM
        move.b    d1,($A04001).l
        waitYM
        move.b    #$2A,($A04000).l
        startZ80
        rts
; End of function sub_7272E



Then, go to "sub_72764" and replace it with:

sub_72764:                ; XREF: loc_71E6A; Sound_ChkValue; sub_7256A; sub_72764
        stopZ80
        waitYM
        move.b    d0,($A04002).l
        waitYM
        move.b    d1,($A04003).l
        waitYM
        move.b    #$2A,($A04000).l
        startZ80
        rts
; End of function sub_72764



If you've followed the above correctly, then congratulations! You've just optimized SMPS.
Make sure you've done everything right - build the ROM and test it in emulator. The sound and the DAC samples should play as normal.

If you have problems, you can always check youself by comparing your edits to a clean disassembly with this guide applied. You can find it below, see Attachments section at the end.


3. Fixing SEGA PCM playback

After playing the previous part, Puto's custom SEGA PCM playback code won't work properly, because it expects that Z80 is stopped by the time the code is executed, but it's no longer stopped by that point.

To fix this, change the code at Sound_E1 as follows:

; ===========================================================================
; ---------------------------------------------------------------------------
; Play "Say-gaa" PCM sound
; ---------------------------------------------------------------------------

Sound_E1:
	stopZ80
		lea	(SegaPCM).l,a2			; Load the SEGA PCM sample into a2. It's important that we use a2 since a0 and a1 are going to be used up ahead when reading the joypad ports
		move.l	#(SegaPCM_End-SegaPCM),d3			; Load the size of the SEGA PCM sample into d3
		move.b	#$2A,($A04000).l		; $A04000 = $2A -> Write to DAC channel
PlayPCM_Loop:
		move.b	(a2)+,($A04001).l		; Write the PCM data (contained in a2) to $A04001 (YM2612 register D0)
		move.w	#$14,d0				; Write the pitch ($14 in this case) to d0 
		dbf	d0,*				; Decrement d0; jump to itself if not 0. (for pitch control, avoids playing the sample too fast)  
		sub.l	#1,d3				; Subtract 1 from the PCM sample size 
		beq.s	return_PlayPCM			; If d3 = 0, we finished playing the PCM sample, so stop playing, leave this loop, and unfreeze the 68K
		lea	($FFFFF604).w,a0		; address where JoyPad states are written
		lea	($A10003).l,a1			; address where JoyPad states are read from
		jsr	(Joypad_Read).w			; Read only the first joypad port. It's important that we do NOT do the two ports, we don't have the cycles for that
		btst	#7,($FFFFF604).w		; Check for Start button 
		bne.s	return_PlayPCM			; If start is pressed, stop playing, leave this loop, and unfreeze the 68K 
		bra.s	PlayPCM_Loop			; Otherwise, continue playing PCM sample 
return_PlayPCM:
	startZ80
		addq.w	#4,sp
		rts




4. Optimizing VBlank routines

Sonic 1 always tends to stop Z80 on DMA-transfers to VRAM or CRAM. But in fact, stopping processor isn't necessary in this case.

When DMA-transfer executes, VDP freezes M68K, requests its bus and starts data transfer from any location (in RAM or ROM) to videomemory at high speeds. But the Z80 isn't affected by this as it can function normally. It is only when the Z80 wants to access 68K memory during this time (for example, if it's reading the ROM), it will freeze as well, waiting for 68K to respond. The 68K will only respond when DMA-trasfer is over and the processor continues working.

However, even taking the case described above into account, forcing Z80 to stop doesn't make sense - it will stop itself when it's required. Moreover, the stop itself takes a while to execute, which means wasting processor cycles from both the Z80 and M68K side. But most importantly, emulators don't emulate Z80 stops during DMA. So, having excluded the forced stops that Sonic 1 performs, you'll get a huge optimization. On real hardware, you won't have optimization this big, however, you'll save some execution time.

So, we are going to work with VBlank code. It starts from "loc_B10". Its code is quite big and includes number of routines.

Find the label "loc_BC8", and you'll see this:

        move.w    #$100,($A11100).l

loc_BC8:
        btst    #0,($A11100).l
        bne.s    loc_BC8



Do you recognize the Z80 stop code here? We've seen one quite a lot already.
Completely delete this code (including the label name and one command above it)

Now, go to "loc_C22". Find and delete this line:

        move.w    #0,($A11100).l


This command started Z80 after its being stopped.

Go to "loc_C76". You'll see the Z80 stop code again:

        move.w    #$100,($A11100).l ; stop the Z80

loc_C76:
        btst    #0,($A11100).l    ; has Z80 stopped?
        bne.s    loc_C76        ; if not, branch



Delete it.

Then, find "loc_D50" (it's few lines below). You'll see Z80 start command, after the stop in loc_C76.

        move.w    #0,($A11100).l


Delete this.

Now, you know the deal. Find and delete the similar code in the following places:

loc_DAE
loc_E64 (move.w #0,($A11100).l is few lines above)
loc_E7A
loc_F54
loc_FAE
loc_1060 (few lines above)
loc_1076
loc_10D4 (at the end, just before an rts)

That's it!
This was a hard and continuous guide, and if you successfully finished it, you deserve good praise (and a cookie). From now on, you can play digital samples and songs in near-perfect quality.

5. Attachment

A clean disassembly with Mega PCM installed and this guide applied:
https://www.dropbox....aPCM_HQ.7z?dl=0

This one also contains a bonus: on the title screen, there plays a high-quality digital song from Sonic 1 Megahack: Ultra Edition!

Enjoy!
This post has been edited by vladikcomper: 30 April 2017 - 02:27 PM

#21 User is offline GT Koopa 

Posted 17 December 2012 - 09:22 PM

  • Posts: 1990
  • Joined: 23-February 09
  • Gender:Male
  • Location:Elgin, IL
  • Project:Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
  • Wiki edits:6

View PostHitaxas, on 11 June 2012 - 05:31 PM, said:

This custom driver setup is awesome! I tested it out on a fresh Sonic 1 hack, messed around with adding voices to Sonic. Impressive. I might consider switching to this driver, currently I use the S1HL driver with tons of samples added.


Edit: I failed at reading the opening paragraph. This is a custom driver, not a modification of the original.

Edit2: I did find an issue with this driver. The first act of a level, everything works fine, music and voices. However, the dac turns to static when the next act loads.


Ok, +1 confirm for this problem. Tried to combine it with Markey's Sonic 128 disassembly. Double checked everything. Here is my specific report, via level selecting to Green Hill Zone act 3:

---

- The "static" itself lasts as long as the dac drum sample itself, a corruption of the original sound byte.
- Invincibility music doesn't affect it.
-dying doesn't affect it normally.
-hitting a 1up monitor with its jingle causes the dac drums to static.
- When getting to the boss arena and the boss music, the dac drums play normal, HOWEVER anything after will have the corrupt dac, including dying.
-and of course, going to a new act or the special stage causes the static problem
-once activated, none of the above matters, it is always "on"
-the only way it gets "fixed" is by getting a game over and going back to the SEGA screen.


---

It has to be the way new music is being called up that is causing it.

#22 User is offline vladikcomper 

Posted 18 December 2012 - 10:34 AM

  • Posts: 182
  • Joined: 13-June 09
  • Gender:Male
  • Location:Russia
  • Project:Sonic Warped
  • Wiki edits:1
I had a quick go on implementing Mega PCM in Sonic 1: Project 28, and it all worked out perfectly, like in the other disassemblies. I didn't have enough time and will to also apply a HQ playback guide yet, but the fact the main one worked means all the rest will do. Here's disassembly for the reference:
https://www.dropbox....MegaPCM.7z?dl=0

I tested it in Kega, Gens and Regen, tried to locate samples at different offsets in ROM, both ran GHZ 3 from Level Select and got to it through the normal game play -- I couldn't reproduce the weird bug you're talking about. I even have no idea how a thing like this could happen, because the Mega PCM code is quite steady for this sort of things: it ensures offsets are correct before reading data and there is no way you could corrupt Z80 RAM or Mega PCM's variables by playing a broken sample.

Could you PM me that buggy ROM? I'm quite interested to see what could wrong here.
This post has been edited by vladikcomper: 30 April 2017 - 02:28 PM

#23 User is offline GT Koopa 

Posted 18 December 2012 - 11:35 AM

  • Posts: 1990
  • Joined: 23-February 09
  • Gender:Male
  • Location:Elgin, IL
  • Project:Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
  • Wiki edits:6
PMed it to you. To have more to talk about in my current post, is the above disassembly clean, without a jump dash and other unwanted changes? Just Markey's disassembly with your sound driver attached?
This post has been edited by GT Koopa: 18 December 2012 - 11:35 AM

#24 User is offline vladikcomper 

Posted 19 December 2012 - 02:46 PM

  • Posts: 182
  • Joined: 13-June 09
  • Gender:Male
  • Location:Russia
  • Project:Sonic Warped
  • Wiki edits:1
So, I figured out GT Koopa's problem. Since two or more people had it, I think this should be highlighted.

The bug described above occurs when you forgot to follow this part of guide in the first post:

Quote

goto 'loc_71C88' label, find and delete these lines:

btst #3,d0
bne.s loc_71CAC

This removes hardcoded Timpani tempo modifier for old driver. Certain sample numbers ($88-$8B) were hardcoded to play sample $83 (timpani) with different tempos. New driver doesn't need it, as you can set this stuff in the DAC table.


Basically, the old driver was hardcoded to play sample $83 with different pitches for samples ($88-$8B), in order to do this, loc_71CAC routine modified drivers code in Z80 RAM. This fix essentially was for the old driver's code as you see, for Mega PCM, it just breaks its code in a random place.

So, by playing samples $88-$8B, the unwanted fix works and the Mega PCM code gets corrupted, which causes playback bugs.

Quote

To have more to talk about in my current post, is the above disassembly clean, without a jump dash and other unwanted changes? Just Markey's disassembly with your sound driver attached?

Yes, it's totally clean. In fact, the disassembly I posted earlier was a modified one used in S1 Hacking Studio 2, hence Jump Dash, Spin Dash and a lot of other changes. The program isn't released here yet.
This post has been edited by vladikcomper: 19 December 2012 - 02:46 PM

#25 User is offline GT Koopa 

Posted 20 December 2012 - 06:46 PM

  • Posts: 1990
  • Joined: 23-February 09
  • Gender:Male
  • Location:Elgin, IL
  • Project:Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
  • Wiki edits:6
Perhaps those mini steps could have numbers/letters/chronological markers so people don't miss their place?

Edit: I say this because while following I switched back and forth through windows, and I think that was where my error was.
This post has been edited by GT Koopa: 20 December 2012 - 06:48 PM

#26 User is offline vladikcomper 

Posted 03 March 2013 - 07:15 AM

  • Posts: 182
  • Joined: 13-June 09
  • Gender:Male
  • Location:Russia
  • Project:Sonic Warped
  • Wiki edits:1
Bump.

SSRG user 'Mike B Berry' reported me he had issues with SEGA PCM playback using Puto's custom code, which most of hacks actually use (http://info.sonicret..._the_SEGA_Sound). It turned out that the problem occurred if you apply Mega PCM HQ playback guide, the SEGA PCM wasn't played in various emulators and on real hardware. Apparently, it was working in Kega, which is why I missed that. Although I did run tests in different emulators, even on hardware, my test ROM had a debug screen replacing SEGA logo, so just I couldn't see the problem.

The fix is simple. I've added it into the guide already.

Quote

3. Fixing SEGA PCM playback

After playing the previous part, Puto's custom SEGA PCM playback code won't work properly, because it expects that Z80 is stopped by the time the code is executed, but it's no longer stopped by that point.

To fix this, change the code at Sound_E1 as follows:

; ===========================================================================
; ---------------------------------------------------------------------------
; Play "Say-gaa" PCM sound
; ---------------------------------------------------------------------------

Sound_E1:
	stopZ80
		lea	(SegaPCM).l,a2			; Load the SEGA PCM sample into a2. It's important that we use a2 since a0 and a1 are going to be used up ahead when reading the joypad ports
		move.l	#(SegaPCM_End-SegaPCM),d3			; Load the size of the SEGA PCM sample into d3
		move.b	#$2A,($A04000).l		; $A04000 = $2A -> Write to DAC channel
PlayPCM_Loop:
		move.b	(a2)+,($A04001).l		; Write the PCM data (contained in a2) to $A04001 (YM2612 register D0)
		move.w	#$14,d0				; Write the pitch ($14 in this case) to d0 
		dbf	d0,*				; Decrement d0; jump to itself if not 0. (for pitch control, avoids playing the sample too fast)  
		sub.l	#1,d3				; Subtract 1 from the PCM sample size 
		beq.s	return_PlayPCM			; If d3 = 0, we finished playing the PCM sample, so stop playing, leave this loop, and unfreeze the 68K
		lea	($FFFFF604).w,a0		; address where JoyPad states are written
		lea	($A10003).l,a1			; address where JoyPad states are read from
		jsr	(Joypad_Read).w			; Read only the first joypad port. It's important that we do NOT do the two ports, we don't have the cycles for that
		btst	#7,($FFFFF604).w		; Check for Start button 
		bne.s	return_PlayPCM			; If start is pressed, stop playing, leave this loop, and unfreeze the 68K 
		bra.s	PlayPCM_Loop			; Otherwise, continue playing PCM sample 
return_PlayPCM:
	startZ80
		addq.w	#4,sp
		rts



Don't apply this if you didn't use this guide: http://forums.sonicr...ndpost&p=715140
This post has been edited by vladikcomper: 03 March 2013 - 07:22 AM

#27 User is offline PsychoSk8r 

Posted 07 March 2013 - 02:36 PM

  • HighKnights
  • Posts: 2580
  • Joined: 11-July 07
  • Gender:Male
  • Location:Walsall, UK
  • Project:30 Day Project: Revisited.A New Release!
  • Wiki edits:19
I know with enough work anything is portable, but how much work do you think it'd be if I were to attempt whacking this in Sonic 2?

#28 User is offline vladikcomper 

Posted 11 March 2013 - 10:39 AM

  • Posts: 182
  • Joined: 13-June 09
  • Gender:Male
  • Location:Russia
  • Project:Sonic Warped
  • Wiki edits:1
Getting it work in Sonic 2 will require a lot of work, because it uses SMPS Z80 driver.

The fact is, with sound engine working on the M68K side (SMPS 68k), the Z80 is completely free to process digital sound samples in a continuous loop, which means, you can utilize all the processor's resources as you like, there's nothing besides you and your code. In case of SMPS Z80, the whole sound engine is also running on the Z80 along with the DAC driver. They have to share the same memory space, which is limited to 8 KB in Z80, and, of course, the execution time. Furthermore, hardware limitations make things even harder. The Z80 can only view the game ROM through a small 32 KB window, and with sound engine in the works, it often comes that the sound engine needs to access one part of ROM to read music data, at the same time the DAC driver needs another to read samples data. They have to share bank window as well, which, of course, needs some more resources and performance.

I'm not trying to say this is something impossible. A lot of sound engines on the Z80 could also playback DAC with no issues. But implementing a new and quite a complex DAC driver into Sonic 2 may require a lot of work.

I have plans to attempt an SMPS Z80 port of it, not sure if this happens any soon. I'm not too familiar with SMPS Z80, as my experience with it was little. The last time I had some issues on implementing another bank switching mechanism into it (not for Mega PCM, just to have multiple banks for music and SFX). But why not try it at least, this is gonna be challenging :)

#29 User is offline PsychoSk8r 

Posted 11 March 2013 - 11:45 AM

  • HighKnights
  • Posts: 2580
  • Joined: 11-July 07
  • Gender:Male
  • Location:Walsall, UK
  • Project:30 Day Project: Revisited.A New Release!
  • Wiki edits:19
Exactly what I wanted to know, thanks. =P

#30 User is offline Thorn 

Posted 11 March 2013 - 01:57 PM

  • Posts: 326
  • Joined: 26-February 07
  • Gender:Male
  • Location:Home
  • Project:Sonic 2 Retro Remix
  • Wiki edits:33
vladikcomper: let me ask the obvious question, then... wouldn't it be practical to set up your driver starting from the Sonic 2 "clone" sound driver (a public, on-the-wiki port of the Sonic 1 sound driver to Sonic 2)? Granted, it's not 100% identical, but it does move things back to SMPS 68k. You've probably already thought of that and it's just not obvious in your answer, but I figured I should ask directly. I've considered looking into it myself, but :effort:.

  • 4 Pages +
  • 1
  • 2
  • 3
  • 4
    Locked
    Locked Forum

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users