Skip to content

Commit

Permalink
Roughly implemented DOS beeping.
Browse files Browse the repository at this point in the history
  • Loading branch information
indigoparadox committed Jun 3, 2022
1 parent fcfdda8 commit 6ef1404
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ Currently a work in progress and very volatile.
- Check framework, for running tests: `sudo apt install check`
- ALSA development libraries for beep playback: `sudo apt install libasound2-dev`

## DOS MIDI Player

(WARNING: Experimental, extremely funny-sounding. Needs work! If you try it right now on a real machine, you will probably have to reboot that machine!)

midibeep is a simple one-track MIDI player that can be cross-compiled for DOS from a modern UNIX-like system. Given a type 1 MIDI file and a track number, it will attempt to beep out that track on the PC speaker. It requires the OpenWatcom compiler to compile.

- Ensure that `wcc` and `wcl` are in your PATH.
- Ensure that the `WATCOM` environment variable is set to your watcom installation directory (e.g. `/opt/watcom`).
- Ensure that the `INCLUDE` environment variable is set to the `h` subdirectory of your watcom installation directory (e.g. `/opt/watcom/h`).
- Execute `make midibeep.exe` in the project root.

## References

- https://web.archive.org/web/20140216225718/http://www.sonicspot.com/guide/midifiles.html
Expand Down
27 changes: 27 additions & 0 deletions src/midibeep.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#ifdef USE_ALSA
#include <alsa/asoundlib.h>
#elif defined( USE_DOS )
#include <dos.h>
#endif /* USE_ALSA */

#ifdef USE_MMAP
Expand Down Expand Up @@ -58,6 +60,31 @@ void beep( int freq_hz, int duration_ms ) {
}
}
#elif defined( USE_DOS )
uint32_t freq_division = 0;
uint8_t prev_keyb_status = 0;

/* TODO: Needs cleanup with constants for port numbers, bitmasks, etc. */

freq_division = 1193180 / freq_hz;

/* Set the programmable interrupt timer to the given frequency. */
outp( 0x43, 0xb6 );
outp( 0x42, (uint8_t)freq_division );
outp( 0x42, (uint8_t)(freq_division >> 8) );

/* Set keyboard controller status to enable PC speaker. */
prev_keyb_status = inp( 0x61 );
if( prev_keyb_status != (prev_keyb_status | 0x03) ) {
outp( 0x61, (prev_keyb_status | 0x03) );
}

delay( duration_ms );

/* Turn off the PC speaker. */
prev_keyb_status = inp( 0x61 );
outp( 0x61, (prev_keyb_status & 0xfc) );

/* TODO: Reset the PIT to its previous frequency. */

#endif /* USE_ALSA || USE_DOS */
}
Expand Down

0 comments on commit 6ef1404

Please sign in to comment.