don't click here

SMPS68k RAM Area

Discussion in 'Engineering & Reverse Engineering' started by Oerg866, Jun 30, 2010.

Thread Status:
Not open for further replies.
  1. Dear Sonic Retro,

    Today I thought it was a good idea to release my findings about the RAM that SMPS occupies when being active. I am going to focus on Sonic 1 here, which means that this might be different for any other game using SMPS.

    So, here we go:

    SMPS RAM starts at (FF)F000.

    Lenght = either B (byte), W (word) or L (long)

    Sections:

    Code (Text):
    1. F030-F05F       PCM
    2. F060-F08F       FM1
    3. F090-F0BF       FM2
    4. F0C0-F0EF       FM3
    5. F0F0-F11F       FM4
    6. F120-F14F       FM5
    7. F150-F17F       FM6
    8. F180-F1AF       PSG1
    9. F1B0-F1DF       PSG2
    10. F1E0-F20F       PSG3/NOISE
    SMPS general values:

    Code (Text):
    1. ADDR. LENGTH  Description
    2. F001  B       Timer, counts from 0 up to tempo byte 2 all the time
    3. F002  B       Tempo byte 2 from song (See SCHG:Music_Hacking)
    4. F008  L       Pointer to where the FM instruments for this song are (in ROM)
    5.               (or voices, for you noobs =P)
    6. F028  B       Tempo byte 2 from song (See SCHG:Music_Hacking)
    7. F214  B       FOR SOME SONGS: Ticks/$F until loop is over

    CHANNEL SECTIONS:
    Code (Text):
    1. 0     L       $00000000
    2. 8     L       $00000000
    3. 10    B       Channel information byte
    4.                 Bit 1      if 1 then Channel is mute
    5.                            if 0 then channel is playing
    6.                            Note: for PCM, Bit 1 is always 0!
    7.                 Bit 7      if 1 then channel is used in song at all
    8.                            if 0 then channel is not used in song at all
    9. 11    B       Modifier...
    10.               Known: For PSG3, if $E0, then the channel is noise, else it is
    11.               a melodic PSG channel.
    12. 12    W       constant   xx 00 where xx is the first tempo byte of the song  
    13. 14    L       Data Position Pointer
    14.               = Channel's current position inside ROM
    15. 18    W       Channel modifier (From SMPS file; see SCHG:Music_Hacking)
    16. 1A    B       ?
    17. 1B    B       Current insturment (always 0 for PCM)
    18. 1C    B       Current position in PSG Volume envelope (0 for PCM and FM)
    19. 1D    B       ???? Always $30 for xm3smps/xm4smps created songs,
    20.               SEGA SMPS songs sometimes have $2C here ... Modifying this will
    21.               cause illegal instruction error !
    22. 1E    B       Ticks until next note is triggered
    23.               Note: This also applies for rests!
    24.               This also is present at completely unused channels, and counts
    25.               upwards in this case! If the song doesn't loop, then it also counts upwards
    26.               once the song has ended!
    27. 1F    B       Next note descriptor
    28.               If bit 4 is set, the next note is a rest (?)
    29. 20    B       If PCM is enabled, this is current PCM sample played (2nd byte= 0)
    30.       W       Current frequency (FM / PSG)
    31.               See Addition #1 below
    32. 22    W       Note-playing-but-channel-muted:
    33.               Byte 1: amount of ticks channel is silent
    34.               Byte 2: $04, if this is currently going on...
    35. 24    L       Quote from SCHG:
    36.               " Coordination Flag $F8yyyy
    37.                 Jump to position yyyy (keep previous position in memory for returning) "
    38.  
    39.               This longword is the return adress in ROM. $00000000 if unused at the moment
    40. 28    W       Effect:
    41.               Byte 1: Ticks until effect takes place
    42.                       ($00 if no effect in sight)
    43.               Byte 2: Type of effect? (I've only experienced modulation so far)
    44. 2A    L       Effect data
    45.               For modulation:
    46.               Byte 1: F9 if frequency gets higher, 07 if frequency gets lower
    47.               Byte 2: ?
    48.               Word after that: what gets added to frequency (7000 - FFFF = negative !)
    49. 2E    B       $00
    50. 2F    B       ?? (For PSG: If $E7, then channel is Noise)
    If you have any questions, please contact me

    Addition #1:
    A note in a SMPS song is a byte, starting from $81. Lets assume x is the note.
    the xth note inside a frequency table is then pulled and sent to RAM.

    Here's a reference for FM:

    Code (Text):
    1. 025e = (b-0)
    2.  
    3. 0284 = C-1  0A84 = C-2  1284 = C-3  1A84 = C-4  
    4. 02AB = C#1  0AAB = C#2  12AB = C#3  1AAB = C#4  
    5. 02D3 = C-1  0AD3 = C-2  12D3 = C-3  1AD3 = C-4  
    6. 02FE = D#1  0AFE = D#2  12FE = D#3  1AFE = D#4  
    7. 032D = E-1  0B2D = E-2  132D = E-3  1B2D = E-4  
    8. 035C = F-1  0B5C = F-2  135C = F-3  1B5C = F-4  
    9. 038F = F#1  0B8F = F#2  138F = F#3  1B8F = F#4  
    10. 03C5 = G-1  0BC5 = G-2  13C5 = G-3  1BC5 = G-4  
    11. 03FF = G#1  0BFF = G#2  13FF = G#3  1BFF = G#4  
    12. 043C = A-1  0C3C = A-2  143C = A-3  1C3C = A-4  
    13. 047C = A#1  0C7C = A#2  147C = A#3  1C7C = A#4  
    14. 0A5E = B-1  125E = B-2  1A5E = B-3  225E = B-4  
    15.  
    16. 2284 = C-5  2A84 = C-6  3284 = C-7  3A84 = C-8
    17. 22AB = C#5  2AAB = C#6  32AB = C#7  3AAB = C#8
    18. 22D3 = C-5  2AD3 = C-6  32D3 = C-7  3AD3 = C-8
    19. 22FE = D#5  2AFE = D#6  32FE = D#7  3AFE = D#8
    20. 232D = E-5  2B2D = E-6  332D = E-7  3B2D = E-8
    21. 235C = F-5  2B5C = F-6  335C = F-7  3B5C = F-8
    22. 238F = F#5  2B8F = F#6  338F = F#7  3B8F = F#8
    23. 23C5 = G-5  2BC5 = G-6  33C5 = G-7  3BC5 = G-8
    24. 23FF = G#5  2BFF = G#6  33FF = G#7  3BFF = G#8
    25. 243C = A-5  2C3C = A-6  343C = A-7  3C3C = A-8
    26. 247C = A#5  2C7C = A#6  347C = A#7  3C7C = A#8
    27. 2A5E = B-5  325E = B-6  3A5E = B-7
    The table gets pulled from a location in the Play Music routines of SMPS:

    Code (Text):
    1. word_72790:     dc.w $25E,  $284,  $2AB,  $2D3,  $2FE,  $32D,  $35C,  $38F, $3C5  
    2.                 dc.w $3FF,  $43C,  $47C,  $A5E,  $A84,  $AAB,  $AD3,  $AFE, $B2D  
    3.                 dc.w $B5C,  $B8F,  $BC5,  $BFF,  $C3C,  $C7C,  $125E, $1284      
    4.                 dc.w $12AB, $12D3, $12FE, $132D, $135C, $138F, $13C5, $13FF
    5.                 dc.w $143C, $147C, $1A5E, $1A84, $1AAB, $1AD3, $1AFE, $1B2D
    6.                 dc.w $1B5C, $1B8F, $1BC5, $1BFF, $1C3C, $1C7C, $225E, $2284
    7.                 dc.w $22AB, $22D3, $22FE, $232D, $235C, $238F, $23C5, $23FF
    8.                 dc.w $243C, $247C, $2A5E, $2A84, $2AAB, $2AD3, $2AFE, $2B2D
    9.                 dc.w $2B5C, $2B8F, $2BC5, $2BFF, $2C3C, $2C7C, $325E, $3284
    10.                 dc.w $32AB, $32D3, $32FE, $332D, $335C, $338F, $33C5, $33FF
    11.                 dc.w $343C, $347C, $3A5E, $3A84, $3AAB, $3AD3, $3AFE, $3B2D
    12.                 dc.w $3B5C, $3B8F, $3BC5, $3BFF, $3C3C, $3C7C
    for PSG the order is reverse; the lower the value, the higher the sound:

    Code (Text):
    1. word_729CE:     dc.w $356, $326, $2F9, $2CE, $2A5, $280, $25C, $23A, $21A
    2.                 dc.w $1FB, $1DF, $1C4, $1AB, $193, $17D, $167, $153, $140
    3.                 dc.w $12E, $11D, $10D, $FE, $EF, $E2, $D6, $C9, $BE, $B4
    4.                 dc.w $A9, $A0, $97, $8F, $87, $7F, $78, $71, $6B, $65    
    5.                 dc.w $5F, $5A, $55, $50, $4B, $47, $43, $40, $3C, $39    
    6.                 dc.w $36, $33, $30, $2D, $2B, $28, $26, $24, $22, $20    
    7.                 dc.w $1F, $1D, $1B, $1A, $18, $17, $16, $15, $13, $12    
    8.                 dc.w $11, 0
     
  2. Spanner

    Spanner

    The Tool Member
    Good notes. Maybe someone else who is talented enough could make their own Sound Test out of this information.
     
  3. Spanner

    Spanner

    The Tool Member
    I said someone else. I know that you made a sound test, along with a few others who have done the same.
     
  4. Okay. Sorry.
     
  5. nineko

    nineko

    I am the Holy Cat Tech Member
    6,309
    486
    63
    italy
    I know you know why, but I'll post it here nonetheless just in case someone else doesn't know.
    The PSG frequency is determined by 3579545Hz / 32 / those values above (0-1023), where 3579545Hz is the frequency of the Z80 in NTSC regions, it's 3546893Hz in PAL regions. This explains why the PSG frequencies aren't accurate at all, especially in the higher range. Maxim once suggested to try other reference values instead of A4=440Hz, but his research proven that it's impossible to get anything decent out of the PSGs.

    Nice work on this, though. To put it with SOTI's words:
     
  6. Hivebrain

    Hivebrain

    Administrator
    3,049
    161
    43
    53.4N, 1.5W
    Github
    Good stuff. I'll incorporate this into the disassembly.

    Are the values $20-$2F for PCM only? Because all the other sections are only $20 bytes each.
     
  7. No, the sections have 16 $00 bytes before that.

    EDIT: Oh, thats what you mean, I accidentally something wrong... Fixed, see 1st post again.
     
  8. Mairtrus

    Mairtrus

    Get a load of this!! Tech Member
    27
    0
    0
    Mendoza, Argentina
    Sonic Z. The Z DOESN'T means nothing.
    I toke the time to fully research the 68K SMPS like 2 years ago (but for lazyness I never published my discoveries), so I can say that some of your notes are a bit inaccurate. The real channels distribution is:
    <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>F040-F07F PCM
    F070-F09F FM1
    F0A0-F0CF FM2
    F0D0-F0FF FM3
    F100-F12F FM4
    F130-F15F FM5
    F160-F18F FM6
    F190-F1BF PSG1
    F1C0-F1EF PSG2
    F1F0-F21F PSG3/NOISE

    F220-F24F SFX FM3
    F250-F27F SFX FM4
    F280-F2AF SFX FM5
    F2B0-F2DF SFX PSG1
    F2E0-F30F SFX PSG2
    F310-F33F SFX PSG3
    F340-F36F SFX FM4 (only used by waterfall, I believe)
    F370-F39F SFX PSG (set each time a SFX uses the Noise channel)

    F3A0-F??? Mirror of the musica data (not sure about the SFX data) when the Extra Life music is being played.</div>

    And the structure of each channel is:
    <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>00 = bitfield (explained down) (byte)
    01 = channel identifier (6,0,1,2,4,5,6 for the DAC/FM1,2,3,4,5,6 respectively; 80,A0,C0,E0 for the PSG1,2,3,Noise respectively) (byte)
    02 = particular tempo modifier (byte)
    04 = current offset (long)
    08 = pitch (byte)
    09 = volumen (byte)
    0A = channel configuration (stereo/AMS/FMS) (byte)
    0B = instrument/voice (byte)
    0C = offset adder for the current PSG voice (byte)
    0D = return counter. determines in what adress INSIDE THE CHANNEL is the return offset used by the flag E3. 30 is at the end of channel (should NOT execute a return), 2E is 2 bytes before the end of the channel, etc (byte)
    0E = counter of the current note duration (byte)
    0F = current note duration (byte)
    10 = current frequency (word)
    12 = counter of the current note filler (byte)
    13 = current note filler (byte)
    14 = offset of parameters of the last used modulation (long)
    18 = wait time until the modulation starts (byte)
    19 = modulation speed (byte)
    1A = how much the frequency change per modulation step (signed byte)
    1B = maximun amplitude of modulation (byte)
    1C = the adder who modifies the current frequency to produce the modulation (word)
    1E = RAW LSB to be added at the frequency (flag E1) (byte)
    1F = Feedback/Algorithm of the current instrument (FM); kind of sound produce by the Noise channel (if PSG,flag F3) (byte)
    20 = particular offset of the instruments (only used by the SFX FM) (long)</div>
    And the bitfield in the header means this:
    <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>Bit 0: Reduntant/Without usage
    Bit 1: 0: There is a note. 1: There is a rest
    Bit 2: (For FM/PSG) 0: Nothing playing over this channel. 1: A high priority sound (a SFX) is over this channel.
    (For DAC): 0: Fade In/Out to the last music is inactive. 1: Fade In/Out to the last music is active (flag E4)
    Bit 3: 0: Modulation inactive. 1: Modulation active
    Bit 4: 0: The Key Off event ocurrs. 1: The Key Off event DOESN'T ocurrs (Key On during the whole note) (flag E7)
    Bit 5: Reduntant/Without usage
    Bit 6: Reduntant/Without usage
    Bit 7: 0: This channel is inactive. 1: This channel is active.</div>
     
  9. Hmmm. What is the last byte for then? For PSG3 I see that it is $E7 some times :S all the other times it is just $00 :/

    And thanks for the information, I will incorporate it into the 1st post later
     
  10. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,202
    432
    63
    Japan
    That E7 would be the code in accessing the 4th channel on the PSG chip.

    It's broken up into bits, 1RRR 0ABC

    1 & 0 = Are meant to remain that way for accessing this below
    RRR = what register/area to access, here's a list:

    000 = PSG 1 Frequency (Pitch/Note)
    001 = PSG 1 Attenuation (Volume)
    010 = PSG 2 Frequency (Pitch/Note)
    011 = PSG 2 Attenuation (Volume)
    100 = PSG 3 Frequency (Pitch/Note)
    101 = PSG 3 Attenuation (Volume)
    110 = PSG 4 Settings
    111 = PSG 4 Attenuation (Volume)

    ABC (For PSG 4 Settings only):

    A = Noise type (0 = Periodic/1 = White)
    BC = Shift Rate (00 = 512/01 = 1024/10 = 2048/11 = PSG 3's Frequency)

    E7 in bits is 1110 0111

    which means it's accessing PSG 4 Settings and setting White Noise type and using PSG 3's Frequency input.

    Fun fact: you can use all four channels at once so long as PSG 4's settings of BC are not set 11, though this means you probably won't get the right Frequency noise from the fourth channel that you want, of course everything above is only going by my own research so there may be things that are incorrect =P
     
  11. nineko

    nineko

    I am the Holy Cat Tech Member
    6,309
    486
    63
    italy
    Correct. The SN76489 is capable to output 3+1 channels at the same time, and some drivers (like Cube) support it. SMPS was arbitrarily limited to 3+0 or 2+1. This was done because if the 3 melodic channels are used at the same time, you can only pick 3 frequencies for the noise channel: low, medium, and high, the so-called SMS drums because of their typical usage in 8-bit games. By keeping one of the melodic channels mute, you get 1023 available frequencies for the noise channel, allowing for better hi-hats and so on. Puto once managed to modify the SMPS engine to allow for the 3+1 PSG channels to be used at the same time, it's not hard to do so. Just make sure you don't play a note on melodic PSG channel 2 and on the noise PSG channel at the same time, and you can still get the noise 1023 frequencies, switching back and forth between the 3+0 and the 2+1 modes.
     
  12. Hanoch

    Hanoch

    Also known as TheKnock, Birashot Member
    491
    0
    0
    Israel
    everything

    This means that its somewhat possible to make SMS ports to the megadrive. Did anybody try this yet?
     
  13. Nice to see that people are eager to complete the list. As soon as I get time, I will incorporate it into the first post.

    By the way, I might also, depends on how busy the day will be, add this to SCHG:Music_Hacking.

    Cheers.
     
  14. Fred

    Fred

    Taking a break Oldbie
    1,563
    117
    43
    Portugal
    Sonic 3 Unlocked
    Uhh the Mega Drive already has the SMS processor in it so

    Er, I mean, Cinossu already did it once.
     
  15. amphobius

    amphobius

    doing more important things with my life Member
    2,120
    0
    16
    life
    Last I checked, that's using the intended power of the Mega Drive, not the four PSG channels.
     
Thread Status:
Not open for further replies.