fox Posted December 15, 2017 Share Posted December 15, 2017 How do I play a note via MIDIMATE? I'm trying the following code but hear nothing in Altirra: org $6000 main sei ldy #7 lda #0 sta:rpl ^20,y- mva #$28 ^28 mva #$15 ^24 mva #$23 ^2f mva #0 ^2e mva #$10 ^2e mvx #$c0 ^2d ldx #$01 ; instrument jsr send ldx #$90 jsr send ldx #$3c ; middle C jsr send ldx #$7f jsr send mva $10 ^2e cli rts send lda #$10 and:rne ^2e sta ^2e mva #$10 ^2e stx ^2d rts run main end Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 16, 2017 Share Posted December 16, 2017 There are some setup problems in the serial communication: The serial rate is out of spec. MIDI requires 31.250Kbaud +/- 1%, while a POKEY divisor of $15 corresponds to 31.960Kbaud for NTSC or 31.667Kbaud for PAL. POKEY can't hit this baud rate with sufficient accuracy, so MIDIMATE supplies an external 4MHz/128 clock to use. You need to assert the motor line (PACTL=$34) and enable sending with the external clock (SKCTL=$13). There is, however, a bug in Altirra's MIDI parsing of SysEx messages that is triggering here -- it is trying to parse the program change message as a 3-byte message instead of a 2-byte message. You can work around this by sending a padding $00 byte. I'll fix this for the next release. I'd also recommend waiting for the serial transmission to fully complete before exiting, just in case something is going to reset the serial port immediately after. Waiting for serial output ready and then serial output complete is required to ensure that the last byte is completely sent. 5 Quote Link to comment Share on other sites More sharing options...
fox Posted December 16, 2017 Author Share Posted December 16, 2017 Thank you! It works. I noticed that MIDI Sequencer by Maciej Sygit uses the $15 divisor. The difference seem small enough to transmit one byte if the MIDI device synchronizes on every start bit - does it? Is the 4MHz/128 clock internal to MIDIMATE? I don't know what's inside MIDIMATE, but I know that in the '90s people used a simple "wires-only" SIO-MIDI interface. The minimum set of changes was: motor on, a padding byte and waiting for transmission to complete: org $6000 main sei mva #$34 ^32 ; motor on ldy #7 lda #0 sta:rpl ^20,y- mva #$28 ^28 mva #$15 ^24 mva #$23 ^2f mva #0 ^2e mva #$10 ^2e mvx #$c0 ^2d ldx #$01 ; instrument jsr send ldx #$00 ; padding needed for Altirra jsr send ldx #$90 jsr send ldx #$3c ; middle C jsr send ldx #$7f jsr send lda #8 and:rne ^2e ; wait for transmission complete mva #3 ^2f mva $10 ^2e cli rts send lda #$10 and:rne ^2e sta ^2e mva #$10 ^2e stx ^2d rts run main end Quote Link to comment Share on other sites More sharing options...
_The Doctor__ Posted December 16, 2017 Share Posted December 16, 2017 The external clock also unlocks protected midi software that detects it off the sio... the timing also becomes more critical as more time passes and more devices are involved as well as quarters and triggers..... Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 16, 2017 Share Posted December 16, 2017 I just released 2.99-test24, which should no longer need the $00 padding workaround. The 4MHz/128 clock is indeed built into the MidiMate. Activating the motor control line enables two features on the MidiMate, one being the 31.25KHz clock for POKEY to use, and another connecting the SYNC input to the SIO INTERRUPT line for synchronization purposes. Software written for the actual MidiMate will not work with an adapter that doesn't provide this external clock, as it'll set POKEY to use the nonexistent serial clock and serial output will never complete. As for whether you can get away with using an out-of-spec clock, it depends. I have no experience with actual MIDI hardware, so I couldn't say. If you were just using MidiMate-like adapters to network Ataris, then POKEY would be handling the receiving end and you could probably get away with it. There's no guarantee that other MIDI devices synchronize to the incoming stream the way POKEY does, however. On top of that you have analog signal effects to deal with. Thinking of the input as a perfectly clean square wave can lead you to believe you can get away with +/-5% in baud rate, but real-world effects mean you'll want to be much better than that. lda #8 and:rne ^2e ; wait for transmission complete This isn't quite safe -- you need to wait for output ready first ($10) and only then wait for output complete ($08). This is because of a quirk/bug in POKEY where the output complete IRQ can stay on for up to half a bit until the last byte begins shifting out, and the serial output complete IRQ is actually the "not shifting" signal internally. The serial output ready IRQ trips when a byte is transferred from SEROUT to the shift register, so after it fires you can be sure that the output complete IRQ has turned off. 4 Quote Link to comment Share on other sites More sharing options...
antrykot Posted December 16, 2017 Share Posted December 16, 2017 Hi Phaeron, Could you also fix MidiMate emulation to handle running status messages? Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 16, 2017 Share Posted December 16, 2017 I'm not sure what you mean by status messages...? Quote Link to comment Share on other sites More sharing options...
antrykot Posted December 16, 2017 Share Posted December 16, 2017 The MIDI protocol allows for certain types of messages to be sent without a status byte. The receiving device will then use the last status byte it received. This is called running status and its purpose is to minimize bandwidth used. For example if the bytes 0x90 0x41 0x7f 0x43 0x7f are sent to the serial output, midiOutShortMsg should be called twice midiOutShortMsg(out, 0x7f4190); midiOutShortMsg(out, 0x7f43); Altirra does only the first call. More complicated example, those bytes: 0x90 0xfa 0x41 0x00 0x43 0xfc 0x00 are really four messages midiOutShortMsg(out, 0xfa); midiOutShortMsg(out, 0x4190); midiOutShortMsg(out, 0xfc); midiOutShortMsg(out, 0x43); Messages 0xfa and 0xfc are MIDI real-time messages they can be interspersed with any other message and they don't cancel running status. 1 Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 16, 2017 Share Posted December 16, 2017 Ugh... okay, lemme look into that. Quote Link to comment Share on other sites More sharing options...
fox Posted December 18, 2017 Author Share Posted December 18, 2017 I confirm that Altirra 2.99-test24 doesn't require the padding byte. What's the use of SYNC input? SIO INTERRUPT is a PIA IRQ? I think that MIDI devices have to sync on the start bit, otherwise they could be probing at the signal edges. And the clocks aren't probably perfect. Thanks for pointing out the problems with analog distortions and awaiting completion. More complicated example, those bytes: 0x90 0xfa 0x41 0x00 0x43 0xfc 0x00 are really four messages midiOutShortMsg(out, 0xfa); midiOutShortMsg(out, 0x4190); midiOutShortMsg(out, 0xfc); midiOutShortMsg(out, 0x43); Messages 0xfa and 0xfc are MIDI real-time messages they can be interspersed with any other message and they don't cancel running status. Doesn't 0x43 have the implicit command 0x90? If so, why is it reordered with 0xfc? Quote Link to comment Share on other sites More sharing options...
antrykot Posted December 18, 2017 Share Posted December 18, 2017 0x90 is a note-on message which requires two data bytes. 0x43 is just the first data byte, so we have to wait for the second one, 0x00 in this case. On the other hand 0xfc can be sent immediately after it was received. The last call to MidiOutShortMsg sends two bytes, I could have written it: midiOutShortMsg(out, 0x0043); but writing leading zeroes seemed unnecessary to me. Quote Link to comment Share on other sites More sharing options...
fox Posted December 18, 2017 Author Share Posted December 18, 2017 Thank you. Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 18, 2017 Share Posted December 18, 2017 The MidiMate has SYNC IN and SYNC OUT connectors to allow an audio tape to be used for a clock track. The SIO INTERRUPT line is connected to PIA CB1 and thus SYNC IN allows the tape signal to trigger CB1 interrupts. On the output side, the SIO CLOCK OUT signal from the computer is used to record a clock track on tape. Quote Link to comment Share on other sites More sharing options...
fox Posted December 20, 2017 Author Share Posted December 20, 2017 Audio tape? Where do you put it? Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 20, 2017 Share Posted December 20, 2017 You connect its line in/out to SYNC IN/OUT on the MidiMate. No connection to SIO bus. Quote Link to comment Share on other sites More sharing options...
fox Posted December 23, 2017 Author Share Posted December 23, 2017 So it's for a regular tape recorder? Regarding the motor control signal: should there be a delay between activating it and starting to send? If so, how long? Should I turn it off after I send all the notes? Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 23, 2017 Share Posted December 23, 2017 So it's for a regular tape recorder? Yup, just provides a very simple trigger signal at regular intervals. MidiTrack III supports it, but I haven't actually tested this feature on the real MidiMate -- I'd have to dig around for an adapter since the SYNC inputs are big 3/8" plugs. Regarding the motor control signal: should there be a delay between activating it and starting to send? If so, how long? Should I turn it off after I send all the notes? Shouldn't need a delay to start, but you do need to wait for the transmission to fully end before stopping it. The motor control is only used to gate the external clock and doesn't send any other signal on the MIDI bus, so it only needs to be on as long as POKEY needs a serial clock. Treat it the same way you'd treat the applicable bits in AUDCTL ($D208) and SKCTL ($D20F) during a regular SIO bus transfer. Quote Link to comment Share on other sites More sharing options...
fox Posted December 23, 2017 Author Share Posted December 23, 2017 In this case I would expect Altirra to accept MIDI commands sent with AUDF=$15 and no motor signal. I'm using Altirra 2.99-test24. Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 23, 2017 Share Posted December 23, 2017 Out of spec baud rate aside, this won't work because the MidiMate isolates the SIO bus from the MIDI bus when inactive. Quote Link to comment Share on other sites More sharing options...
fox Posted December 23, 2017 Author Share Posted December 23, 2017 I'm confused because you just contradicted your previous post: "The motor control is only used to gate the external clock". Quote Link to comment Share on other sites More sharing options...
phaeron Posted December 23, 2017 Share Posted December 23, 2017 Sorry, let me clarify. What I meant was that it's not like the SIO COMMAND line, which is a separate signal that the device can see directly. The SIO spec requires a small delay there because the device needs time to turn around from checking COMMAND to receiving serial data. When using SIO MOTOR for a tape drive, you also need a delay because the tape motor needs time to spin up. Neither of these are needed with the MidiMate because the motor control signal doesn't go out on the MIDI bus and devices can't see it, so you can toggle it immediately before and after sending a byte. But you do need it asserted to do any MIDI communication with the MidiMate, because it enables everything -- SIO data in, data out, clock in, clock out, and interrupt are all gated by motor control. If it's off, then there's no connection to the MIDI bus at all and no interference with other SIO bus devices. Quote Link to comment Share on other sites More sharing options...
fox Posted December 23, 2017 Author Share Posted December 23, 2017 Thanks for clarifying. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.