title 'MIDI-Keyboard software for 8051' ;(c) copyright 1996 by: Nico Coesel ;interrupt vectors org 0 ljmp start ;external interrupt 0 org 3 reti ;timer 0 org 0bh reti ;extern interrupt 1 org 13h reti ;timer 1 org 1bh reti ;serial interface org 23h reti ;************************************************** ;equates ;constants datofs equ 30h ;************************************************** ;start code ;initialize org 100h start: ;interrupts ;reset values will do the job (no interrupt enabled) ;timer 1 for 31.25kbaud mov pcon,#128 mov tmod,#00100010B mov th1,#255 mov tl1,#255 setb tcon.6 ;start timer 1 ;serial interface mov scon,#01000010B ;set serial mode and preset TI bit ;init key tags mov r1,#datofs mov r0,#44 inidat: mov @r1,#0 inc r1 djnz r0,inidat ;test data area, output adress with failure mov r1,#datofs mov r0,#44 tstdat: mov p1,r0 cjne @r1,#0,tstdat inc r1 djnz r0,tstdat ;init 8051 for operation mov p1,#255 ;*************************************************** ;key scan ;init new scan nscan: mov r1,#datofs ;set data offset mov r6,#41 ;note offset mov r4,#0 ;lower keys mov r0,#0 ;select lower rows acall scan22 ;upper keys mov r0,#20 mov r4,#0 acall scan22 ljmp nscan ;******************************************************** ;subroutines ;scan 22 notes scan22: mov r5,#22 scanloop: mov a,r4 ;move adres into a mov p1,a ;output adress orl p1,#240 ;set high nibble of p1 ;select 0..15 or 16..24 decoder setb c ;set p3.5 mov p3.5,c mov a,r4 ;p3.5 must be zero? anl a,#0f0h jnz p35one clr c ;p3.5 must be zero! mov p3.5,c p35one: ;p3.5 must be one! ;read and process the key nop ;small delay to allow settling of the signals nop nop ;process data cjne r0,#0,high mov c,p3.0 ;get data lower keys ljmp decode high: mov c,p3.2 ;get data higher keys cpl p3.3 decode: jnc nul ;check if data is 0 or 1 ;0=key is pressed, newly pressed ;1=key is not pressed, released mov a,@r1 orl a,#0 ;set flags jz nextkey ;tag=0 => key is not pressed ;get midi channel mov a,p1 ;read port 0 cpl a anl a,#240 ;cut off lower nibble rl a rl a rl a rl a ;turn key off orl a,#80h ;note off combined with channel number acall sendbyte mov a,r6 ;note number acall sendbyte mov a,#0 ;velocity acall sendbyte mov @r1,#0 ;not =off ljmp nextkey nul: ;key is newly pressed or still pressed mov a,@r1 orl a,#0 jnz nextkey ;tag=1 => key already pressed ;get midi channel mov a,p1 ;read port 0 cpl a anl a,#240 ;cut off lower nibble rl a rl a rl a rl a ;Send MIDI data ;r6 contains the number of the key to be send. ;a contains channel number orl a,#90h ;note on message combined with channel no. acall sendbyte mov a,r6 ;note number acall sendbyte mov a,#70 ;velocity acall sendbyte mov @r1,#1 ;note =on nextkey: ;ready with this key inc r1 ;datofs(tag adresses) inc r6 ;increment key inc r4 ;adress counter djnz r5,nscanloop ret nscanloop: ljmp scanloop ;send a byte to midi ;input in a sendbyte: jnb scon.1,sendbyte clr scon.1 mov sbuf,a ret end