• Please review our updated Terms and Rules here

playing MIDI through PC speaker on an XT

mdanh2002

Experienced Member
Joined
Sep 7, 2011
Messages
265
Location
Singapore
Hi,

I am trying to play a MIDI file through the PC speaker on my XT with an NEC V20 running at 12MHz. I am using the MIDIPLAY utility written by James Allwright from here http://www.bttr-software.de/freesoft/sound.htm. The actual download link has long gone, but I managed to download the ZIP file via archive.org and attached it to this post.

This tool actually plays various MIDI file nicely through the PC speaker on my 286/386. However, on my XT, after loading the file for a few seconds, it simply plays a short beep and quits. I compiled the code using Personal C Compiler (http://vetusware.com/download/Personal C Compiler 1.2d/?id=4526), which was originally used by the author, and suspected that the problem lies within the assembly code in NOTE.A that is responsible for playing sound. This code is called from MIDIPLAY.C in a while loop to play the MIDI note by note:

Code:
while (place != NULL) {
    note(place->pitch, place->start);
    place = place->next;
};

This is the actual code to play a note:

Code:
dosound:

in al, 61h
push ax
or al, 03h
out 61h, al ; turn speaker on
xor si, si

mov ax, [bp+4] ; timer interval
push ax
mov al, 0B6h
out 43h, al
pop ax
out 42h, al
mov al, ah
out 42h, al   ; set up interval

call delay

pop ax
out 61h, al ; turn speaker off

endtune:

mov sp, bp ; restore stack pointer
pop bp
ret

delay:

mov cx, word [bp+8] ; high word
mov dx, word [bp+6] ; low word
mov ah, 86h
int 15h
ret

Basically on my XT, the program parses the MIDI file and reads the list of notes into memory properly. However, when it comes to playback, each note will only be played for maybe a few milliseconds at most, instead of the specified pitch and duration, so every MIDI file will sound like a single 'beep' when played. There is no problem with the PC speaker on my XT, as games with PC speaker sounds work just fine.

Any ideas what may cause the code to fail to work on an XT?
 

Attachments

  • midiplay.zip
    23.4 KB · Views: 2
Last edited:
Instead of using INT 15h with AH=86H, do you know what I can use for the thing to work on my XT as well as my 286/386?

You would have to use the PIT counter yourself (the BIOS wait function works on the secondary CMOS timer, which was only introduced on the AT... PCs and XTs have only the 8253 timer).
You can either do it via interrupts (that's how my MIDI player works, because that way it can run in the background while other things happen in the foreground), or you can poll the timer.
The biggest problem here is that the timer runs at 1.19 MHz, and only has a 16-bit counter. So you can do a maximum of 65536 ticks at 1.19 MHz, which effectively gives you 18.2 Hz.
So what you'll want to do is to extend the counter to at least 32-bit. So you glue a 16-bit high-word 'on top' of the counter, and you decrement this high word every time the 16-bit counter wraps around.
 
Alternatively, if you're always going to be running on a PC XT at 4.77Mhz, you can program your delays with simple CPU loops. Probably more than adequate for MIDI playback.
 
I tried to simulate the delays using loop and it worked fine on my NEC V20 at 12Mhz. Nevertheless, not a good approach. Will be trying Scali's suggestion for a more flexible way of implementing the delay.

I am also thinking of porting the code to TURBO C and simply use delay() and sound() functions in conio.h to play the sound. Will let you know how it goes.

You can either do it via interrupts (that's how my MIDI player works, because that way it can run in the background while other things happen in the foreground)

Do you have the link to download your MIDI player?
 
I successfully ported the original code to Turbo C and replaced the assembly code to play MIDI notes with Turbo C's sound() and nosound() functions from conio.h. With this modification, the player works well on the XT as no AH=86h/INT 15h calls are needed. It will also work on the 286, 386 and newer machine as long as the PC speaker is present. The modified player binary, source code as well as some MIDI files for testing are attached to this post.

See the full write-up about this on my blog http://www.toughdev.com/content/2018/09/developing-a-pc-speaker-midi-player-for-the-ibm-pc-xt/
 

Attachments

  • midiplay_modified.zip
    78.9 KB · Views: 3
Last edited:
Back
Top