; Title : Sweetener ; Version : 1.0 ; Created : 1998.10.04 ; Last updated : 1998.12.10 ; Target : AT90S2313 ; File : sweetnr.asm ; Author : Dave Keenan .nolist .include "2313def.inc" ;I/O port and bit definitions .list ;UART pins .equ RX =PD0 ;UART receive pin .equ TX =PD1 ;UART transmit pin ;Rows and columns of LED matrix .equ ROW0 =PD6 ;Top .equ ROW1 =PD5 .equ ROW2 =PD4 .equ ROW3 =PD3 .equ ROW4 =PD2 ;Bottom .equ ROW_MASK=0b01111100 .equ COL0 =PB6 ;Left .equ COL1 =PB5 .equ COL2 =PB4 .equ COL3 =PB3 .equ COL4 =PB2 .equ COL5 =PB1 .equ COL6 =PB0 Right .equ COL_MASK=0b01111111 .equ MCU_CLK =12000000 ; Hz .equ UART_RATE =31250 ; b/s (for MIDI) .equ TUNING_MSG_ADDR =$60 ; Start of SRAM .equ TUNING_MSG_SIZE =22 .equ TUNING_MSG_ADDRESS_ADDR =TUNING_MSG_ADDR+5 .equ TUNING_MSG_DATA_ADDR =TUNING_MSG_ADDR+8 .equ TUNING_MSG_CHECKSUM_ADDR=TUNING_MSG_ADDR+20 .equ SCALE_FIFTHS_ADDR =$00 .equ SCALE_FIFTHS_SIZE =7 .def scaleFifth0 =r0 .def scaleFifth1 =r1 .def scaleFifth2 =r2 .def scaleFifth3 =r3 .def scaleFifth4 =r4 .def scaleFifth5 =r5 .def scaleFifth6 =r6 .def minFifth =r7 .def maxFifth =r8 .def twiceMid =r9 .def oldTwiceMid =r10 .def oldMidFifth =r11 .def savedSREG =r12 .def status =r14 .def note =r15 .def velocity =r16 .def state =r17 .equ OTHER_STATE =0 .equ NOTE_STATE =1 .equ VELOCITY_STATE =2 .def pos =r18 ;Must not be used in interrupt routine .def rows =r19 ;Must not be used in interrupt routine .def midFifth =r20 .def offset =r21 .def delta =r21 .def temp3 =r22 ;Must not be used in interrupt routine .def temp2 =r23 .def temp =r24 ;r26..r31 are index regs X,Y,Z, But XL,XH,YH (r26,r27,r29) are not used yet. ;Reset and interrupt vectors (must be the first code generated) rjmp RESET ; Reset handler rjmp EXT_INT0 ; External interrupt0 (pin 6, PD2) handler rjmp EXT_INT1 ; External interrupt0 (pin 7, PD3) handler rjmp TIM_CAPT1 ; Timer1 capture Handler rjmp TIM_COMP1 ; Timer1 compare Handler rjmp TIM_OVF1 ; Timer1 overflow Handler rjmp TIM_OVF0 ; Timer0 overflow Handler rjmp UART_RXC ; UART RX Complete Handler rjmp UART_DRE ; UDR Empty Handler rjmp UART_TXC ; UART TX Complete Handler ;rjmp ANA_COMP ; Analog Comparator Handler ;Initial values for the tuning message (to be copied from flash to RAM). INITIAL_TUNING_MSG: ;If there's an odd number of bytes after a .db in program memory ; it gets padded to the next word boundary, even if the next line is a .db. .db $F0,$41 ;System exclusive message header ;Manufacturer ID: Roland $41, Yamaha $43 .db $10,$42 ;Device ID: default for XP-10 $10(17) ;Model ID: GS $42, XP-10 $7B .db $12,$40 ;Command ID: Set data $12 ;Address MSB .db $11,$40 ;Address 2SB, $1x where x is part (voice) number 1..9,0,A..F = 1..16 ;Address LSB ;Although D is the middle fifth for this tuning, we make A have zero offset ; so we still obey the A 440Hz standard. .db $40+(-2*-100-85)/31, $40+( 5*-100-85)/31 ;C Offset in cents 0..$7F = -64..63 ;C# .db $40+( 0*-100-85)/31, $40+(-5*-100-85)/31 ;D ;Eb .db $40+( 2*-100-85)/31, $40+(-3*-100-85)/31 ;E ;F .db $40+( 4*-100-85)/31, $40+(-1*-100-85)/31 ;F# ;G .db $40+( 6*-100-85)/31, $40+( 1*-100-85)/31 ;G# ;A .db $40+(-4*-100-85)/31, $40+( 3*-100-85)/31 ;Bb ;B .db $22,$F7 ;Checksum ;System Exclusive message terminator EXT_INT0: ; External interrupt0 (pin 6, PD2) handler EXT_INT1: ; External interrupt0 (pin 7, PD3) handler TIM_CAPT1: ; Timer1 capture Handler TIM_COMP1: ; Timer1 compare Handler TIM_OVF1: ; Timer1 overflow Handler TIM_OVF0: ; Timer0 overflow Handler UART_DRE: ; UDR Empty Handler UART_TXC: ; UART TX Complete Handler ANA_COMP: ; Analog Comparator Handler ; UART receive-complete handler UART_RXC: in savedSREG,SREG in temp,UDR ;Send realtime messages immediately cpi temp,$F0 brlo END_REALTIME SEND_BYTE: sbis USR,UDRE ;Wait for UART data reg empty rjmp PC-1 out UDR,temp rjmp END_UART_RXC END_REALTIME: ;State machine tst temp brmi CASE_OTHER ;We will eventually get a status byte when in the NOTE state CASE_NOTE: cpi state,NOTE_STATE brne CASE_VEL ldi state,VELOCITY_STATE mov note,temp rjmp END_UART_RXC CASE_VEL: cpi state,VELOCITY_STATE brne CASE_OTHER ldi state,NOTE_STATE mov velocity,temp tst velocity breq END_ADAPT ;Zero velocity is same as note-off mov temp,note rcall NOTE_TO_FIFTH rcall ADAPT_FOR_FIFTH END_ADAPT: sbis USR,UDRE ;Wait for UART data reg empty rjmp PC-1 out UDR,status sbis USR,UDRE ;Wait for UART data reg empty rjmp PC-1 out UDR,note sbis USR,UDRE ;Wait for UART data reg empty rjmp PC-1 out UDR,velocity rjmp END_UART_RXC CASE_OTHER: mov temp2,temp andi temp2,$F0 cpi temp2,$90 ldi state,OTHER_STATE ;Since we may come here when we're actually in NOTE_STATE brne SEND_BYTE ; if a status byte is received instead of note data. ldi state,NOTE_STATE mov status,temp END_UART_RXC: out SREG,savedSREG reti ;Main program start RESET: ;Init stack pointer before calling subroutines or enabling interrupts ldi temp,RAMEND out SPL,temp ;Set the display row and column pins as outputs ldi temp,COL_MASK out DDRB,temp ldi temp,ROW_MASK out DDRD,temp ;Init 8 bit timer ldi temp,(1<= oldTwiceMid ... brlt END_ADJUST_MID breq TWICE_MID_EQ rjmp DEC_MIDFIFTH TWICE_MID_EQ: ;If twiceMid = oldTwiceMid ... mov offset,temp2 ;Get the fifth we are adapting for sub offset,midFifth ;sub offset,twiceMid/2 cpi offset,-2 breq DEC_MIDFIFTH cpi offset,-3 brne END_ADJUST_MID DEC_MIDFIFTH: dec midFifth END_ADJUST_MID: cpi midFifth,-9 brge END_IF_LT_MI9 subi midFifth,-12 ;addi midFifth,12 rcall SHIFT_SCALE_UP_12 rjmp END_IF_GE_11 END_IF_LT_MI9: cpi midFifth,11 brlt END_IF_GE_11 subi midFifth,12 rcall SHIFT_SCALE_DOWN_12 END_IF_GE_11: mov delta,midFifth sub delta,oldMidFifth breq END_IF_DELTA_NE rcall SHIFT_KEYS rcall SEND_TUNING_MSG END_IF_DELTA_NE: ret ;---------------------------------------------------- ;Test routines SEND_NOTES_OFF: ldi temp,$90 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$3C ;C4 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$00 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$3D ;C#4 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$00 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$43 ;G4 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$00 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$44 ;G#4 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$00 out UDR,temp sbis USR,UDRE rjmp PC-1 ret SEND_NOTE_ON1: ldi temp,$90 ;Channel in low nible 0..F = 1..16 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$3C ;C4 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$40 out UDR,temp sbis USR,UDRE rjmp PC-1 ret SEND_NOTE_ON2: ldi temp,$90 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$3D ;C#4 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$40 out UDR,temp sbis USR,UDRE rjmp PC-1 ret SEND_NOTE_ON3: ldi temp,$90 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$43 ;G4 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$40 out UDR,temp sbis USR,UDRE rjmp PC-1 ret SEND_NOTE_ON4: ldi temp,$90 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$44 ;G#4 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$40 out UDR,temp sbis USR,UDRE rjmp PC-1 ret SEND_TUNING_TABLE1: ldi temp,$F0 ;System exclusive message header out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$41 ;Manufacturer ID: Roland $41, Yamaha $43 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$10 ;Device ID: default for XP-10 $10(17) out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$42 ;Model ID: GS $42, XP-10 $7B out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$12 ;Command ID: Set data $12 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$40 ;Address MSB out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$11 ;Address 2SB, $1x where x is part (voice) number 1..9,0,A..F = 1..16 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$40 ;Address LSB out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;C offset in cents 0..$7F = -64..63 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;C# out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;D out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;D# out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;E out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;F out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;F# out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;G out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;G# out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;A out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;Bb out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;B out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$80-(($40+$11+$40+$72+$72+$72+$0E+$72+$0E+$72+$72+$72+$0E+$72+$0E)&$7F) ;Checksum out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$F7 ;System Exclusive message terminator out UDR,temp sbis USR,UDRE rjmp PC-1 ret SEND_TUNING_TABLE2: ldi temp,$F0 ;System exclusive message header out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$41 ;Manufacturer ID: Roland $41, Yamaha $43 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$10 ;Device ID: default for XP-10 $10(17) out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$42 ;Model ID: GS $42, XP-10 $7B out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$12 ;Command ID: Set data $12 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$40 ;Address MSB out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$11 ;Address 2SB, $1x where x is part (voice) number out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$40 ;Address LSB out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;C offset in cents 0..$7F = -64..63 out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;C# out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;D out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;D# out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;E out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;F out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;F# out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;G out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;G# out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;A out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$0E ;Bb out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$72 ;B out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$80-(($40+$11+$40+$0E+$0E+$0E+$72+$0E+$72+$0E+$72+$0E+$72+$0E+$72)&$7F) ;Checksum out UDR,temp sbis USR,UDRE rjmp PC-1 ldi temp,$F7 ;System Exclusive message terminator out UDR,temp sbis USR,UDRE rjmp PC-1 ret