Issue with Soundpool MO4
I have a Atari STe with a Soundpool MO4 MIDI extension. It used to work very well, but unfortunatelly doesn't anymore: Cubase still detects it, and I can output MIDI to it but nothing is coming out from any MIDI Out. It took me a while to tackle it (lack of time, lack of tool, other items to play with), but I gave a glance last week-end.
The parallel port on the Atari uses only the following signals:
- Pin 1 : Strobe (Atari -> MO4)
- Pin 2 : Data 0 (Atari -> MO4)
- Pin 3 : Data 1 (Atari -> MO4)
- Pin 4 : Data 2 (Atari -> MO4)
- Pin 5 : Data 3 (Atari -> MO4)
- Pin 6 : Data 4 (Atari -> MO4)
- Pin 7 : Data 5 (Atari -> MO4)
- Pin 8 : Data 6 (Atari -> MO4)
- Pin 9 : Data 7 (Atari -> MO4)
- Pin 11: Busy (MO4 -> Atari)
Inside the box, the MO4 is architectured around a CPLD (IspLSI1016 from Lattice) which contains the logic. The other ICs are Lattice GAL16V8 (for reducing the 8 MHz clock to 500 KHz) and a 74LS541 for buffering. Also, a 7805 voltage regulator (alim is 7.5V, positive central), a diode for protection and few passive componants: crystal, pull up/pull down resistors and filtering/decoupling caps. We find a port for In-System Programming of the CPLD, as well as a couple of test points. There is not silkscreening on the pcb. I regret the lack of a led to show the status of power, since it's easy to plug it the wrong way: the silkscreening on the box itself is misleading on this point.
The CPLD manages all the signals from the parallel port, and is also responsible to perfom the parallel to serial convertion. Despite the MIDI protocol allows to select among 16 channels, it doesn't include a way to select a specific output. I don't know yet what SoundPool chose to implement the output select: Control Change? Unimplemented Real-time? I know however that all bits from the parallel port appear on two different pins on the CPLD; is this used for parallel-to-serial or for output selection, I don't know yet.
The communication between the Atari and the CPLD is achieved thru the Strobe (pin 1) and Busy (pin 11) lines: the Atari pulse the Strobe line before sending data, and read the Busy line to check the status. On the Busy line, low indicates ready and high indicates busy. Busy is connected to the Multi Function Peripheral (MFP 68901) of the Atari, precisely at address=$FFFA01, bit 0. My problems is precisely here: after the initialization, the CPLD keeps the busy line to low, and the parallel port stays steady. I was able to trigger the send of new data by pulsing Busy to high. All signals (Busy, Strobe, MIDI out flow) are sent across the 74LS541.
The capture below shows the initialization of the MO4 when the driver (MO44.DRV) is started. The source code responsible for this initialization is the following:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Reset hardware. ; Writes four zero bytes to the printer port, which corresponds to ; the Strobe line (normally high). ; Each pulse is 3 micro-seconds (1.5 high, 1.5 low). ; ; The Atari ST uses 2 registers of the Sound generator YM-2149 to drive ; the Centronics (parallel) port. ; Register 14 bit 5 contains the value of Centronics' Strobe line. ; Register 15 is the Centronics Data. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; reset_hardware: movem.l d0-d1/a5,-(a7) move.w sr,-(a7) movea.w #ym_data,a5 ori.w #$0700,sr ; Interrupts off. move.b #15,ym_base.w ; Select register 15 of the YM-2149 (Centronics) move.b #0,(a5) ; Set data lines to 0. move.b #14,ym_base.w ; Select register 14 = parallel port A move.b ym_base.w,d0 ; Fetch port A status to d0. move.w d0,d1 ; Copy d0 to d1 and.b #$DF,d1 ; Strobe low value. or.b #$20,d0 ; Strobe high value. move.b d1,(a5) ; Pulse strobe low-high four times. move.b d0,(a5) ; This gets the hardware back to a state where move.b d1,(a5) ; it's expecting a port bitfield, regardless move.b d0,(a5) ; of what state it's currently in. move.b d1,(a5) move.b d0,(a5) move.b d1,(a5) move.b d0,(a5) ; End with strobe high.
I reverse engineered to draw a schematic, however I don't know yet what causes Busy to stay low: bad join, dead gate on the 74LS541, or worse, dead gate or corrupted program on the CPLD. I'll investigate more with a logic analyzer.
UpdateI managed to obtain some results by triggering the /busy line. For this, I made a small circuit on breadboard with a NE555 configured as monostable (goes low around .5 sec, then goes high) and switch. The goal is to debounce the switch. With this circuit, I was able to communicate with the Atari and to trigger the send of next bytes. Unfortunatelly, probably due to timing issue, the result is hardly exploitable.
Comments
I was able to force the Atari to send new bytes by triggering the STROBE line (I did so with a switch and a NE555 configured as monostable to filter out bouncings). I also tried by connecting the STROBE to the clock (the GAL does the clock division, so on different port, you'll find different frequencies), but no luck. So the cause is very likely the CPLD.
The MO4 has the ISP (In-System Programming) port available, but without the source nor the programmer, it's useless.
My next idea was to get rid of the entire board and simulate the same with a STM32. But since I have many other projects running, it will probably never see light... :-)
Just to link this here for good measure, here are a few disassembled MROS drivers inclusive of the MO4: https://github.com/ggnkua/Atari_ST_Sources/tree/master/ASM/Various/Foxie
The above is from this thread on AF, where the MROS SDK can be found: https://www.atari-forum.com/viewtopic.php?t=25067&sid=f3bbe9befdf0cc02636b159179e220a6
Thanks for the links, very interesting. I quickly read the source of MROS Driver for the MO4, this fixed some of my assumptions. The selection of destination (MIDI OUT) is performed by MROS, not by the driver itself.
The dialog with hardware is performed via /Strobe (Atari -> MO4) and /busy (MO4 -> Atari).
Also, such architecture is easily expandable.
The only thing I don't fully understand yet is how the correct output is selected; it's done inside MROS, not by the driver. My understanding is the driver receives 4 bit fields from MROS, and send them to the MO4, pulsing the STROBE line before and after each bit field. So STROBE is not used to select the output, only to warn the MO4. My guess is the first byte after STROBE is pulsed contains the selection of output, which could as simple as 1 to 4 (or 0 to 3).