MD-1 cards A and C - Keyboard MIDI converters


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