Image Map Image Map
Results 1 to 10 of 10

Thread: playing MIDI through PC speaker on an XT

  1. #1

    Default playing MIDI through PC speaker on an XT

    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/Person...01.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?
    Attached Files Attached Files
    Last edited by mdanh2002; February 26th, 2018 at 06:58 PM.

  2. #2
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,467
    Blog Entries
    20

    Default

    I believe that the AH=86h/int 15h call was first implemented in the 5170. See Ralf Brown's List on this function

  3. #3

    Default

    Quote Originally Posted by Chuck(G) View Post
    I believe that the AH=86h/int 15h call was first implemented in the 5170. See Ralf Brown's List on this function
    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?
    Last edited by mdanh2002; February 27th, 2018 at 12:18 AM.

  4. #4
    Join Date
    Dec 2014
    Location
    The Netherlands
    Posts
    2,024

    Default

    Quote Originally Posted by mdanh2002 View Post
    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.

  5. #5
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,467
    Blog Entries
    20

    Default

    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.

  6. #6

    Default

    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?

  7. #7
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,467
    Blog Entries
    20

    Default

    You can also "calibrate" your CPU loops against the timer and vary the timing according to the CPU speed.

  8. #8
    Join Date
    Dec 2014
    Location
    The Netherlands
    Posts
    2,024

    Default

    Quote Originally Posted by mdanh2002 View Post
    Do you have the link to download your MIDI player?
    Binary is here: https://www.dropbox.com/s/7d7ff4opmy...MPlay.zip?dl=0
    Plays on a Sound Blaster MIDI interface at base address 220h.
    I haven't released the source.

  9. #9

    Default

    Quote Originally Posted by Scali View Post
    Binary is here: https://www.dropbox.com/s/7d7ff4opmy...MPlay.zip?dl=0
    Plays on a Sound Blaster MIDI interface at base address 220h.
    I haven't released the source.
    Thanks. I will try it out.

  10. #10

    Default

    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...the-ibm-pc-xt/
    Attached Files Attached Files
    Last edited by mdanh2002; July 5th, 2019 at 12:58 AM.

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
  •