Image Map Image Map
Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 26

Thread: Creative Music System (CMS) / Game Blaster compatible replica

  1. #11
    Join Date
    Jul 2010
    Location
    Silicon Forest, Oregon, USA
    Posts
    718

    Default

    BTW, wouldn't it be simpler to hack a game and remove the detection code (and set it to a default value of 0x220, or use an environment variable)? It seems that the described detection method only works with the Game Blaster, but not with SB 1.5 / SB 2.0. So hacking the game will make it usable on these cards as well.

  2. #12
    Join Date
    Dec 2012
    Location
    Russia, Moscow
    Posts
    113

    Default

    Today i get some time to build CMS replica... I used mostly Sergey's circuit for auto-detect part except 10k pull-ups. If i read any empty port i get 0xFF value, so i think motherboard have internal pull-ups for data lines. Soldered auto-detect part from Sergey's circuit:



    Did the test stand based on 386 CPU and install my device onto left ISA-slot:



    And run TESTCARD.EXE from CMS diskette. So, this software successfuly found CMS:



    Then i soldered two SAA1099 and 74HC74 for divide 14,3MHz by two. Audio outputs has not filtered, no amplifier. Just 1k pull-ups for all four output channel and then mixed by 10k resistive divider into left and right. Then output to headphones over 0,1mF:



    It's worked! noisy, but work! I think needs to be done with the use of filter capacitors.

    I recorded sound from this card:


  3. #13
    Join Date
    Mar 2006
    Location
    Massachusetts, USA
    Posts
    1,885

    Default

    Sounds very promising, and I would think that if it replicates DOSBox's CMS detection methods, then it would work with every game that requires the Game Blaster autodetection to work.
    All you Russians, first the Adlib, then the SSI-2001 and now the Game Blaster! Perhaps the Covox Sound Master will be next. Will no 8-bit sound card be kept exclusive and ludicrously expensive?
    Last edited by Great Hierophant; May 24th, 2015 at 09:26 AM.
    My Retro Computing and Vintage Gaming Blog : http://nerdlypleasures.blogspot.com/

  4. #14
    Join Date
    Aug 2006
    Location
    Chicagoland, Illinois, USA
    Posts
    6,056
    Blog Entries
    1

    Default

    Quote Originally Posted by Tronix View Post
    It's worked! noisy, but work!
    Fantastic work, Tronix! Warms my heart to see the SAA1099 get some love.
    Offering a bounty for:
    - The software "Overhead Express" (doesn't have to be original, can be a copy)
    - A working Sanyo MBC-775, Olivetti M24, or Logabax 1600
    - Music Construction Set, IBM Music Feature edition (has red sticker on front stating IBM Music Feature)

  5. #15
    Join Date
    Jul 2010
    Location
    Silicon Forest, Oregon, USA
    Posts
    718

    Default

    Nice work!

    Audio quality: Adlib and SoundBlaster use active filters. Also the audio part is separated from digital, shielded (at least has a solid ground plane).

    Not sure if reading an unused I/O address will always give 0xFF. Older computers (e.g. PC/XT) normally don't have pull-ups on data bus. And 0xFF might be a side effect of TTL inputs reading '1' when connected to Hi-Z state outputs. So I recommend put these pull-up resistors.

    It is interesting to see some soviet/Russian chips on your board.
    BTW, K155TM2 is an old plain TTL 7474; K555 series are 74LS analogs; K1533 are 74ALS.

  6. #16
    Join Date
    Dec 2012
    Location
    Russia, Moscow
    Posts
    113

    Default

    Thank you all for your support!

    It is time to develop some software support... Adopting experience of Innovation SSI-2001 MIDI fun, I tried to do the same thing with CMS. I downloaded source code of Miles Sound System Version 2 (AIL2) from John Miles site and modify Tandy driver (SPKR.INC) to work with Creative Music System card. Only the default IO address (220h) is currently supported.

    I used mostly source code of Paku-Paku game by Jason M. Knight (sound library). Also very helpful this threads: Creative Music System (C/MS)??? for CMS_Programming_Information.zip and this Game Blaster / CMS / SB + CMS owners, please help test But it's not a simple "copy-paste". In Paku-paku CMS sound write procedure i found some mistakes or bugs. For example, overflow when "set frequensy" command calculating; bad logic in "set octave" command calculating; reading CMS port and then ORed with new value for channel enable, but CMS port are write only etc..

    So, beta-version of Miles CMS.ADV driver in attachment (with source code). I am tested it with perfect and simple MIDI and XMIDI player PX-Palyer in DosBox (set "sbtype=gb" in dosbox.conf file) because i not have the time to check on the real hardware. Sound quality so-so, but its worked. Driver not used noise generator functions and very simple at all.

    Right now CMS can support 150+ games, in theoretical
    Attached Files Attached Files
    Last edited by Tronix; May 28th, 2015 at 11:17 AM.

  7. #17

    Default

    If it helps any to tweak it in better, I've updated my CMS library so that it works with a wider range of devices -- some of the GAL's used in certain versions of the card don't entirely work the same, so these changes get rid of the last few CMS equipped SB's that either didn't make sound, or output nonsense.

    Code:
    ; Creative Music Source dual SA1099 Sound support
    ; Jason M. Knight, October 2014
    ; Intended for compilation with NASM
    
    ; labels starting with "i_" are for local/internal use only
    
    BITS 16
    CPU 8086
    
    %include "TURBOPAS.MAC"
    
    segment CONST
    
    ; CMS registers are read only, so we have to buffer these ourselves!
    cmsOctaveStore dw 0x0000, 0x0000, 0x0000
    cmsFreqBits    dw 0x0000
    cmsNoiseBits   dw 0x0000
    
    cmsFreqMap: ; convert 0..243 to 0..255 with SAA1099 freq curve
    	db    0,   2,   3,   5,   7,   9,  11,  13
    	db   15,  17,  19,  21,  24,  26,  28,  30
    	db   32,  33,  35,  37,  39,  40,  42,  45
    	db   47,  48,  50,  51,  53,  55,  57,  58
    	
    	db   60,  61,  63,  65,  66,  67,  68,  70
    	db   71,  73,  74,  76,  77,  79,  80,  82
    	db   83,  85,  86,  87,  88,  90,  91,  93
    	db   95,  96,  97,  98, 100, 101, 103, 104
    	
    	db  105, 106, 108, 109, 111, 112, 113, 114
    	db  115, 116, 118, 119, 120, 121, 123, 124
    	db  125, 126, 127, 129, 130, 131, 132, 133
    	db  134, 135, 136, 137, 138, 140, 141, 142
    	
    	db  143, 144, 145, 146, 148, 149, 150, 151
    	db  152, 153, 154, 155, 156, 157, 158, 159
    	db  160, 161, 162, 162, 163, 164, 165, 166
    	db  167, 168, 170, 171, 172, 173, 174, 174
    	
    	db  175, 176, 177, 178, 179, 180, 181, 182
    	db  182, 183, 184, 185, 186, 187, 188, 189
    	db  190, 191, 192, 193, 193, 194, 195, 196
    	db  196, 197, 198, 199, 200, 200, 201, 202
    	
    	db  203, 203, 204, 205, 206, 206, 208, 208
    	db  209, 209, 210, 211, 212, 212, 213, 213
    	db  214, 215, 216, 217, 217, 218, 218, 219
    	db  219, 220, 221, 222, 222, 223, 224, 225
    	
    	db  225, 226, 226, 227, 227, 228, 228, 229
    	db  230, 231, 232, 232, 233, 233, 234, 234
    	db  235, 235, 236, 236, 237, 238, 239, 239
    	db  240, 240, 241, 241, 242, 243, 243, 244
    	
    	db  244, 245, 245, 246, 246, 247, 247, 248
    	db  249, 250, 250, 251, 251, 252, 252, 253
    	db  253, 254, 254, 255
    	
    segment CODE
    
    ; let's do the math here instead of during execution
    %define cmsFreqMin 32
    %define cmsFreqMax 7823
    %define cmsFreqLo  245
    %define cmsFreqHi  489
    %define cmsFreqMapOffsetMinusLo cmsFreqMap - cmsFreqLo
    
    extern cmsSoundPort
    
    i_WriteByteBoth:
    ; INPUT
    ;   dx = soundport
    ;   al = register
    ;   ah = data
    ; PRESERVES
    ;   all
    	add   dx, 3
    	out   dx, al
    	dec   dx
    	xchg  ah, al
    	out   dx, al
    	dec   dx
    	xchg  ah, al
    	out   dx, al
    	dec   dx
    	xchg  ah, al
    	out   dx, al
    	xchg  ah, al
    	ret
    	
    i_WriteWordBoth:
    ; INPUT
    ;   dx = soundport
    ;   al = register
    ;   bx = data
    ; PRESERVES
    ;   all
    	add   dx, 3
    	out   dx, al ; oAL
    	dec   dx
    	xchg  bl, al ; BL = oAL, AL = oBL, BH = oBH
    	out   dx, al ; oBL
    	xchg  bh, al ; BL = oAL, AL = oBH, BH = oBL
    	out   dx, al ; oBH
    	dec   dx
    	xchg  bl, al ; BL = oBH, AL = oAL, BH = oBL
    	out   dx, al ; oAL
    	dec   dx
    	xchg  bh, al ; BL = oBH, AL = oBL, BH = oAL
    	out   dx, al ; oBL
    	xchg  bl, al ; BL = oBL, AL = oBH, BH = oAL
    	out   dx, al ; oBH
    	xchg  bh, al ; original order.
    	ret
    	
    i_CmsSelectPort:
    ; INPUT
    ;   [bp + 6] == voice 0..11
    ; OUTPUT
    ;   bx = cms register (0..5)
    ;   dx = port (0x02?1 or 0x02?3)
    	mov  bx, [bp + 6]
    	mov  dx, [cmsSoundPort]
    	inc  dx
    	cmp  bx, 6
    	js   .done
    	sub  bx, 6
    	inc  dx
    	inc  dx
    .done:
    	ret
    	
    i_CmsFindBits:
    ; INPUT
    ;   al = register to set
    ;   bx = voice register 0..5
    ;   dx = chip register port (typically 0x02?1 or 0x02?3)
    ; OUTPUT
    ;   al == bitmask
    ;   bx == address of appropriate cmsFreqBits byte
    ;   dx == chip data port (typically 0x02?0 or 0x2?2)
    ; CORRUPTS
    ;   cl
    	out  dx, al
    	dec  dx
    	mov  cl, bl
    	mov  al, 1
    	shl  al, cl
    	mov  bx, cmsFreqBits
    	test dx, 0x0002
    	jz   .done
    	inc  bx
    .done:
    	ret
    	
    i_CmsSetAL:
    ; INPUT
    ;   al = bit mask
    ;   bx = address of cmsBits byte
    ;   dx = chip data port
    	or   al, [bx]
    	mov  [bx], al
    	out  dx, al
    	ret
    	
    i_CmsMaskAL:
    ; INPUT
    ;   al = bit mask
    ;   bx = address of cmsBits byte
    ;   dx = chip data port
    ; CORRUPTS
    ;   al (masks off top two bits)
    	not  al
    	and  al, 0x3F
    	and  al, [bx]
    	mov  [bx], al
    	out  dx, al
    	ret
    	
    i_SetFreq:
    ; INPUT
    ;   ah = freq
    ;   bx = voice 0..5
    ;   dx = port 0x02?1 or 0x02?3
    ; OUTPUT
    ;   none
    ; CORRUPTS
    ;   al
    	mov   al, bl
    	or    al, 0x08
    	out   dx, al
    	dec   dx
    	mov   al, ah
    	out   dx, al
    	inc   dx
    	ret
    	
    i_SetOctave:
    ; INPUT
    ;   ch = octave
    ;   bx = voice 0..5
    ;   dx = port 0x02?1 or 0x2?3
    ; OUTPUT
    ;   none
    ; CORRUPTS
    ;   al, bx
    	mov   al, bl
    	shr   al, 1
    	or    al, 0x10
    	out   dx, al
    	dec   dx
    	shr   bx, 1
    	mov   al, [bx + cmsOctaveStore]
    	jc    .setHigh
    ; setLow
    	and   al, 0xF0
    	jmp  .done
    .setHigh:
    	and   al, 0x0F
    	mov   cl, 4
    	shl   ch, cl
    .done:
    	or    al, ch
    	out   dx, al
    	inc   dx
    	mov   [bx + cmsOctaveStore], al
    	ret
    	
    ; procedure cmsReset
    pProcNoArgs cmsReset
    	mov   ax, ds
    	mov   es, ax
    	xor   ax, ax
    	mov   di, cmsOctaveStore
    	stosw
    	stosw
    	stosw
    	stosw ; cmsFreqBits
    	stosw ; cmsNoiseBits
    	mov   dx, [cmsSoundPort]
    	mov   cx, 0x20
    .loopZero:
    	call  i_WriteByteBoth
    	inc   al
    	loop  .loopZero
    	mov   al, 0x1C
    	mov   bx, 0x0102
    	call  i_WriteWordBoth
    	mov   al, 0x15
    	call  i_WriteByteBoth
    	dec   ax
    	call  i_WriteByteBoth
    	inc   ax
    	inc   ax
    	call  i_WriteByteBoth
    	mov   cx, 6
    	mov   ax, 0x8800
    .loopVolume:
    	call  i_WriteByteBoth
    	inc   al
    	loop  .loopVolume
    	retf
    	
    ; proceudre cmsSetAmplitude(left, right, voice:word);
    pProcArgs cmsSetAmplitude
    	call i_CmsSelectPort
    	mov  al, bl
    	out  dx, al
    	mov  al, [bp + 8]
    	mov  cl, 4
    	shr  al, cl
    	add  al, [bp + 10]
    	dec  dx
    	out  dx, al
    	pRet 6
    	
    ; procedure cmsEnableFreq(voice:word);
    pProcArgs cmsEnableFreq
    	call i_CmsSelectPort
    	mov  al, 0x14
    	call i_CmsFindBits
    	call i_CmsSetAL
    	pRet 2
    
    ; procedure cmsDisableFreq(voice:word);
    pProcArgs cmsDisableFreq
    	call i_CmsSelectPort
    	mov  al, 0x14
    	call i_CmsFindBits
    	call i_CmsMaskAL
    	pRet 2
    
    ; procedure cmsEnableNoise(voice:word);
    pProcArgs cmsEnableNoise
    	call i_CmsSelectPort
    	mov  al, 0x15
    	call i_CmsFindBits
    	call i_CmsSetAL
    	pRet 2
    	
    ; procedure cmsDisableNoise(voice:word);
    pProcArgs cmsDisableNoise
    	call i_CmsSelectPort
    	mov  al, 0x15
    	call i_CmsFindBits
    	call i_CmsMaskAL
    	pRet 2
    	
    ; procedure cmsSetFreq(freq, voice:word);
    pProcArgs cmsSetFreq
    	call  i_CmsSelectPort
    	mov   ah, [bp + 8]
    	call  i_SetFreq
    	pRet  4
    	
    ; procedure cmsSetOctave(octave, voice:word);
    pProcArgs cmsSetOctave
    	call i_CmsSelectPort
    	mov   ch, [bp + 8]
    	call  i_SetOctave
    	pRet  4
    
    ; function cmsSetHz(hz, voice:word);
    pProcArgs cmsSetHz
    	; first let's turn off this voice
    	call i_CmsSelectPort ; bx == register 0..5, dx == 0x2?1 or 0x2?3
    	mov   di, bx
    	mov   si, dx
    	mov   al, 0x14
    	call  i_CmsFindBits
    	call  i_CmsMaskAL
    	; determine freq and octave from hz
    	mov   bx, [bp + 8]
    	cmp   bx, cmsFreqMin
    	jl    .exit
    	cmp   bx, cmsFreqMax
    	jg    .exit
    	mov   ch, 3
    	; I HATE "WHILE" LOGIC!!!
    .loopDownOctave:
    	cmp   bx, cmsFreqLo
    	jg    .loopUpOctave
    	shl   bx, 1
    	dec   ch
    	jmp   .loopDownOctave
    .loopUpOctave:
    	cmp   bx, cmsFreqHi
    	jl    .calcFreq
    	shr   bx, 1
    	inc   ch
    	jmp   .loopUpOctave
    .calcFreq:
    	mov   ah, [bx + cmsFreqMapOffsetMinusLo] 
    	; AH = freq, CH = OCTAVE
    	mov   bx, di
    	mov   dx, si
    	call  i_SetFreq
    	call  i_SetOctave
    	; turn this voice back on.
    	mov   bx, di
    	mov   al, 0x14
    	call  i_CmsFindBits
    	call  i_CmsSetAL
    .exit:
    	pRet  4
    Hope that helps. Mind you, it's only designed for three voice, so the octaveStore buffer would need to be enlarged.

    Basically I noticed all the same bugs you did and fixed them back in October.
    From time to time the accessibility of a website must be refreshed with the blood of owners and designers. It is its natural manure.
    CUTCODEDOWN.COM

  8. #18
    Join Date
    Mar 2006
    Location
    Massachusetts, USA
    Posts
    1,885

    Default

    I decided to probe my Game Blaster using port reads and writes via debug. I found that 0x224 reads either 3F or 7F depending on the system, and that 0x225 behaves identically to 0x224. Values written to 0x226 and 0x227 appear at 0x22A and 0x22B. Other addresses read usually as FF and writing to them does not appear to change anything elsewhere. The 3F value was seen in a Tandy 1000 TL, the 7F in a generic 486 PC.

    All the games requiring a Game Blaster and the Creative drivers/utilities work fine with a Game Blaster in my 1000 TL, so I guess it isn't that important.
    Last edited by Great Hierophant; May 28th, 2015 at 04:33 PM.
    My Retro Computing and Vintage Gaming Blog : http://nerdlypleasures.blogspot.com/

  9. #19
    Join Date
    Dec 2012
    Location
    Russia, Moscow
    Posts
    113

    Default

    Today i found KA2206N stereo amplifier (TEA2025 analog). I solder this chip to my board. I used reference circuit from KA2206 datasheet.



    Then i solder filter 0,01mF capacitors from Sam Coupe SAA1099 circuit:



    Sound still not clean, digital noise present. I think it's because of the tangle of wires. Originally under the chips have a large ground polygon. I leave everything as it is. Some new records from board:


  10. #20
    Join Date
    Dec 2012
    Location
    Russia, Moscow
    Posts
    113

    Default

    Playing Warcraft II with Miles-CMS driver on Creative Music System card: Video:


    Circuit: http://habrastorage.org/files/105/62...f554ddb193.png

    Circuit in DipTrace format in attachment.
    Attached Files Attached Files
    Last edited by Tronix; July 12th, 2015 at 08:48 PM.

Bookmarks

Posting Permissions

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