BeatMaster Support: Questions & Answers


Synchronization

actually, im very curious about what you did regarding note scheduling. one of the problems i felt that i ran into when i was attempting to implement a sequencer was the inherent port read/write delays of the mpu-401 card in dumb uart mode. i was unable to find a balance between this send rate and the timers interrupt rate. add to this the user interface overhead, and my sequencer ran very poorly. it seemed at the time that the only solution was to use smart uart mode, but all of the (scant) documentation that i had seemed to brush this mode off as a chore, so i stuck with dumb uart.

Joe - Massachussetts


If you were doing all your MIDI-processing (MPU reads/writes etc) from within the interrupt-handling mechanism (ie. with interrupts disabled), that may have been a problem. As you know only too well, it takes time to send every byte to the MPU and if you also have the user-interface and everything else to deal with, you end up with a very busy interrupt handler. If you delay the timer interrupt for too long by doing too much inside it, either the clock slows down due to excessive 'dead time' between ticks, or the interrupt blocks itself causing the clock to start missing ticks completely (depending on the mode of the 8253 timer chip). Bad news.

The way I dealt with this problem was to do the MIDI I/O asynchronously during the interval between timer-tick interrupts. By doing this I avoided any problems with synchronizing the timer and the MIDI port (BeatMaster also uses the MIDI port in dumb UART mode). The UI is updated in response to flags set by the tick-handler which are polled by the main program loop. This effectively breaks the single process of handling a tick into a hierarchy of three asynchronous threads of execution:

Interrupt Processing

MIDI I/O

User-Interface

The interrupt processing section of the handler for a hardware-interrupt (like the one triggered by the timer chip) is whatever it does before sending an End-Of-Interrupt (EOI) signal to the programmable interrupt controller (PIC) chip to re-enable hardware interrupts. Hardware interrupt handlers do this before returning to an interrupted process so that the device that triggered the interrupt knows that it has been serviced and can reset itself. Once the EOI has been sent, the system is back in normal processing mode and future interrupts can occur, even if the handler does not return immediately. Any code after the EOI can thus execute safely without slowing down the interrupt mechanism. You can think of it as executing asynchonously 'during' an interrupt-interval rather than 'in-between' interrupts.

The code before the EOI in my fast_tick() handler is restricted to programming the timer-chip for the next interrupt:

The fast_tick() handler sends the EOI before calling the user_tick() handler to do BeatMaster's real work (unless the current tick coincides with a normal timer-tick [18.2/sec] when the original DOS tick-handler is called which sends the EOI itself). This means that all the code in the user-handler (MIDI-processing etc) operates in normal processing mode and does not hold-up interrupts. This obviously means that the next tick-interrupt might break into the code if it takes too long to complete, but the danger of re-entry to the user_handler() is prevented by the intick flag in fast_tick(), which effectively closes the door to the handler before calling it.

If the user_handler() code takes so long talking to the MIDI port that it gets interrupted by the next tick, that next tick is completely skipped. The user_handler() has no way of knowing that the event even occurred and the countdown is simply restarted. In practice, this does not seem to be much of a problem since the MIDI port usually manages to keep up.

The non time-critical code to update the user-interface is executed by the main program loop and not by the interrupt handler. It does this by responding to flags which are set by the user_handler() function whenever a tick or a new beat occurs. Because DOS is a single-task system, this means that the UI will only be updated when no interrupt-driven MIDI I/O is occurring.

Eamonn


Go To: BeatMaster Support