This page last revised June 12, 2007
The hardware of all four MD-1 cards is identical, but they have slightly different software. On a typical organ, the Pedal interface card (card D) has the basic software, version 1.1. Click here to go to the MD-1 hardware page that describes the actual hardware of the board.
The standard software used on MD-1 card D is listed below, but note that any of the other versions would work just as well since they contain enhancements that are simply not needed or used in the pedal division. (Note: my own organ uses a different software version - see the bottom of this page.)
* MD-1 Keyboard scanner program
* Copyright (C) 2002, 2006 by Peter A. Stark
* This version (a) uses the DIP switch to
set the lowest note
*
(b) does not allow changing channel or program numbers
*
from the keyboard
* Version 1.1 10/24/2006 - mod to reset COP
timer
* Version 1.0 3/13/2005 - minor edits
* Version 0.5 7/22/2002 - original
* I/O bits:
* Inputs
* PA0: Serial input from shift register
* PC7-0: 1st note DIP switch
* PD0: Serial RS232 input
* PE5-2: Channel DIP switch
* PE0: Jumper to ground for Buffalo, but
usable elsewhere too
* Outputs
* PA7: H=RS232 (default), L=MIDI out
* PB0: LOAD/SHIFT' selection line
* PB1: Shift register clock line
* PD1: Serial out to RS232 or MIDI
**************************
* GENERAL SYSTEM EQUATES
**************************
RAM EQU
$0000 START OF RAM
REG EQU
$1000 START OF REGISTERS
EEPROM EQU $B600
START OF EEPROM
ENDEEP EQU $B7FF
END OF EEPROM
PORTA EQU $1000
PORT A DATA & TIMER - B7=BI, B6-3=O,B2-1=I
PACTL EQU $1026
PORT A CONTROL
PORTB EQU $1004
PORT B DATA - OUTPUT ONLY
PORTC EQU $1003
PORT C DATA - BI
DDRC EQU $1005
PORT C DIRECTION
PORTD EQU $1008
PORT D DATA - 6 BITS BI & SCI/SPI
DDRD EQU $1009
PORT D DIRECTION
PORTE EQU $100A
PORT E - INPUT ONLY & A/D
BAUD EQU $102B
SCI BAUD REG
SCCR1 EQU $102C
SCI CONTROL 1 REG
SCCR2 EQU $102D
SCI CONTROL 2 REG
SCSR EQU $102E
SCI STATUS REG
SCDAT EQU $102F
SCI DATA REG
COPRST EQU $103A
*****************
* RAM LOCATIONS
*****************
ORG RAM
CHANNL RMB 1
CHANNEL NUMBER
NOTE RMB 1
NOTE NUMBER
LOWNOT RMB 1
FIRST (LOWEST) NOTE
DATA RMB 64
KEYBOARD MEMORY
*
bit 7 = 1 if now playing, =0 if silent
*
bit 0: latest key status, 1=down
*
bits 1-6: previous 6 key statuses
STACK EQU $00FF
****************
* Start and Initialize ports
****************
ORG EEPROM
COLDST LDS #STACK
CLR PORTB SHIFT, NOT LOAD & HIGH
CLOCK
CLR DDRC PORT C IS ALL INPUT
CLR DDRD PORT D ALL INPUT (EXC
SERIAL)
CLR PORTE PORT E IS ALL INPUT
**********
* Initialize the SCI serial port
*
use $30 for 9600 baud during testing
*
use $20 for 31.25K baud for final version
**********
LDX #REG POINT TO REGISTERS
BCLR PORTA-$1000,X $80 PA7=L FOR MIDI
BSET PACTL-$1000,X $80 ... AND OUTPUT
LDAA #$20 SET 31.25K BAUD INTO...
STAA BAUD BAUD REGISTER
LDAA #$00 SET 8X1, NO WAKEUP
STAA SCCR1
LDAA #$0C
STAA SCCR2 ENABLE
**********
* WARMST - WARM START
**********
WARMST LDAA PORTD
GET CHANNEL NUMBER
LSRA
SHIFT RIGHT INTO PLACE
LSRA
STAA CHANNL
LDAA PORTC GET LOWEST (FIRST) NOTE
ANDA #$7F MAX IS 127
STAA LOWNOT
LDAB #64 ERASE THE DATA ARRAY
LDX #DATA
LOOP1 CLR 0,X
INX
DECB
BNE LOOP1
LDAB #127 ISSUE 128 NOTE OFFS
STAB NOTE PUT NOTE NUMBER IN NOTE
LOOP2 BSR NOTEOFF
DEC NOTE
BPL LOOP2
********
*** outer loop to scan entire keyboard once
********
OULOOP LDAA #$55
STAA COPRST RESET COP TIMER
LDAA #$AA
STAA COPRST
LDAA #$01
STAA PORTB LOAD SHIFT REGISTER
CLR PORTB TURN OFF LOAD
LDX #DATA+64 POINT PAST DATA ARRAY
LDAA LOWNOT
ADDA #64
STAA NOTE CURRENT NOTE BEING WORKED
ON+1
********
*** inner loop to process one key
********
INLOOP DEX
POINT TO NEXT ARRAY ELEMENT
CPX #DATA FINISHED?
BMI OULOOP YES, GO RELOAD SHIFT REG
DEC NOTE CURRENT NOTE BEING WORKED
ON
BRSET 0,X $80 PLAYING BRANCH IF NOTE IS NOW PLAYING
**********
* if note is silent
**********
SILENT LDAA PORTA
CHECK IF KEY IS UP OR DOWN
ANDA #$01
BNE SILEUP BRANCH IF SILENT AND KEY UP
* if note is not currently playing but key
is down
* then immediately play the note
SILEDN LDAA 0,X
GET THE BYTE
LSLA
SHIFT IT LEFT
ORA #$81 SET BITS 7 AND 0
STAA 0,X
BSR NOTEON PLAY THE NOTE
SHIFTIT LDAB #$02
SEND OUT SHIFT PULSE
STAB PORTB TO SHIFT REG
CLR PORTB
BRA INLOOP AND REPEAT FOR NEXT KEY
* if note is silent and key is up, then just store it
SILEUP LDAA 0,X
GET THE BYTE
LSLA
SHIFTIT LEFT
ANDA #$7F CLEAR BIT 7
STAA 0,X
BRA SHIFTIT SHIFT REGISTER AND REPEAT
**********
* if note is playing
**********
PLAYING LDAA PORTA
CHECK IF KEY IS UP OR DOWN
ANDA #$01
BNE PLAYUP BRANCH IF PLAYING AND KEY UP
* if note is currently playing and key is
down
* then just store it
PLAYDN LDAA 0,X
GET THE BYTE
LSLA
SHIFT IT LEFT
ORA #$81 SET BITS 7 AND 1
STAA 0,X
BRA SHIFTIT SHIFT REG AND REPEAT
* if note is playing and key is up, then debounce
PLAYUP LDAA 0,X
GET THE BYTE
LSLA
SHIFTIT LEFT
BEQ SHUTOFF IF IT'S ALL 0, THEN DO NOTE OFF
ORA #$80 ELSE SET BIT 7
STAA 0,X STORE IT
BRA SHIFTIT SHIFT REGISTER AND REPEAT
SHUTOFF STAA 0,X
STORE IT
BSR NOTEOFF
BRA SHIFTIT SHIFT REGISTER AND REPEAT
********
* NOTEOFF - OUTPUT ONE NOTE OFF
MESSAGE
* USING CHANNL, NOTE,
VEL
********
NOTEOFF LDAA #$80
NOTEOFF CODE
ADDA CHANNL
BSR OUTEEE NOTEOFF + CHANNEL
LDAA NOTE
BSR OUTEEE NOTE NUMBER
CLRA
BRA OUTEEE VELOCITY
********
* NOTEON - OUTPUT ONE NOTE ON
MESSAGE
* USING CHANNL, NOTE,
VEL
********
NOTEON LDAA #$90
NOTEON CODE
ADDA CHANNL
BSR OUTEEE NOTEON + CHANNEL
LDAA NOTE
BSR OUTEEE NOTE NUMBER
LDAA #$70
BRA OUTEEE VELOCITY
********
* OUTEEE - ROUTINE TO OUTPUT
ONE CHARACTER THRU SERIAL PORT
********
OUTEEE LDAB SCSR
READ STATUS
BITB #$80
BEQ OUTEEE LOOP UNTIL TDRE=1
STAA SCDAT SEND CHARACTER
RTS
COPRIT FCC 'COPYRIGHT (c) 2002, 2006
BY '
FCC 'PETER A. STARK'
END
As of June 10, 2007, I plan to change this software to a new version 1.1PT. The code that follows is the beta version of this new code -- it may change if any bugs are discovered. The new software will let this board output MIDI messages on two channels.
My Schober organ has 48 stop tabs plus 11 combination buttons (ten plus a general cancel) mounted below the accomp keyboard, which all connect to MD-1 board C, for a total of 59 used inputs. That MD-1 board has room for 64 inputs, so there is a total of 5 left over unused. But the Virginia WurtliTzer organ for Hauptwerk 2 has many more stops, pistons, toy counter, and other controls than that, so I need more inputs.
Each MD-1 board has room for 64 inputs, but the pedal board only uses 25 of those for the Schober Theater console, or 32 for a full AGO console. The other 32 could be used for stops etc., but they need to output a different channel number so they don't play notes.
The new software thus supports two channels: One channel for the lowest 32 inputs (normally used for pedals, and selected by the 4-bit DIP switch on the board, as usual), and a second channel for the top 32 inputs (used for other inputs, and selected by the least significant four bits of the 8-bit DIP switch on the board). The pedal outputs will start at note 36 (hex 24) as is normal; the combo outputs will start at note 0, so they can overlap with other control signals on the same channel.
At this time, I have an extra set of 15 buttons mounted below the solo keyboard, as shown in this view.
There may be more in the future as well, such as a small box with indicators and buttons on the cheekblock. I am planning ahead by changing the software. Since each set of 32 inputs has its own 34-pin ribbon cable and connector, future additions will thus be possible without any other software changes.
The new code follows:
* MD-1 Keyboard scanner program
* Special version PT for the pedal and comb.
buttons
* Copyright (C) 2002, 2007 by Peter A. Stark
* This version (a) does NOT use the DIP switch
to set the lowest note -
*
defaults to low note = 36 (two oct below middle C)
*
for the pedal channel only
*
(b) does not allow changing channel or program numbers
*
from the keyboard
*
(c) Outputs on two different channels:
*
(1) The bottom 32 notes (mainly pedal) output on the
*
channel set by the DIP-4 switch
*
(2) The top 32 notes (comb. buttons etc.) output on
*
channel set by the low 4 bits of the DIP-8 switch
*
They also output note numbers 0 through 31
* Version 1.1PT revised 6/12/2007 for note
number change
* Version 1.1PT 3/29/2007 - mod for pedal/comb
button use
* Version 1.1 10/24/2006 - mod to reset COP
timer
* Version 1.0 3/13/2005 - minor edits
* Version 0.5 7/22/2002 - original
* I/O bits:
* Inputs
* PA0: Serial input from shift register
* PC7-0: former 1st note DIP switch, now
2nd channel
* PD0: Serial RS232 input
* PE5-2: Channel DIP switch
* PE0: Jumper to ground for Buffalo, but
usable elsewhere too
* Outputs
* PA7: H=RS232 (default), L=MIDI out
* PB0: LOAD/SHIFT' selection line
* PB1: Shift register clock line
* PD1: Serial out to RS232 or MIDI
**************************
* GENERAL SYSTEM EQUATES
**************************
RAM EQU
$0000 START OF RAM
REG EQU
$1000 START OF REGISTERS
EEPROM EQU $B600
START OF EEPROM
ENDEEP EQU $B7FF
END OF EEPROM
PORTA EQU $1000
PORT A DATA & TIMER - B7=BI, B6-3=O,B2-1=I
PACTL EQU $1026
PORT A CONTROL
PORTB EQU $1004
PORT B DATA - OUTPUT ONLY
PORTC EQU $1003
PORT C DATA - BI
DDRC EQU $1005
PORT C DIRECTION
PORTD EQU $1008
PORT D DATA - 6 BITS BI & SCI/SPI
DDRD EQU $1009
PORT D DIRECTION
PORTE EQU $100A
PORT E - INPUT ONLY & A/D
BAUD EQU $102B
SCI BAUD REG
SCCR1 EQU $102C
SCI CONTROL 1 REG
SCCR2 EQU $102D
SCI CONTROL 2 REG
SCSR EQU $102E
SCI STATUS REG
SCDAT EQU $102F
SCI DATA REG
COPRST EQU $103A
LOWNOT EQU 36
LOWEST NOTE ON KBD
*****************
* RAM LOCATIONS
*****************
ORG RAM
PCHANL RMB 1
PEDAL CHANNEL NUMBER
TCHANL RMB 1
COMB BUTTON CHANNEL NUMBER
CHANNL RMB 1
CURRENT CHANNEL TO USE
NOTE RMB 1
KEYBOARD NOTE NUMBER
DATA RMB 64
KEYBOARD MEMORY
*
bit 7 = 1 if now playing, =0 if silent
*
bit 0: latest key status, 1=down
*
bits 1-6: previous 6 key statuses
STACK EQU $00FF
****************
* Start and Initialize ports
****************
ORG EEPROM
COLDST LDS #STACK
CLR PORTB SHIFT, NOT LOAD & HIGH
CLOCK
CLR DDRC PORT C IS ALL INPUT
CLR DDRD PORT D ALL INPUT (EXC
SERIAL)
CLR PORTE PORT E IS ALL INPUT
**********
* Initialize the SCI serial port
*
use $30 for 9600 baud during testing
*
use $20 for 31.25K baud for final version
**********
LDX #REG POINT TO REGISTERS
BCLR PORTA-$1000,X $80 PA7=L FOR MIDI
BSET PACTL-$1000,X $80 ... AND OUTPUT
LDAA #$20 SET 31.25K BAUD INTO...
STAA BAUD BAUD REGISTER
LDAA #$00 SET 8X1, NO WAKEUP
STAA SCCR1
LDAA #$0C
STAA SCCR2 ENABLE
**********
* WARMST - WARM START
**********
WARMST LDAA PORTD
GET PEDAL CHANNEL NUMBER
LSRA
SHIFT RIGHT INTO PLACE
LSRA
STAA PCHANL
LDAA PORTC GET COMBO CHANNEL NO
ANDA #$0F USE LOW FOUR BITS
STAA TCHANL
LDAB #64 ERASE THE DATA ARRAY
LDX #DATA
LOOP1 CLR 0,X
INX
DECB
BNE LOOP1
LDAA PCHANL
JSR ALLOFF ALL NOTES OFF FOR PEDAL
LDAA TCHANL
JSR ALLOFF ALL NOTES OFF FOR COMBO
********
*** outer loop to scan entire keyboard once
********
OULOOP LDAA #$55
STAA COPRST RESET COP TIMER
LDAA #$AA
STAA COPRST
LDAA #$01
STAA PORTB LOAD SHIFT REGISTER
CLR PORTB TURN OFF LOAD
LDX #DATA+64 POINT PAST DATA ARRAY
LDAA #32 DOING COMBO BUTTONS
FIRST
STAA NOTE CURRENT NOTE BEING WORKED
ON+1
LDAA TCHANL TOP NOTES ARE COMBO BUTTONS
STAA CHANNL
********
*** inner loop to process one key
********
INLOOP DEX
POINT TO NEXT ARRAY ELEMENT
CPX #DATA FINISHED?
BMI OULOOP YES, GO RELOAD SHIFT REG
DEC NOTE CURRENT NOTE BEING WORKED
ON
BPL CONTNU CONTINUE UNLESS NEGATIVE
LDAA PCHANL IF -1 SWITCH TO PEDAL CHANNEL
STAA CHANNL
LDAA #LOWNOT
ADDA #31 SWITCH TO PEDAL NOTES
STAA NOTE
CONTNU BRSET 0,X $80 PLAYING BRANCH
IF NOTE IS NOW PLAYING
**********
* if note is silent
**********
SILENT LDAA PORTA
CHECK IF KEY IS UP OR DOWN
ANDA #$01
BNE SILEUP BRANCH IF SILENT AND KEY UP
* if note is not currently playing but key
is down
* then immediately play the note
SILEDN LDAA 0,X
GET THE BYTE
LSLA
SHIFT IT LEFT
ORA #$81 SET BITS 7 AND 0
STAA 0,X
BSR NOTEON PLAY THE NOTE
SHIFTIT LDAB #$02
SEND OUT SHIFT PULSE
STAB PORTB TO SHIFT REG
CLR PORTB
BRA INLOOP AND REPEAT FOR NEXT KEY
* if note is silent and key is up, then just store it
SILEUP LDAA 0,X
GET THE BYTE
LSLA
SHIFTIT LEFT
ANDA #$7F CLEAR BIT 7
STAA 0,X
BRA SHIFTIT SHIFT REGISTER AND REPEAT
**********
* if note is playing
**********
PLAYING LDAA PORTA
CHECK IF KEY IS UP OR DOWN
ANDA #$01
BNE PLAYUP BRANCH IF PLAYING AND KEY UP
* if note is currently playing and key is
down
* then just store it
PLAYDN LDAA 0,X
GET THE BYTE
LSLA
SHIFT IT LEFT
ORA #$81 SET BITS 7 AND 1
STAA 0,X
BRA SHIFTIT SHIFT REG AND REPEAT
* if note is playing and key is up, then debounce
PLAYUP LDAA 0,X
GET THE BYTE
LSLA
SHIFTIT LEFT
BEQ SHUTOFF IF IT'S ALL 0, THEN DO NOTE OFF
ORA #$80 ELSE SET BIT 7
STAA 0,X STORE IT
BRA SHIFTIT SHIFT REGISTER AND REPEAT
SHUTOFF STAA 0,X
STORE IT
BSR NOTEOFF
BRA SHIFTIT SHIFT REGISTER AND REPEAT
********
* NOTEOFF - OUTPUT ONE NOTE OFF
MESSAGE
* USING CHANNL, NOTE,
VEL
********
NOTEOFF LDAA #$80
NOTEOFF CODE
ADDA CHANNL
BSR OUTEEE NOTEOFF + CHANNEL
LDAA NOTE
BSR OUTEEE NOTE NUMBER
CLRA
BRA OUTEEE VELOCITY = 0
********
* NOTEON - OUTPUT ONE NOTE ON
MESSAGE
* USING CHANNL, NOTE,
VEL
********
NOTEON LDAA #$90
NOTEON CODE
ADDA CHANNL
BSR OUTEEE NOTEON + CHANNEL
LDAA NOTE
BSR OUTEEE NOTE NUMBER
LDAA #$70 DEFAULT
BRA OUTEEE VELOCITY
********
* ALLOFF - ISSUE AN ALL
NOTES OFF MSG - ENTER WITH CHANNEL IN A
********
ALLOFF ADDA #$B0
CONTROLLER CODE
BSR OUTEEE CTRLR + CHANNEL
LDAA #123
BSR OUTEEE ALL NOTE OFF CODE
CLRA
BRA OUTEEE LAST BYTE = 0
********
* OUTEEE - ROUTINE TO OUTPUT
ONE CHARACTER THRU SERIAL PORT
********
OUTEEE LDAB SCSR
READ STATUS
BITB #$80
BEQ OUTEEE LOOP UNTIL TDRE=1
STAA SCDAT SEND CHARACTER
RTS
COPRIT FCC 'COPYRIGHT (c) 2002-2007
BY '
FCC 'PETER A. STARK'
END