> MIDI/src - *MIDI v1.20 * Redirect SOUND commands to MIDI port 0 Syntax: *MIDI (ON|OFF|) (&) (: 2' v1.00 20-Oct-1989 Initial version <. v1.01 20-Dec-1989 Added parameter F7 v1.02 15-Jan-1991 Modifed clock for EMR interface PA v1.10 20-Mar-1992 Tidied up code, added parameter Z0 v1.11 21-Mar-1992 Added default parameters d/ v1.12 25-Jul-2010 Works out clock setting n5 v1.13 28-Jul-2010 Some optimisation and tidying xI v1.20 30-Jul-2010 AllOff loops from SOUND x,-N,x,x, ignores chan>16 : (OSARGS=&FFDA:OSBYTE=&FFF4:WORDV=&20C : ! mcode% &280:load%=&FFFF0900 %ptr=&A8:num=&AA:regA=&EF:ctrl=&F0 : P=0 1 P%=load%:O%=mcode% [OPT P*3+4 :.defAddr:EQUB &FCF0 255 :\ Default I/O port K.defClk :EQUB 0 :\ Default clock setting 0,&15,&16 /EQUS "v1.20":EQUS 1,0) :\ Spare padding :  .RdNum  LDX #0  .RdNumLp "&LDA (ptr),Y:CMP #"0":BCC RdNumEnd ,CMP #"9"+1:BCC P%+4:SBC #7 6 #15:STA num @TXA:ASL A:ASL A:ASL A:ASL A JA num:TAX:INY:BNE RdNumLp T .RdNumEnd ^ TXA:RTS h .SkipSpc r-LDA (ptr),Y:INY:CMP #" ":BEQ SkipSpc:RTS |: .go% @LDX defAddr:JSR setPorts :\ Set default I/O port =LDA defClk:STA mClock :\ Set default Clock %LDA #1:LDX #ptr:LDY #0:JSR OSARGS ?LDA (ptr),Y:CMP #13:BEQ initON :\ *MIDI -> Do *MIDI 5 #&DF:CMP #"O":BNE initNum :\ Not *MIDI / INY:LDA (ptr),Y: #&DF 1CMP #"N":BEQ initON :\ *MIDI 1CMP #"F":BEQ initOFF:DEY :\ *MIDI  .initNum ;CMP #"&"&DF:BEQ initAddr :\ &nnnn - I/O Address EJSR RdNum:CMP #&10:BCC P%+4:SBC #7 :\ Get channel as dec or hex BJSR midiSetChannel :\ Convert 1..16 to 0..15 $JSR SkipSpc:CMP #"&":BNE initON  .initAddr ;INY:JSR RdNum:JSR setPorts :\ Set I/O address & .initON 0=LDX mClock:BNE initClock :\ Use coded default :?LDA #&15:STA mClock:JSR midiReset :\ Set to Divide By 16 DEPHP:SEI:LDY #4 :\ Time TxData clearing, X=0 N=.initLp1:LDA #0:JSR midiOutWR :\ Send note=0,vel=0 X*.initLp2:DEX:JSR midiTxRDY:BEQ initLp2 b?DEY:BNE initLp1:PLP:TXA: #&40 :\ X should be about &B0 lDBEQ initClock:INC mClock :\ If not, use Divide By 64 v.initClock DJSR midiReset :\ Reset ACIA and set Clock >JSR cmpWORDV:BEQ initExit :\ Already redirected LDA WORDV+0:STA oldWORDV+0 LDA WORDV+1:STA oldWORDV+1 #LDA #midiWORD 255:STA WORDV+0 #LDA #midiWORD 256:STA WORDV+1  .initExit RTS  .initOFF :JSR cmpWORDV:BNE initOffExit :\ Not redirected LDA oldWORDV+0:STA WORDV+0 LDA oldWORDV+1:STA WORDV+1 .initOffExit RTS  : .midiReset  LDA #3:JSR midiReset2 *%LDA #&15:]:mClock=P%-1:[OPT P*3+4 4.midiReset2 >,STA &FCF0:]:mCommand=P%-2:[OPT P*3+4:RTS H .setPorts R.STX mCommand:STX mStatus:INX:STX mData:RTS \ .cmpWORDV f/LDA WORDV+0:CMP #midiWORD 255:BNE cmpDone p,LDA WORDV+1:CMP #midiWORD 256:.cmpDone zE.midiCORE :\ Resident code starts here .noNewNote RTS : \ OSWORD intercept \ ----------------  .midiWORD CMP #7:BEQ midiSOUND  .oldWORD JMP (oldWORDV)  .oldSOUND LDX ctrl+0:LDY ctrl+1 LDA #7:BNE oldWORD : .midiSOUND  STX ctrl+0:STY ctrl+1:LDY #0 @LDA (ctrl),Y: #15:BEQ oldSOUND :\ Channel 0, pass to MOS $CTAX:INY:LDA (ctrl),Y:INY :\ X=1..15, up to 15 notes .BCMP #&FE:BEQ midiControl :\ -257 -> MIDI Control 8ICMP #&20:BCS oldSOUND :\ Channel >= &2000, pass to MOS B>CMP #&10:BCS noNewNote :\ Ignore &Hxxx notes L@LDA lastnote,X:BMI noOldNote:PHA :\ Nothing being played VKLDA #&80:STA lastnote,X:JSR midiCmd :\ Send NoteOff to current channel `BPLA:JSR midiOut:JSR midiOutZero :\ Send note and velocity j.noOldNote t: ~\ At this point Carry=CC 4LDA (ctrl),Y:BEQ noNewNote :\ Volume=0 ASBC #0: #255:BPL P%+4:LDA #15 :\ Convert 0..-15 to 0..15 HASL A:ASL A:ASL A:PHA :\ Convert to velocity and save JLDA #&90:JSR midiCmd :\ Send NoteOn to current channel 1LDY #4:LDA (ctrl),Y :\ Pitch 9LSR A:LSR A:CLC:ADC #35:STA lastnote,X :\ Note number BJSR midiOut:PLA:BPL midiOut :\ Send note and velocity \ JSR midiOut \ BIT &262\BMI oldSOUND\RTS : 9\ -258,Command >&7F,Note,Velocity - send raw output A\ -257,Command >&7F,Note,Velocity - send to current channel <\ -257,Data <&80,0,0 - send raw data byte  6\ -257,<0,param1,param2 - midi control ;\ ----------------------------------------------------- /\ X=Channel low nybble, Y=>Command low byte (.midiControl 2@CPX #&0F :\ CS= -257, CC= -258 <&7F,note,vol d>CMP #&F0:BCS midiCtrlDone:PHA :\ &Fx, one byte only nKINY:LDA (ctrl),Y:CMP #&80:PHP :\ Copy b7 of note number to Carry x: #127:JSR midiOut :\ Send note number DPLP:INY:LDA (ctrl),Y:ASL A :\ Copy previous b7 into b0 Command high byte .midiSystem ;INY:LDA (ctrl),Y:BNE midiSetChannel :\ -257/8,-1,n,x \ #\ -257,-1,0,0 - All Notes Off '\ --------------------------------- FDEX :\ Loop x,1-count,x,x times ".midiAllLp1 ,;TAY :\ Start at note 0 6.midiAllOff @GLDA #&80:JSR midiCmd:TYA:JSR midiOut :\ Send Note Off for all notes J&JSR midiOutZero:INY:BPL midiAllOff TEINX:BNE midiAllLp1 :\ Loop twice for x,-1,x,x ^>TYA:LDX #15 :\ A=&80 for Note Off h.midiAllLp2 rBSTA lastnote,X:DEX:BNE midiAllLp2 :\ Clear last note buffer |.midiCtrlDone RTS : )\ -257,-1,chan,0 - set MIDI channel -\ --------------------------------------- .midiSetChannel &FFFF0AFE:"WARNING: Overlaps soft keys" *: 4HA$="*SAVE MIDI "+~mcode%+" "+~O%+" "+~(go%&FFFF0000)+" "+~load% >A$;:A$: