The hardware of all four MD-1 cards is identical,
but they have slightly different software. The Pedal interface card (card
D) has the basic software; the keyboard cards differ in four respects:
1. Instead of issuing 128 note-off messages at the beginning, the software outputs an "all-notes-off" message.
2. 8-position DIP switch S2 is not used; instead, the lowest note number 36 or $24 is defaulted into the program as an EQUate at LOWNOT. This is valid since all known keyboards start on the C two octaves below middle C. (This would need to be changed only if someone uses these boards with shorter keyboards, such as the 44-key manuals used on spinet organs, or the 13-key "stick" pedalboards.)
3. As usual, a MIDI note-on message contains a velocity code which indicates how hard (or actually, how fast) the key is pressed; this is used to control loudness or timbre. In the normal MD-1 card, all keys default to velocity hex 70 (decimal 112), out of a maximum hex 7F (decimal 127). But the keyboard cards also listen for a serial input through their DB-9 RS-232 jack at the standard MIDI baud rate (31.25 kbaud). If any character is received at any time, it is substituted instead of the default velocity code. In the case of the A and C cards, this input would come from the corresponding swell shoe MD-2 card.
4. The NOTEON subroutine has been modified so that it recognizes special key combinations to change program/patch or channel numbers. It works like this:
On my 61-key solo and accompaniment keyboards, the top C (note number 96, three octaves above middle C) does not actually play any note; instead, it acts as a Control key. Think of it as a Control-C or Control-Break. It does the following:
a. Pressing that C at any time generates an "All-Notes-Off"
message on the current channel, useful for turning off any stuck notes.
b. Holding that C down stops all other keys on
the keyboard from playing, and instead makes them into special function
keys as follows:
(1) The bottom 16 keys (at the bass
end) are used to send program-change signals. Think of them as sixteen
hex digits 0 through F, and press them in sequence to choose a program
number (also called a patch number). The last two keys pressed determine
the number.
(2) The top 16 keys just below the
top C are used to change the channel number. The last key pressed determines
the number. (The B just left of the top C is channel 16.)
Please note - musicians think of channels as going from 1 to 16, and program/patch numbers as going from 1 to 128, but in reality they start at 0. So channels are really coded as 0 through 15, and patch numbers as 0 through 127 (or 00 through FF in hexadecimal). I have put small labels above the keyboards to help in selecting the proper codes; see the photo.
Click here to go to the MD-1 hardware page that describes the actual hardware of the board.
The software used on MD-1 cards A and C is listed below:
0001
* MD-1c-VEL Keyboard scanner program
0002
* Copyright (C) 2002, 2006 by Peter A. Stark
0003
0004
* This version (a) does NOT use the low-note DIP switch
0005
*
(defaults to note 36)
0006
*
(b) Allows changing channel and program numbers
0007
*
from the keyboard
0008
*
(c) Reads velocity code from rs-232 if present,
0009
*
else defaults to $70
0010
0011
* Version 1.1cvel - modified 10/24/2006 to tickle COP timer
0012
* Version 1.0Cvel - modified 9/1/2006 to input velocity from MD-2
0013
* Version 1.0C - Modified 3/13/2005 to allow changing
0014
*
channel or program numbers
0015
* Version 0.5 7/22/2002 - original
0016
0017
* I/O bits:
0018
* Inputs
0019
* PA0: Serial input from shift register
0020
* PC7-0: 1st note DIP switch
0021
* PD0: Serial RS232 input
0022
* PE5-2: Channel DIP switch
0023
* PE0: Jumper to ground for Buffalo, but usable elsewhere too
0024
* Outputs
0025
* PA7: H=RS232 (default), L=MIDI out
0026
* PB0: LOAD/SHIFT' selection line
0027
* PB1: Shift register clock line
0028
* PD1: Serial out to RS232 or MIDI
0029
0030
0031
**************************
0032
* GENERAL SYSTEM EQUATES
0033
**************************
0034
0035 0000
RAM EQU $0000
START OF RAM
0036 1000
REG EQU $1000
START OF REGISTERS
0037 b600
EEPROM EQU $B600 START OF EEPROM
0038 b7ff
ENDEEP EQU $B7FF END OF EEPROM
0039 1000
PORTA EQU $1000 PORT A
DATA & TIMER - B7=BI, B6-3=O,B2-1=I
0040 1026
PACTL EQU $1026 PORT A
CONTROL
0041 1004
PORTB EQU $1004 PORT B
DATA - OUTPUT ONLY
0042 1003
PORTC EQU $1003 PORT C
DATA - BI
0043 1005
DDRC EQU $1005 PORT
C DIRECTION
0044 1008
PORTD EQU $1008 PORT D
DATA - 6 BITS BI & SCI/SPI
0045 1009
DDRD EQU $1009 PORT
D DIRECTION
0046 100a
PORTE EQU $100A PORT E
- INPUT ONLY & A/D
0047 102b
BAUD EQU $102B SCI
BAUD REG
0048 102c
SCCR1 EQU $102C SCI CONTROL
1 REG
0049 102d
SCCR2 EQU $102D SCI CONTROL
2 REG
0050 102e
SCSR EQU $102E SCI
STATUS REG
0051 102f
SCDAT EQU $102F SCI DATA
REG
0052 103a
COPRST EQU $103A COP RESET REG
0053 0024
LOWNOT EQU 36
LOWEST NOTE ON KBD
0054
0055
*****************
0056
* RAM LOCATIONS
0057
*****************
0058
0059 0000
ORG RAM
0060
0061 0000
CHANNL RMB 1
CHANNEL NUMBER
0062 0001
VELOCT RMB 1
VELOCITY
0063 0002
NOTE RMB 1
NOTE NUMBER
0064 0003
PATCH RMB 1
PATCH/PROGRAM NUMBER
0065 0004
CPFLAG RMB 1
FLAG=1 IF WE'RE CHANGING C OR P
0066 0005
DATA RMB 64
KEYBOARD MEMORY
0067
*
bit 7 = 1 if now playing, =0 if silent
0068
*
bit 0: latest key status, 1=down
0069
*
bits 1-6: previous 6 key statuses
0070
0071 00ff
STACK EQU $00FF
0072
0073
****************
0074
* Start and Initialize ports
0075
****************
0076
0077 b600
ORG EEPROM
0078
0079 b600 8e 00 ff
COLDST LDS #STACK
0080 b603 7f 10 04
CLR PORTB SHIFT, NOT LOAD & HIGH
CLOCK
0081 b606 7f 10 05
CLR DDRC PORT C IS ALL INPUT
0082 b609 7f 10 09
CLR DDRD PORT D ALL INPUT (EXC
SERIAL)
0083 b60c 7f 10 0a
CLR PORTE PORT E IS ALL INPUT
0084
0085
**********
0086
* Initialize the SCI serial port
0087
* use $30 for 9600 baud during
testing
0088
* use $20 for 31.25K baud for
final version
0089
**********
0090 b60f ce 10 00
LDX #REG POINT TO REGISTERS
0091 b612 1d 00 80
BCLR PORTA-$1000,X $80 PA7=L FOR MIDI
0092 b615 1c 26 80
BSET PACTL-$1000,X $80 ... AND OUTPUT
0093 b618 86 20
LDAA #$20 SET 31.25K BAUD INTO...
0094 b61a b7 10 2b
STAA BAUD BAUD REGISTER
0095 b61d 86 00
LDAA #$00 SET 8X1, NO WAKEUP
0096 b61f b7 10 2c
STAA SCCR1
0097 b622 86 0c
LDAA #$0C
0098 b624 b7 10 2d
STAA SCCR2 ENABLE
0099 b627 b6 10 2f
LDAA SCDAT CLEAR OUT INPUT PORT
0100
0101
**********
0102
* WARMST - WARM START
0103
**********
0104
0105 b62a b6 10 08
WARMST LDAA PORTD GET PRIMARY CHANNEL
NUMBER
0106 b62d 44
LSRA
SHIFT RIGHT INTO PLACE
0107 b62e 44
LSRA
0108 b62f 97 00
STAA CHANNL
0109 b631 86 70
LDAA #$70
0110 b633 97 01
STAA VELOCT DEFAULT VELOCITY
0111
0112
* LDAA PORTC
IGNORE DIP-8 SWITCH
0113
0114 b635 c6 40
LDAB #64 ERASE THE DATA ARRAY
0115 b637 ce 00 05
LDX #DATA
0116 b63a 6f 00
LOOP1 CLR 0,X
0117 b63c 08
INX
0118 b63d 5a
DECB
0119 b63e 26 fa
BNE LOOP1
0120 b640 7f 00 04
CLR CPFLAG RESET FLAG
0121 b643 bd b7 1c
JSR ALLOFF ALL NOTES OFF
0122
0123
********
0124
*** outer loop to scan entire keyboard once
0125
********
0126
0127 b646 86 55
OULOOP LDAA #$55
0128 b648 b7 10 3a
STAA COPRST RESET COP TIMER
0129 b64b 86 aa
LDAA #$AA
0130 b64d b7 10 3a
STAA COPRST
0131 b650 f6 10 2e
LDAB SCSR CHECK FOR INPUT VELOCITY
0132 b653 c5 20
BITB #$20
0133 b655 27 07
BEQ NOVELO NONE THERE
0134 b657 b6 10 2f
LDAA SCDAT YES, SO GET IT
0135 b65a 84 7f
ANDA #$7F JUST IN CASE
0136 b65c 97 01
STAA VELOCT AND STORE IT
0137 b65e 86 01
NOVELO LDAA #$01
0138 b660 b7 10 04
STAA PORTB LOAD SHIFT REGISTER
0139 b663 7f 10 04
CLR PORTB TURN OFF LOAD
0140 b666 ce 00 45
LDX #DATA+64 POINT PAST DATA ARRAY
0141 b669 86 24
LDAA #LOWNOT
0142 b66b 8b 40
ADDA #64
0143 b66d 97 02
STAA NOTE CURRENT NOTE BEING WORKED
ON+1
0144
0145
********
0146
*** inner loop to process one key
0147
********
0148
0149 b66f 09
INLOOP DEX
POINT TO NEXT ARRAY ELEMENT
0150 b670 8c 00 05
CPX #DATA FINISHED?
0151 b673 2b d1
BMI OULOOP YES, GO RELOAD SHIFT REG
0152 b675 7a 00 02
DEC NOTE CURRENT NOTE BEING WORKED
ON
0153 b678 1e 00 80 23
BRSET 0,X $80 PLAYING BRANCH IF NOTE IS NOW PLAYING
0154
0155
**********
0156
* if note is silent
0157
**********
0158
0159 b67c b6 10 00
SILENT LDAA PORTA CHECK IF KEY IS UP
OR DOWN
0160 b67f 84 01
ANDA #$01
0161 b681 26 13
BNE SILEUP BRANCH IF SILENT AND KEY UP
0162
0163
* if note is not currently playing but key is down
0164
* then immediately play the note
0165
0166 b683 a6 00
SILEDN LDAA 0,X GET THE
BYTE
0167 b685 48
LSLA
SHIFT IT LEFT
0168 b686 8a 81
ORA #$81 SET BITS 7 AND 0
0169 b688 a7 00
STAA 0,X
0170 b68a 8d 4b
BSR NOTEON PLAY THE NOTE
0171
0172 b68c c6 02
SHIFTIT LDAB #$02 SEND OUT SHIFT PULSE
0173 b68e f7 10 04
STAB PORTB TO SHIFT REG
0174 b691 7f 10 04
CLR PORTB
0175 b694 20 d9
BRA INLOOP AND REPEAT FOR NEXT KEY
0176
0177
* if note is silent and key is up, then just store it
0178
0179 b696 a6 00
SILEUP LDAA 0,X GET THE
BYTE
0180 b698 48
LSLA
SHIFTIT LEFT
0181 b699 84 7f
ANDA #$7F CLEAR BIT 7
0182 b69b a7 00
STAA 0,X
0183 b69d 20 ed
BRA SHIFTIT SHIFT REGISTER AND REPEAT
0184
0185
**********
0186
* if note is playing
0187
**********
0188
0189 b69f b6 10 00
PLAYING LDAA PORTA CHECK IF KEY IS UP OR
DOWN
0190 b6a2 84 01
ANDA #$01
0191 b6a4 26 09
BNE PLAYUP BRANCH IF PLAYING AND KEY UP
0192
0193
* if note is currently playing and key is down
0194
* then just store it
0195
0196 b6a6 a6 00
PLAYDN LDAA 0,X GET THE
BYTE
0197 b6a8 48
LSLA
SHIFT IT LEFT
0198 b6a9 8a 81
ORA #$81 SET BITS 7 AND 1
0199 b6ab a7 00
STAA 0,X
0200 b6ad 20 dd
BRA SHIFTIT SHIFT REG AND REPEAT
0201
0202
* if note is playing and key is up, then debounce
0203
0204 b6af a6 00
PLAYUP LDAA 0,X GET THE
BYTE
0205 b6b1 48
LSLA
SHIFTIT LEFT
0206 b6b2 27 06
BEQ SHUTOFF IF IT'S ALL 0, THEN DO NOTE OFF
0207 b6b4 8a 80
ORA #$80 ELSE SET BIT 7
0208 b6b6 a7 00
STAA 0,X STORE IT
0209 b6b8 20 d2
BRA SHIFTIT SHIFT REGISTER AND REPEAT
0210 b6ba a7 00
SHUTOFF STAA 0,X STORE IT
0211 b6bc 8d 02
BSR NOTEOFF
0212 b6be 20 cc
BRA SHIFTIT SHIFT REGISTER AND REPEAT
0213
0214
********
0215
* NOTEOFF - OUTPUT ONE NOTE OFF MESSAGE
0216
* USING CHANNL, NOTE, VEL
0217
* **EXCEPT** TOP C TURNS OFF CPFLAG
0218
********
0219 b6c0 96 02
NOTEOFF LDAA NOTE
0220 b6c2 81 60
CMPA #96 TOP C?
0221 b6c4 26 04
BNE NTOF1 NO
0222 b6c6 7f 00 04
CLR CPFLAG YES, CLR FLAG & QUIT
0223 b6c9 39
RTS
0224 b6ca 86 80
NTOF1 LDAA #$80 NOTEOFF
CODE
0225 b6cc 9b 00
ADDA CHANNL
0226 b6ce 8d 59
BSR OUTEEE NOTEOFF + CHANNEL
0227 b6d0 96 02
LDAA NOTE
0228 b6d2 8d 55
BSR OUTEEE NOTE NUMBER
0229 b6d4 4f
CLRA
0230 b6d5 20 52
BRA OUTEEE VELOCITY = 0
0231
0232
********
0233
* NOTEON - OUTPUT ONE NOTE ON MESSAGE
0234
* USING CHANNL, NOTE, VEL
0235
* **EXCEPT** (A) IF TOP C, SET FLAG,
0236
*
(B) IF FLAG SET, PROCESS C OR P
0237
********
0238 b6d7 96 02
NOTEON LDAA NOTE
0239 b6d9 81 60
CMPA #96 TOP C?
0240 b6db 26 07
BNE NTON1 NO
0241 b6dd 97 04
STAA CPFLAG YES, SET FLAG
0242 b6df 7f 00 03
CLR PATCH CLEAR PATCH MEMORY
0243 b6e2 20 38
BRA ALLOFF ALL NOTES OFF & EXIT
0244
0245 b6e4 7d 00 04
NTON1 TST CPFLAG CHECK THE FLAG
0246 b6e7 27 25
BEQ NOTEOK NORMAL NOTE ON IF CLEAR
0247
0248 b6e9 80 50
SUBA #80 CHECK IF CHANNEL CHANGE
0249 b6eb 24 09
BHS SWCHAN >=80 WAS YES
0250 b6ed 96 02
LDAA NOTE
0251 b6ef 80 24
SUBA #LOWNOT
0252 b6f1 81 0f
CMPA #$F >$F?
0253 b6f3 23 04
BLS CHGPAT
0254 b6f5 39
RTS
IGNORE >16
0255
0256 b6f6 97 00
SWCHAN STAA CHANNL CHANGE CHANNEL
0257 b6f8 39
RTS
AND QUIT
0258
0259 b6f9 d6 03
CHGPAT LDAB PATCH
0260 b6fb 58
LSLB
0261 b6fc 58
LSLB
0262 b6fd 58
LSLB MOVE INTO LEFT NIBBLE
0263 b6fe 58
LSLB
0264 b6ff c4 70
ANDB #$70 ONLY 7 BITS
0265 b701 1b
ABA
COMBINE W PREV DIGIT
0266 b702 97 03
STAA PATCH
0267 b704 86 c0
LDAA #$C0
0268 b706 9b 00
ADDA CHANNL
0269 b708 8d 1f
BSR OUTEEE PROG CHGE CODE
0270 b70a 96 03
LDAA PATCH
0271 b70c 20 1b
BRA OUTEEE AND PATCH NUMBER
0272
0273 b70e 86 90
NOTEOK LDAA #$90 NOTEON CODE
0274 b710 9b 00
ADDA CHANNL
0275 b712 8d 15
BSR OUTEEE NOTEON + CHANNEL
0276 b714 96 02
LDAA NOTE
0277 b716 8d 11
BSR OUTEEE NOTE NUMBER
0278 b718 96 01
LDAA VELOCT
0279 b71a 20 0d
BRA OUTEEE VELOCITY
0280
0281
********
0282
* ALLOFF - ISSUE AN ALL NOTES OFF MSG
0283
********
0284 b71c 86 b0
ALLOFF LDAA #$B0 CONTROLLER CODE
0285 b71e 9b 00
ADDA CHANNL
0286 b720 8d 07
BSR OUTEEE CTRLR + CHANNEL
0287 b722 86 7b
LDAA #123
0288 b724 8d 03
BSR OUTEEE ALL NOTE OFF CODE
0289 b726 4f
CLRA
0290 b727 20 00
BRA OUTEEE LAST BYTE = 0
0291
0292
********
0293
* OUTEEE - ROUTINE TO OUTPUT ONE CHARACTER THRU SERIAL PORT
0294
********
0295 b729 f6 10 2e
OUTEEE LDAB SCSR READ STATUS
0296 b72c c5 80
BITB #$80
0297 b72e 27 f9
BEQ OUTEEE LOOP UNTIL TDRE=1
0298 b730 b7 10 2f
STAA SCDAT SEND CHARACTER
0299 b733 39
RTS
0300
0301 b734 43 4f 50 59 52 49 COPRIT
FCC 'COPYRIGHT (c) 2002, 2006 BY '
47 48 54 20 28 63
29 20 32 30 30 32
2c 20 32 30 30 36
20 42 59 20
0302 b750 50 45 54 45 52 20
FCC 'PETER A. STARK'
41 2e 20 53 54 41
52 4b
0303
0304
END