Quantcast

Page 1 of 26 1234511 ... LastLast
Results 1 to 15 of 377

Thread: Street Fighter 2 - new Z80 PCM sound driver project

  1. #1
    Outrunner Stef's Avatar
    Join Date
    Aug 2011
    Location
    France
    Posts
    603
    Rep Power
    25

    Default Street Fighter 2 - new Z80 PCM sound driver project

    Also posted in SpritesMind but i think it will interest some people here too :

    Hi folks,

    I guess everyone know this famous game and its reputation for having scratchy voices. One of my crazy future project i had in mind was to rewrite the Z80 PCM sound driver for this game to improve the voices rendering as the Megadrive is perfectly able of playing them well, it just requires good programming... something that Capcom never (wanted to) achieved on the Sega Megadrive hardware.

    So 2 days ago i finally decided to get a shoot in that project and i started by disassembling the Z80 driver. I don't know if it has already be made before but i did not found any informations about it...
    Anyway i was very surprised by the size of the driver, it's very simple and short (code size = 358 bytes).
    So for those who are curious here's the SF2 Z80 driver code. I commented, equated and modified it a bit (replaced some JR (PC+2) by 3 NOP) to make it more readable :

    Code:
    ; BC = bank register
    
    COUNTER     EQU     $1FF0           ; 16 bits counter
    COMM_CH0    EQU     $1FFE           ; FF = done, < 80 = SFX ID to play
    COMM_CH1    EQU     $1FFF           ; FF = done, < 80 = SFX ID to play
    
    FM_ACCESS   EQU     $1FFD           ; indicate that Z80 is accessing DAC register (00 = ok, 2A = DAC access)
    
    CH0_PRIO    EQU     $1FE0           ; channel 0 priority
    CH0_LEN     EQU     $1FE1           ; channel 0 length (2 bytes: LH)
    CH0_ADDR    EQU     $1FE3           ; channel 0 address (3 bytes: LMH)
    
    CH1_PRIO    EQU     $1FE8           ; channel 1 priority
    CH1_LEN     EQU     $1FE9           ; channel 1 length (2 bytes: LH)
    CH1_ADDR    EQU     $1FEB           ; channel 1 address (3 bytes: LMH)
    
                ORG     $0000
    
    init
                DI                      ; disable ints
                IM      $01             ; set int mode 1
                LD      SP, $1000       ; setup stack
    
                ld      A,0xff
                ld      (COMM_CH0),a        ; clear command ch 0
                ld      (COMM_CH1),a        ; clear command ch 1
    
                ld      hl,(0x1001)         ; load empty sample param
                ld      (CH0_ADDR),hl
                ld      (CH1_ADDR),hl
                ld      a,(0x1003)
                ld      (CH0_ADDR+2),a
                ld      (CH1_ADDR+2),a
                ld      bc,0x6000           ; init BC
    
    loop
                ld      hl,(COUNTER)
                inc     hl                  ; inc counter
                ld      (COUNTER),hl        ;                                       =38
    
    do_com0
                ld      a,(COMM_CH0)
                or      a                   ; read command channel 0
                jp      m,do_com1           ; if (a & 0x80) goto do_com1            =27
    
                ld      l,a                 ; A = SFX ID
                ld      h,0x00
                add     hl,hl
                add     hl,hl
                add     hl,hl
                ex      de,hl
                ld      ix,0x1000
                add     ix,de               ; IX = SFX DATA ADDR                    =+77
    
                ld      a,(CH0_PRIO)
                ld      e,a                 ; E = old prio
                ld      a,(ix+0)            ; A = new prio                          =+36
    
                cp      e                   ; if (new_prio > old_prio)
                jr      c,com0_done         ; {                                     =+11/16
    
                ld      (CH0_PRIO),a        ;   load prio
                ld      l,(ix+4)
                ld      h,(ix+5)
                ld      (CH0_LEN),hl        ;   load lenght
                ld      l,(ix+1)
                ld      h,(ix+2)
                ld      (CH0_ADDR),hl       ;   load address
                ld      a,(ix+3)
                ld      (CH0_ADDR+2),a      ; }                                     =+153
    
    com0_done
                ld      a,0xff
                ld      (COMM_CH0),a        ; command channel 0 done                =+20
    
    do_com1
                ld      a,(COMM_CH1)
                or      a                   ; read command channel 1
                jp      m,set_bank0         ; if (a & 0x80) goto set_bank0          =27
    
                ld      l,a                 ; A = SFX ID
                ld      h,0x00
                add     hl,hl
                add     hl,hl
                add     hl,hl
                ex      de,hl
                ld      ix,0x1000
                add     ix,de               ; IX = SFX DATA ADDR                    =+77
    
                ld      a,(CH1_PRIO)
                ld      e,a                 ; E = old prio
                ld      a,(ix+0)            ; A = new prio                          =+36
    
                cp      e                   ; if (new_prio > old_prio)
                jr      c,com1_done         ; {                                     =+11/16
    
                ld      (CH1_PRIO),a        ;   load prio
                ld      l,(ix+4)
                ld      h,(ix+5)
                ld      (CH1_LEN),hl        ;   load lenght
                ld      l,(ix+1)
                ld      h,(ix+2)
                ld      (CH1_ADDR),hl       ;   load address
                ld      a,(ix+3)
                ld      (CH1_ADDR+2),a      ; }                                     =+153
    
    com1_done
                ld      a,0xff
                ld      (COMM_CH1),a        ; command channel 1 done                =+20
    
    set_bank0
                ld      hl,(CH0_ADDR)       ; HL = sample 0 addr (ML)
                ld      a,h
                rlca
                ld      (bc),a              ; bank = addr bit 15                    =31
    
                ld      a,(CH0_ADDR+2)      ; A = sample 0 addr (H)
                ld      (bc),a              ; bank = addr bit 16
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a              ; bank = addr bit 23                    =97
    
    read0
                set     7,h                 ; HL = sample ch0 addr banked
                ld      a,(hl)
                ex      af,af'              ; A' = sample ch0                       =19
    
    set_bank1
                ld      hl,(CH1_ADDR)       ; HL = sample 1 addr (ML)
                ld      a,h
                rlca
                ld      (bc),a              ; bank = addr bit 15                    =31
    
                ld      a,(CH1_ADDR+2)      ; A = sample 1 addr (H)
                ld      (bc),a              ; bank = addr bit 16
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a
                rrca
                ld      (bc),a              ; bank = addr bit 23                    =97
    
    read1
                set     7,h                 ; HL = sample ch1 addr banked           =8
    
                ld      de,FM_ACCESS
                ld      a,0x2a
                ld      (de),a              ; indicate Z80 is accessing YM DAC register
                ld      (0x4000),a          ; prepare DAC write                     =37
    
    mix
                ex      af,af'              ; A = sample ch0 (7 bits)
                add     a,(hl)              ; A = mixed sample (8 bits)
                rra                         ; A = mixed sample (7 bits)
                ld      (0x4001),a          ; write sample to DAC                   =28
    
                xor     a
                ld      (de),a              ; Z80 release YM access                 =11
    
    update0
                ld      hl,(CH0_LEN)        ; HL = ch0.len
                ld      a,h
                or      l                   ; if (ch0.len == 0)
                jr      z,play_fixed0       ;   goto play_fixed0                    =31
    
                dec     hl
                ld      (CH0_LEN),hl        ; ch0.len--
                ld      a,h
                or      l                   ; if (ch0.len == 0)
                jr      z,play_done0        ;   goto play_done0                     =37
    
                ld      hl,CH0_ADDR
                inc     (hl)                ; ch0.addr.l++
                jr      nz,play_done0_1                                             =28
    
                ld      hl,(CH0_ADDR+1)
                inc     hl                  ; ch0.addr.mh++
                ld      (CH0_ADDR+1),hl
                jp      update1             ; goto update1                          =48
    
    play_fixed0
                ld      a,0x05
    play_f0_wait
                dec     a
                jr      nz,play_f0_wait                                             =+87+5
    
                nop                         ; waste some cycles
                jr      update1             ; goto update_ch1                       =+16
    
    play_done0
                xor     a
                ld      (CH0_PRIO),a        ; no more playing ch0
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                jr      update1             ; waste some cycles                     =+61+5
    
    play_done0_1
                ld      a,0x00
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop                         ; waste some cycles                     =+43+5
    
    update1
                ld      hl,(CH1_LEN)        ; HL = ch1.len
                ld      a,h
                or      l                   ; if (ch1.len == 0)
                jr      z,play_fixed1       ;   goto play_fixed1                    =31
    
                dec     hl
                ld      (CH1_LEN),hl        ; ch1.len--
                ld      a,h
                or      l                   ; if (ch1.len == 0)
                jr      z,play_done1        ;   goto play_done1                     =37
    
                ld      hl,CH1_ADDR
                inc     (hl)                ; ch1.addr.l++
                jr      nz,play_done0_1                                             =28
    
                ld      hl,(CH1_ADDR+1)
                inc     hl                  ; ch1.addr.mh++
                ld      (CH1_ADDR+1),hl
                jp      next                ; goto next                             =48
    ; note that in the original driver it was jumping to 'update1' instead
    ; that is probably a copy/paste bug and lead to some missed sample
    
    play_fixed1
                ld      a,0x05
    play_f1_wait
                dec     a
                jr      nz,play_f1_wait                                             =+87+5
    
                nop                         ; waste some cycles
                jr      next                ; goto next                             =+16
    
    play_done1
                xor     a
                ld      (CH1_PRIO),a        ; no more playing ch1
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                jr      next                ; waste some cycles                     =+61+5
    
    play_done1_1
                ld      a,0x00
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop                         ; waste some cycles                     =+43+5
    
    next
                jp loop                                                             =10
    
                                            ; total cycles per loop = 749 ~ 4.8 Khz
    
                BLOCK   $1000-$
    
    ; SFX DATA
    ; --------
    ; format : PP AA AA AA LL LL 00 00
    ; PP = priority
    ; AA = address (LMH)
    ; LL = length (LH)
    ;
    ; 001000    00 00 00 28 52 05 00 00         SFX 0
    ;           00 52 05 28 e7 0d 00 00         SFX 1
    ; 001010    00 39 13 28 b9 05 00 00         .....
    ;           00 f2 18 28 ca 05 00 00
    ; 001020    00 bc 1e 28 d1 06 00 00 00 8d 25 28 97 05 00 00
    ; 001030    00 24 2b 28 c8 05 00 00 00 ec 30 28 fe 06 00 00
    ; 001040    00 ea 37 28 70 01 00 00 00 5a 39 28 c7 03 00 00
    ; 001050    00 21 3d 28 95 04 00 00 00 b6 41 28 b6 03 00 00
    ; 001060    00 6c 45 28 85 05 00 00 00 f1 4a 28 08 0a 00 00
    ; 001070    00 f9 54 28 de 09 00 00 00 d7 5e 28 20 07 00 00
    ; 001080    00 f7 65 28 03 05 00 00 00 fa 6a 28 8b 06 00 00
    ; 001090    00 85 71 28 fd 0c 00 00 00 82 7e 28 82 04 00 00
    ; 0010a0    02 04 83 28 f5 02 00 00 02 f9 85 28 3b 04 00 00
    ; 0010b0    02 34 8a 28 50 07 00 00 02 84 91 28 6a 03 00 00
    ; 0010c0    02 ee 94 28 6d 04 00 00 02 5b 99 28 d6 06 00 00
    ; 0010d0    02 31 a0 28 d1 01 00 00 01 02 a2 28 30 03 00 00
    ; 0010e0    02 32 a5 28 d1 08 00 00 01 03 ae 28 37 02 00 00
    ; 0010f0    02 3a b0 28 45 05 00 00 02 7f b5 28 ca 07 00 00
    ; 001100    02 49 bd 28 bb 14 00 00 02 04 d2 28 67 0c 00 00
    ; 001110    02 6b de 28 69 15 00 00 02 d4 f3 28 b4 08 00 00
    ; 001120    02 88 fc 28 5a 14 00 00 02 e2 10 29 9b 13 00 00
    ; 001130    02 7d 24 29 09 10 00 00 03 86 34 29 7f 1b 00 00
    ; 001140    02 05 50 29 44 17 00 00 02 49 67 29 6e 02 00 00
    ; 001150    02 b7 69 29 e1 1a 00 00 03 98 84 29 63 17 00 00
    ; 001160    02 fb 9b 29 2e 05 00 00 03 29 a1 29 be 0b 00 00
    ; 001170    03 e7 ac 29 cd 14 00 00 02 b4 c1 29 e1 0b 00 00
    ; 001180    02 95 cd 29 5c 1b 00 00 02 f1 e8 29 49 12 00 00
    ; 001190    02 3a fb 29 7b 1b 00 00 02 b5 16 2a ec 03 00 00
    ; 0011a0    02 a1 1a 2a fd 06 00 00 03 9e 21 2a f7 26 00 00
    ; 0011b0    02 95 48 2a 98 23 00 00 01 2d 6c 2a 3b 1f 00 00
    ; 0011c0    02 68 8b 2a 4c 1a 00 00 02 b4 a5 2a 50 0e 00 00
    ; 0011d0    02 04 b4 2a 30 10 00 00 02 34 c4 2a 9d 10 00 00
    ; 0011e0    02 d1 d4 2a 43 05 00 00 02 14 da 2a 27 06 00 00
    ; 0011f0    02 3b e0 2a a0 09 00 00 02 db e9 2a c9 0a 00 00
    ; 001200    02 a4 f4 2a 46 0e 00 00 02 ea 02 2b 44 0b 00 00
    ; 001210    02 2e 0e 2b b9 0e 00 00 02 e7 1c 2b 57 0a 00 00
    ; 001220    02 3e 27 2b ae 10 00 00 02 ec 37 2b 89 09 00 00
    ; 001230    02 75 41 2b fa 0d 00 00 02 6f 4f 2b 2b 0f 00 00
    ; 001240    03 9a 5e 2b 82 0b 00 00 03 1c 6a 2b 42 07 00 00
    ; 001250    03 5e 71 2b a2 0b 00 00 03 00 7d 2b 15 0c 00 00
    ; 001260    02 15 89 2b e0 0c 00 00 02 f5 95 2b e2 09 00 00
    ; 001270    02 d7 9f 2b f1 0a 00 00 02 c8 aa 2b 67 0f 00 00
    ; 001280    02 2f ba 2b 92 0f 00 00 02 c1 c9 2b 43 13 00 00
    ; 001290    02 04 dd 2b 34 0f 00 00 02 38 ec 2b ef 14 00 00
    ; 0012a0    02 27 01 2c d5 21 00 00 02 fc 22 2c 1f 23 00 00
    ; 0012b0    ff 1b 46 2c 01 00 00 00 ff ff ff ff ff ff ff ff
    ; 0012c0    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ; ...
    ; 0013f0    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ;
    ; NOT USED
    ; 001400    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ; ...
    
    ; VARIABLES
    ; 001fe0    00 00 00 00 00 28 00 00 00 00 00 00 00 28 00 00
    ; 001ff0    53 30 00 00 00 00 00 00 00 00 00 00 00 00 ff ff
    I even fixed a bug in the driver ! Because of it the channel 2 can miss one sample from time to time, not very important but still it shows how developer was lazy about it. Also the code is definitely not optimized, of course it do not use buffering but even worse, it uses lazy and slow memory access for many thing and never take advantage of SP register.
    The loop is 749 cycles length (i do not count special case of new command) which mean the sample rate is about 4.8 Khz.
    That is really bad, one of the first driver i wrote (which was not using any buffering) was able to play 2 channels at 14 Khz.

    It took me about 3h to reverse engineer the driver, that was the easy part Now what i need to do is to mimic this driver but replacing it by something safe against DMA. I will use the same method i used in my bad apple demo. The idea is to buffer sample from ROM in Z80 ram during the active period and use them to read sample during DMA which should occurs in VBlank period. Problem is that SF2 is extending VBlank a bit and i don't know if DMA is effectly used before the VInt occurs. If that is the case i will have to "count" to find the correct period where i need to stop ROM accesses... Then i will need to patch some 68k code, i guess they disable Z80 during DMA which we should avoid for instance, same for IO access (but not as important).


    Edit : Last version of patched rom :
    https://dl.dropboxusercontent.com/u/...sf2_mod_v7.bin
    Last edited by Stef; 08-26-2014 at 08:44 PM.

  2. #2
    ding-doaw Raging in the Streets tomaitheous's Avatar
    Join Date
    Sep 2007
    Location
    Sonoran Desert
    Age
    41
    Posts
    3,981
    Rep Power
    74

    Default

    The sloppy code part doesn't surprise me. I've seen quite a bit of lazy, unoptimized, and down right poorly written code in lots of PCE games. And I mean, where the code counts (I can understand for non critical parts, but where it counts should be optimal). Konami has slow loading routine for Dracula X, at the start of each level, for no reason whatsoever (unnecessary multiple seek times). Air Zonk, and other PCE games, have unoptimized sample playback routines, etc.

    I'm interested in what you find out on the 68k and VDMA side. If the game breaks the vDMA into segments, and how much it does it process per frame, etc.

    Are the samples compressed or straight 8bit? The PCE version uses bitpacked samples (DAC writes are 5bit, two sample streams both bitpack), and adds quite a bit of overhead among the other stuff.

  3. #3
    Outrunner Stef's Avatar
    Join Date
    Aug 2011
    Location
    France
    Posts
    603
    Rep Power
    25

    Default

    I extracted the samples from the original ROM :
    https://www.dropbox.com/s/m0nudiaih1...f2_samples.wav

    Unfortunately the base samples are already pretty bad to start with, even without the DMA distortion they sound scratchy, i wonder if some simple filtering could improve them... ut maybe we can't do really better with 4.7 Khz
    Last edited by Stef; 07-19-2014 at 07:27 AM.

  4. #4
    ding-doaw Raging in the Streets tomaitheous's Avatar
    Join Date
    Sep 2007
    Location
    Sonoran Desert
    Age
    41
    Posts
    3,981
    Rep Power
    74

    Default

    Do you have enough space in the rom for improved samples?

  5. #5
    Outrunner Stef's Avatar
    Join Date
    Aug 2011
    Location
    France
    Posts
    603
    Rep Power
    25

    Default

    There is not many space left in the ROM, but i was thinking about using 4 bits ADPCM samples instead for instance and also maybe using better filtering on input samples.
    Of course we should start from the arcade version samples instead but i don't know if ADPCM is a great idea for so low rate sample, 9.54Khz in ADPCM will probably bring many distortion because of quality loss :-/ That is even more true that samples use the full 8 bits dynamic, looks like they did an heavy normalization on them.

  6. #6
    Outrunner Stef's Avatar
    Join Date
    Aug 2011
    Location
    France
    Posts
    603
    Rep Power
    25

    Default

    Quote Originally Posted by tomaitheous View Post
    The sloppy code part doesn't surprise me. I've seen quite a bit of lazy, unoptimized, and down right poorly written code in lots of PCE games. And I mean, where the code counts (I can understand for non critical parts, but where it counts should be optimal). Konami has slow loading routine for Dracula X, at the start of each level, for no reason whatsoever (unnecessary multiple seek times). Air Zonk, and other PCE games, have unoptimized sample playback routines, etc.

    I'm interested in what you find out on the 68k and VDMA side. If the game breaks the vDMA into segments, and how much it does it process per frame, etc.

    Are the samples compressed or straight 8bit? The PCE version uses bitpacked samples (DAC writes are 5bit, two sample streams both bitpack), and adds quite a bit of overhead among the other stuff.
    Yeah that is not the first time i saw lazy code but this time i believe it really hurts on final gaming experience so it's a shame they did not made more efforts on that point. I did not made any recent analyze about how DMA are done... A long time i had a look into that and saw that sometime they were transferring data on same vram location twice during a single frame but that does not make any sense, i probably made a wrong analysis, but who know. Also i remember they were spliting DMA but not that much, in 2 or 3 parts. I guess they do one for the first sprite tiles data, another one for second sprite tiles data and the third for the sprite table maybe.

    Samples are 8 bits unsigned, not packed. When you said they are packed on PCE, you mean that 2 samples does really eat 10 bit and not 16 bits ?

  7. #7
    I remain nonsequitur Shining Hero sheath's Avatar
    Join Date
    Jul 2010
    Location
    Texas
    Age
    40
    Posts
    13,313
    Rep Power
    128

    Default

    Didn't the Street Fighter Turbo (hack?) already have better sounding samples? I wonder what kind of driver it uses.
    "... If Sony reduced the price of the Playstation, Sega would have to follow suit in order to stay competitive, but Saturn's high manufacturing cost would then translate into huge losses for the company." p170 Revolutionaries at Sony.

    "We ... put Sega out of the hardware business ..." Peter Dille senior vice president of marketing at Sony Computer Entertainment

  8. #8
    Outrunner Stef's Avatar
    Join Date
    Aug 2011
    Location
    France
    Posts
    603
    Rep Power
    25

    Default

    The driver SF2 beta uses is only capable to play 1 PCM at once which definitely suck for this game... also i believe it does not sound *that* great. Maybe DMA are split to help, or just less data to transfer... but almost certain it does not buffer anything.

  9. #9
    Hard Road! ESWAT Veteran Barone's Avatar
    Join Date
    Aug 2010
    Location
    Brazil
    Posts
    7,043
    Rep Power
    151

    Default

    Quote Originally Posted by Stef View Post
    The driver SF2 beta uses is only capable to play 1 PCM at once which definitely suck for this game... also i believe it does not sound *that* great. Maybe DMA are split to help, or just less data to transfer... but almost certain it does not buffer anything.
    Yep, it kinda sucks too. I think it's a SMPS 68K variation, nothing really special.
    Besides the other Capcom fighters on the Mega Drive (Saturday Night Slam Master and SSF2), another fighting game which suffers from really scratchy samples is Art of Fighting. It uses the SMPS Z80 IIRC and it sounds REALLY bad.

    Stef, I really hope you can come up with a good audio driver replacement for SFII SCE; it would be really awesome and it would also answer a lot of questions about the PCM capabilities of the Mega Drive - since a lot of people think it completely sucks thanks to the SF games and there's even those who say that Capcom did a great job with that audio driver handling 2 PCM channels.

  10. #10
    I remain nonsequitur Shining Hero sheath's Avatar
    Join Date
    Jul 2010
    Location
    Texas
    Age
    40
    Posts
    13,313
    Rep Power
    128

    Default

    Quote Originally Posted by Stef View Post
    The driver SF2 beta uses is only capable to play 1 PCM at once which definitely suck for this game... also i believe it does not sound *that* great. Maybe DMA are split to help, or just less data to transfer... but almost certain it does not buffer anything.
    Gotcha. I always figured Super Street Fighter 2 sounded better in the voice samples just because there were fewer (none?) samples in the music. Also, does anybody know the owner of the Megadrive/Genesis Sound Engine List? It would be nice if we could get the "Capcom custom" engine updated to note that it is a Z80 driver.
    "... If Sony reduced the price of the Playstation, Sega would have to follow suit in order to stay competitive, but Saturn's high manufacturing cost would then translate into huge losses for the company." p170 Revolutionaries at Sony.

    "We ... put Sega out of the hardware business ..." Peter Dille senior vice president of marketing at Sony Computer Entertainment

  11. #11
    Hero of Algol TrekkiesUnite118's Avatar
    Join Date
    May 2010
    Age
    29
    Posts
    7,769
    Rep Power
    106

    Default

    I wonder if the raw samples are different on the Beta though. If they are it might be interesting to see if they might work better for raw samples in this hack.

    It would also be interesting to see if someone could redo some of the stage themes (or even just replace them with the ones from the beta), as some are just plain awful in SCE.

  12. #12
    Outrunner Stef's Avatar
    Join Date
    Aug 2011
    Location
    France
    Posts
    603
    Rep Power
    25

    Default

    I just built a rom to test the SF2 sample with the original sound driver and with/without DMA occuring (with different mode) :

    https://dl.dropboxusercontent.com/u/...f2/sf2_drv.bin

    The difference can be seen only on real hardware or highly accurate emulator as Exodus or BlastEm.
    As we can see the DMA does hurt a lot on playback quality (as expected)... splitting the DMA in 4 parts does improve a bit, but the difference is minor. Splitting it in 16 parts make things worst but i think it comes from my overhead in calling DMA method and the small sleep, and so some DMA occurs in active period (much slower).

    Here's the code for the different DMA mode :

    Code:
         switch(dma_mode & 3)
        {
            case 1:
                VDP_doVRamDMA(0, 32 * 128, (64 * 32) / (2 * 1));
                break;
    
            case 2:
                for(i = 0; i < 4; i++)
                {
                    VDP_doVRamDMA(0, 32 * 128, (64 * 32) / (2 * 4));
                    waitSubTick(10);
                }
                break;
    
            case 3:
                for(i = 0; i < 16; i++)
                {
                    VDP_doVRamDMA(0, 32 * 128, (64 * 32) / (2 * 16));
                    waitSubTick(0);
                }
                break;
        }
    You may wonder why the rom is so big, it is just that i aligned samples on 1MB address for easier modifications of the original driver.
    Last edited by Stef; 07-19-2014 at 05:00 PM.

  13. #13
    Outrunner Stef's Avatar
    Join Date
    Aug 2011
    Location
    France
    Posts
    603
    Rep Power
    25

    Default

    Quote Originally Posted by sheath View Post
    Gotcha. I always figured Super Street Fighter 2 sounded better in the voice samples just because there were fewer (none?) samples in the music. Also, does anybody know the owner of the Megadrive/Genesis Sound Engine List? It would be nice if we could get the "Capcom custom" engine updated to note that it is a Z80 driver.
    The fact that PCM are not used in music does not make any difference actually. In SF2 each sample has a priority so music sample can be "overridden" by voice sample... the thing is that they still mix 2 PCM channels. I think they avoided PCM in music just to not have altered music when you have voices SFX in battle.
    The voices improvements is probably more due to better scheduled DMA (and maybe less transfer more generally) and some work with the samples themself, as some pre filtering and avoiding too high frequencies which are more sensible.

  14. #14
    Outrunner Stef's Avatar
    Join Date
    Aug 2011
    Location
    France
    Posts
    603
    Rep Power
    25

    Default

    Quote Originally Posted by Barone View Post
    Yep, it kinda sucks too. I think it's a SMPS 68K variation, nothing really special.
    Besides the other Capcom fighters on the Mega Drive (Saturday Night Slam Master and SSF2), another fighting game which suffers from really scratchy samples is Art of Fighting. It uses the SMPS Z80 IIRC and it sounds REALLY bad.

    Stef, I really hope you can come up with a good audio driver replacement for SFII SCE; it would be really awesome and it would also answer a lot of questions about the PCM capabilities of the Mega Drive - since a lot of people think it completely sucks thanks to the SF games and there's even those who say that Capcom did a great job with that audio driver handling 2 PCM channels.
    Unfortunately a lot of genesis games suffers from scratchy samples :-/ Of course the system has its responsibilities in that but still developers could have make more efforts as it is definitely avoidable. It's true that SF2 really fucked up the reputation of the Sega Megadrive when it comes to play voices, that will definitely prove that good voices were possible, even better the ones we have in the SNES version (which are muffled, shortened and echoed as crazy)
    Thanks for the rep by the way
    Last edited by Stef; 07-19-2014 at 06:37 PM.

  15. #15
    Wildside Expert fluxcore's Avatar
    Join Date
    Aug 2013
    Posts
    226
    Rep Power
    6

    Default

    Very cool area of investigation!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •