How to detect sound chips without Bios

Page 4/4
1 | 2 | 3 |

By Grauw

Ascended (9181)

Grauw's picture

23-10-2019, 19:38

norakomi wrote:

I was hoping for an easy compatible driver....
Hands in my hair...
holy **** why is this so complicated....

Well, once you throw the BIOS out of the window you have to do everything yourself and things like using the stock MB1.4 driver gets more complicated. You could modify it to do the detection once before you kick out the BIOS?

Anyway I did some manual (untested) extraction of just the VGMPlay detection code in generic assembly;

Here’s Y8950 MSX-AUDIO.

MSXAudio_STATUS_PORT: equ 0C0H
MSXAudio_ADDRESS_PORT: equ 0C0H
MSXAudio_DATA_PORT: equ 0C1H

MSXAudio_ADPCM_CONTROL: equ 07H

; f <- c: found
MSXAudio_Detect:
    in a,(MSXAudio_STATUS_PORT)
    and 11111001B
    ret nz
    ld de,10000000B << 8 | MSXAudio_ADPCM_CONTROL
    call MSXAudio_Detect_WriteRegister
    in a,(MSXAudio_STATUS_PORT)
    and 11111001B
    push af
    ld de,00000000B << 8 | MSXAudio_ADPCM_CONTROL
    call MSXAudio_Detect_WriteRegister
    pop af
    xor 00000001B
    ret nz
    scf
    ret
MSXAudio_Detect_WriteRegister:
    ld a,e
    out (MSXAudio_ADDRESS_PORT),a
    ld b,8  ; wait 12 cycles
    djnz $
    ld a,d
    out (MSXAudio_DATA_PORT),a
    ld b,8  ; wait 12 cycles
    djnz $
    ret

And here’s YM2413 OPLL MSX-MUSIC.

It does need the BIOS RDSLT and WRSLT since it has to scan the slots and enable the FM-PAC…

RDSLT: equ 0CH
WRSLT: equ 14H
EXPTBL: equ 0FCC1H

MSXMusic_ID_ADDRESS: equ 4018H
MSXMusic_ENABLE_ADDRESS: equ 7FF6H

; f <- c: found
; a <- slot
; b <- 0: external, -1: internal
MSXMusic_Detect:
    ld hl,MSXMusic_MatchInternalID
    call Memory_SearchSlots
    ld b,-1
    ret c
    ld hl,MSXMusic_MatchExternalID
    call Memory_SearchSlots
    ld b,0
    ret

; a = slot id
; f <- c: found
MSXMusic_MatchInternalID:
    ld de,MSXMusic_internalId
    ld hl,MSXMusic_ID_ADDRESS
    ld bc,8
    jp Memory_MatchSlotString

; a = slot id
; f <- c: found
MSXMusic_MatchExternalID:
    ld de,MSXMusic_externalId
    ld hl,MSXMusic_ID_ADDRESS + 4
    ld bc,4
    call Memory_MatchSlotString
    ret nc
    push af
    ld hl,MSXMusic_ENABLE_ADDRESS
    call RDSLT
    ei
    set 0,a
    ld e,a
    pop af
    push af
    ld hl,MSXMusic_ENABLE_ADDRESS
    call WRSLT
    ei
    pop af
    ret

; Search all slots and subslots for a match.
; Invoke Continue to continue searching where a previous search left off.
; hl = detection routine (receives a = slot ID, can modify all)
; f <- c: found
; a <- slot number
; Modifies: af, bc, de
Memory_SearchSlots:
    ld a,0
Memory_SearchSlots_PrimaryLoop:
    ex de,hl
    ld hl,EXPTBL
    ld b,0
    ld c,a
    add hl,bc
    ld a,(hl)
    ex de,hl
    and 10000000B
    or c
Memory_SearchSlots_SecondaryLoop:
    push af
    push hl
    call Memory_SearchSlots_JumpHL
    pop hl
    jp c,Memory_SearchSlots_Found
    pop af
Memory_SearchSlots_Continue:
    add a,00000100B
    jp p,Memory_SearchSlots_NextPrimary
    bit 4,a
    jp z,Memory_SearchSlots_SecondaryLoop
Memory_SearchSlots_NextPrimary:
    inc a
    and 00000011B
    ret z  ; not found
    jp Memory_SearchSlots_PrimaryLoop
Memory_SearchSlots_Found:
    pop af
    scf
    ret
Memory_SearchSlots_JumpHL:
    jp hl

; a = slot
; bc = string length
; de = string
; hl = address
; f <- c: found
; Modifies: f, bc, de, hl
Memory_MatchSlotString:
    push af
    push bc
    push de
    call RDSLT
    ei
    pop de
    pop bc
    ex de,hl
    cpi
    jr nz,Memory_MatchSlotString_NotFound
    jp po,Memory_MatchSlotString_Found
    inc de
    ex de,hl
    pop af
    jp Memory_MatchSlotString
Memory_MatchSlotString_Found:
    pop af
    scf
    ret
Memory_MatchSlotString_NotFound:
    pop af
    and a
    ret

MSXMusic_internalId:
    db "APRLOPLL"

MSXMusic_externalId:
    db "OPLL"

By norakomi

Paragon (1086)

norakomi's picture

23-10-2019, 21:31

Quote:

You could modify it to do the detection once before you kick out the BIOS?

Well I wouldn't mind doing this whole story with Bios enabled. But the reason I was thinking of doing it with Bios disabled, is because I have no clue what is happening in the Bios, and I'm affraid that it will not work perfectly.
Also I don't know exactly WHEN to do it.
Right now when the Rom boots, I do a rominit, and somewhere in the middle I do
call SRCCHP ;check connected soundchips (this is a mess)
But I'm not sure if that's good, or the right place to do it.
I get issues like:
Philips NMS8245 + japanese FM PAC : fm pac in slot 2 works, in slot 1 doesn't.
and more....

Anyway... I feel like I am taking too much of your time.
I will just let this sink in for some days, then read all the text in this post over and over,
and then maybe see what the best thing is that I can do.

The fact is that I don't really understand the whole rominitialisation either (findrom, put page1 in ROM, force subslot regs into correct position, search all slots for RAM etc). I'm using that at boot, but it's code I don't understand.

So using code I don't understand to init the rom, and inside that more code I don't understand (to detect soundchips) which on top of that use the Bios, which I don't follow is just making things too complicated.

But thank you for all your help, I will take a few days to soak it up.

By Grauw

Ascended (9181)

Grauw's picture

23-10-2019, 21:56

Sounds like a good idea to let things sink in. Gaining understanding of code which you don’t fully understand (anymore) takes some time. I can imagine the feeling Wink, at work atm we’re porting a game that another company made. Often it requires quite some digging before finding the solution to the problem. And I’m regularly fixing things that we broke ourselves when we made changes earlier without understanding the full implications of it.

Feel absolutely free to ask more later though! For me if something takes too much time to answer I’ll just respond later or more briefly Wink, so don’t worry about it. And there’s always others willing to help.

By sd_snatcher

Prophet (3296)

sd_snatcher's picture

23-10-2019, 23:27

Grauw wrote:

I was specifically referring to detecting MSX-AUDIO (Y8950), and not OPL family in general which can indeed be done using the timer. This is the best and simplest way I have found to detect it.

I know, this is way I said "don't get me wrong". But this is a recurring issue, and probably every programmer that tries to make some game with OPLn support will have to deal with it. So I tried to make my answer as generic as possible so if anyone ever googles for this issue in the future, he might find his answers here.

But maybe I'm taking the wrong approach. It would probably be better for us, as a community, to write an article on the MSX-Wiki about the best approaches to detect and handle the OPL soundchips on the MSX, with both the official and unofficial ways described. This way the programmer can decide what approach best suit his requirements.

Just for the sake of precision: In the programming context I prefer to call "MSX-Audio" a whole cartridge that at least complies with the chip+BIOS specs. When talk about direct chip programming, it's less ambiguous to use the real chip names just like we do with the VDP (TMS9918, V9938, V9958 etc): So it's Y8950, YMF262 (or OPL3), YMF278 (or OPL4) and so on.

Quote:

Even if you would want to modify the music driver to support OPL by omitting the ADPCM loading and playback if necessary, you would still need to determine whether it is an MSX-AUDIO or not.

Yes you are right. This is why I proposed a two-step detection: One to detect the OPLn chip, and other to detect its features.

Since most MoonBlaster 1.4 music made for MSX-AUDIO relies heavily on ADPCM though, you will probably get a broken version of the music.
Quote:

This is where I beg to disagree. We have games that use moonblaster and support both the Y8950 and YM2413. When played on the YM2413, there's no ADPCM playback, and we always were perfectly happy with this support. Why should the other OPLn chips should get a different treatment? IMHO, it's just different characteristics of the chips being taken advantage. On the OPL3, the soundtrack can produce real stereo sound, i.e.

(Just like Space Manbow has panning borders on the V9938, and we don't call this "broken" Wink )

[quote=Grauw

wrote:
sd_snatcher wrote:

I can't avoid to remind that none of this are the correct way according to the MSX standard. The official MSX way is described on the MSX datapack and involves calling the EXTBIO hook.

That does not work with the Philips or Toshiba Music Module because they do not have the MSX-AUDIO BIOS, so it is merely a distraction to the goal of this thread.

As I mentioned, I was thinking of an answer that could help any programmer that could google for this problem later. Maybe I took the wrong approach, sorry (wiki article instead?), but with good intentions. Smile

Grauw wrote:

My recommendation is always to use RDSLT and WRSLT, and save ENASLT for when it is absolutely necessary. The former two are much easier to use since you don’t have to worry about the current slot selection state.

I totally agree with this. Detection isn't some part of a software that runs all the time would require high performance, and using RDSLT will result in a much more compact code.

By Grauw

Ascended (9181)

Grauw's picture

24-10-2019, 00:31

sd_snatcher wrote:
Grauw wrote:

Since most MoonBlaster 1.4 music made for MSX-AUDIO relies heavily on ADPCM though, you will probably get a broken version of the music.

This is where I beg to disagree. We have games that use moonblaster and support both the Y8950 and YM2413. When played on the YM2413, there's no ADPCM playback, and we always were perfectly happy with this support. Why should the other OPLn chips should get a different treatment? IMHO, it's just different characteristics of the chips being taken advantage. On the OPL3, the soundtrack can produce real stereo sound, i.e.

Of course I don’t disagree with multi chip support in principle, but IMO the difference lies in whether the trade-off is intentionally made (the musician may choose to replace the ADPCM with FM or PSG drums), versus music that really is made for the more feature-rich chip and when part of it is missing you’ll get a lacking experience that the musician never authored for.

Similar to how many of us say that Konami games should really be played at 60 Hz for the authentic experience, and playing them at 50 Hz with slowed down music, gameplay and flatter pixels is… well, there are strong and moderate opinions about it Smile.

If the music is made for OPL and also plays an all of its descendants with perhaps some PCM drum additions, stereo and increased polyphony on MSX-AUDIO, OPL3 and OPL4, then of course that sounds pretty cool. But we never had a plain OPL released for MSX so I don’t think that makes much sense to compose for unless the second target is OPL4 with PCM. Which involves much more new replayer code than detection alone.

By hit9918

Prophet (2895)

hit9918's picture

24-10-2019, 15:17

norakomi wrote:

fm pac in slot 2 works, in slot 1 doesn't.

norakomi wrote:

force subslot regs into correct position

this smells like you got an own enaslt code and it is broken
even worse the need to warmup FFFF means that there is no enaslt function. but "OUT A8 all over the place". a style that is always buggy.

you need an enaslt function. that updates fcc5 mirrors. and a GETSLT function. that is easy and fast with fcc5. to debug enaslt or to simply save the slot select before using enaslt.
bios ENASLT works on page 1.

By sd_snatcher

Prophet (3296)

sd_snatcher's picture

25-10-2019, 02:51

Grauw wrote:

Of course I don’t disagree with multi chip support in principle, but IMO the difference lies in whether the trade-off is intentionally made (the musician may choose to replace the ADPCM with FM or PSG drums), versus music that really is made for the more feature-rich chip and when part of it is missing you’ll get a lacking experience that the musician never authored for.

I understand your POV, but since the idea here would be to teach programmers on how to write new software to detect and support the OPLn sounchips, do we agree that only the first case would be happening?

Thus, the documentation would describe the best way to support the OPLn chips. Then it's up to the game team creative process to decide how the music will sound on any of them, and what's the best use they'll do of each chip specific features. Smile

The same dilemma already happens with the PSG vs OPLL: some people create specific soundtracks for the PSG, while others decide that when the OPLL is not present, the PSG will still produce the same notes that it would do if a OPLL was present. Yes, you get a crippled version of the song (like most Micro Cabin games), but that decision was up to them (limited resources sometimes dictate that).

By norakomi

Paragon (1086)

norakomi's picture

23-11-2019, 11:18

One month later and still I'm not able to do a good detection.
I do however use Bios this time.
So about msx-music (fmpac) I just use the original code of MBLOADER (the moonblaster driver).
The first thing I notice is that the check for APRLOPLL isn't in the code at all.

This is the code that I execute: (the call SRCCHP)

;
; conditionals
;
;withBIN: equ 0 ;1=include .bin header
withAUD: equ 1 ;1=include check for emulated MSX-MUSIC
withGPIO: equ 1 ;1=include check for real Y8950 GPIO
withDisk: equ 0 ;1=include disk loading code

;
;Note: The labels CHIPS and SMPADR refered to in this source file should be
; written to the locations with the same labels in MBPLAY.SRC. When
; using this source file together with MBPLAY.SRC, make sure to remove
; these labels at the end of the source in some way to make sure the
; values are written to the correct location. They are in this source
; file just for the sake of being able to assemble it without errors.
;
;if withBIN=1
; db 0feh
; dw start,end,start
; org 0c000h

;start:
;endif
;
; BDOS constants
;
if withDisk=1
BDOS: equ 0f37dh
SETDMA: equ 26
READ: equ 39
OPEN: equ 15
CLOSE: equ 16
endif

;---------------- check connected soundchips ---------------
;
;Output = CHIPS contains 0,1 or 2.(MSX-AUDIO,MSX-MUSIC(fmpac),both)
;

SRCCHP: xor a
ld (CHIPS),a
call SRCFMP CryingMSC-Music / FMPac)
call SRCAUD ;MSX AUDIO / MUSIC MODULE
ld a,(CHIPS)
or a
ret z
dec a
ld (CHIPS),a
ret

;----- find MSX-MUSIC / FMPac -----

SRCFMP: ld hl,0fccah
xor a
ld b,4
FMLP2: push bc
ld b,4
FMLP1: push bc
push af
push hl
set 7,a
ld h,040h
call 024h
pop hl
push hl
ld a,(hl)
cp 020h
call z,FMTEST
jp z,FMFND
pop hl
pop af
add a,4
and 0fh
inc hl
inc hl
inc hl
inc hl
pop bc
djnz FMLP1
add a,1
and 03h
pop bc
djnz FMLP2
jp SETBAS
FMTEST: ld hl,04018h
ld de,FM2TXT
ld b,8
call FMLP
jr z,FM2
ld hl,0401ch
ld de,FMTEXT
ld b,4
call FMLP
if withAUD=1
ret nz
ld hl,04018h
ld de,FM3TXT
ld b,3
call FMLP
jr Z,FMEMU
xor a
FMEMU: or a
endif
ret

FMLP: ld a,(de)
cp (hl)
ret nz
inc hl
inc de
djnz FMLP
cp a
ret
FM2: ld a,(CHIPS)
set 2,a
ld (CHIPS),a
ret
FMFND: pop hl
pop af
pop bc
pop bc
ld a,(CHIPS)
bit 2,a
res 2,a
set 1,a
ld (CHIPS),a
jr nz,SETBAS
ld a,(07ff6h)
or 1
ld (07ff6h),a
SETBAS: ;di
ld a,(0fcc1h)
ld h,040h
call 024h
;ei
ret
if withAUD=1
FM3TXT: db "AUD"
endif
FM2TXT: db "APRL"
FMTEXT: db "OPLL"

;---- find MSX-AUDIO ----

SRCAUD: in a,(0c0h)
if withGPIO=1
cp 0ffh
ret z
else
or 06h
cp 06h
ret nz

ld a,018h
out (0c0h),a
ld a,0fh
out (0c1h),a
ld a,019h
out (0c0h),a
ld b,0
.GPIO: ld a,b
out (0c1h),a
in a,(0c1h)
and 0fh
cp b
ret nz
inc b
bit 4,b
jr z,.GPIO
ld a,018h
out (0c0h),a
xor a
out (0c1h),a
endif
ld a,(CHIPS)
set 0,a
ld (CHIPS),a
ret

;------------------- load MoonBlaster song ----------------
;
; Note: - Make sure the name is writting in the FCB before
; calling the routine!
; - Make sure to only load USER saved files!

if withDisk=1
MBLOAD: push de
call OPENF
pop de
ld hl,(BLENG)
call LOADF
jp CLOSEF

;------------------- load MoonBlaster sample kit -----------
;
; Note: - Make sure to switch off the R800 mode before
; calling the routine!
;

MKLOAD: call OPENF
ld de,08000h
ld hl,56
call LOADF
ld hl,08000h
ld de,SMPADR
ld bc,56
ldir
ld a,1
ld (SAMPDT),a
ld hl,04000h
ld de,08000h
call LOADF
call MOVSMP
ld hl,04000h
ld de,08000h
call LOADF
call MOVSMP
jp CLOSEF

;------ disk access routines ------

OPENF: ld de,FCB
ld c,OPEN
call BDOS
ld hl,1
ld (SIZE),hl
dec hl
ld (BLOCK),hl
ld (BLOCK+2),hl
ret
LOADF: push hl
ld c,SETDMA
call BDOS
ld de,FCB
pop hl
ld c,READ
jp BDOS
CLOSEF: ld de,FCB
ld c,CLOSE
jp BDOS
endif

;------- transfer samplekit into MSX-AUDIO RAM ------

SAMPDT: db 1
MOVSMP: ld a,(SAMPDT)
xor 1
ld (SAMPDT),a
or a
ex af,af'
call Z,MOVSM2
ex af,af'
call nz,MOVSM3
;di
ld a,4
out (0c0h),a
ld a,060h
out (0c1h),a
ld bc,04000h
ld hl,08000h
MOVSM6: ld a,0fh
out (0c0h),a
ld a,(hl)
out (0c1h),a
ld a,4
out (0c0h),a
ld a,080h
out (0c1h),a
inc hl
dec bc
ld a,b
or c
jr z,MOVSM4
MOVSM5: in a,(0c0h)
bit 3,a
jr z,MOVSM5
jr MOVSM6
MOVSM4: ld a,4
out (0c0h),a
ld a,078h
out (0c1h),a
ld a,080h
out (0c1h),a
ld a,7
out (0c0h),a
ld a,1
out (0c1h),a
;ei
ret
MOVSM3: ld hl,SAMPD3
jr MOVSM7
MOVSM2: ld hl,SAMPD2
MOVSM7: ld b,10
MOVSM8: ld a,(hl)
out (0c0h),a
inc hl
ld a,(hl)
out (0c1h),a
inc hl
djnz MOVSM8
ret
SAMPD2: db 004h,078h,004h,080h,007h,001h,007h,060h,008h,000h
db 009h,000h,00ah,000h,00bh,0ffh,00ch,00fh,010h,0f0h
SAMPD3: db 004h,078h,004h,080h,007h,001h,007h,060h,008h,000h
db 009h,000h,00ah,010h,00bh,0ffh,00ch,01fh,010h,0f0h

;----------- FCB -----------

if withDisk=1
FCB: db 0,"???????????"
dw 0
SIZE: dw 0
BLENG: dw 0 ; block length
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
BLOCK: dw 0
dw 0
endif

;---- miscellaneous labels (these should refer to the ones in MBPLAY.SRC!) ----

;CHIPS: db 0
;SMPADR: ds 56

;if withBIN=1
;end:
;endif

So, this code is then not complete ??

By Metalion

Paragon (1155)

Metalion's picture

03-08-2020, 09:13

norakomi wrote:

One month later and still I'm not able to do a good detection. I do however use Bios this time. So about msx-music (fmpac) I just use the original code of MBLOADER (the moonblaster driver). The first thing I notice is that the check for APRLOPLL isn't in the code at all.

So, this code is then not complete ??

No, the string detection is in, look better in the code, here Smile

if withAUD=1
FM3TXT:	db	"AUD"
endif
FM2TXT:	db	"APRL"
FMTEXT:	db	"OPLL"

Sorry to unearth this topic, but I'm looking also for a good detection code for MSX-Music.

So in the end, which code worked the best ?

Page 4/4
1 | 2 | 3 |