midifun2.S
以下はアセンブラ部分のソースですが、プリプロセッサを通すためにファイル名のエクステンションは「.S」(英大文字の「エス」) にする必要があります。
;/*************************************************/ ;/* midifun2.S : MIDI functions (asm part) */ ;/* for ATtiny10 */ ;/* */ ;/* 2012/01/16 : Created by pcm1723 */ ;/*************************************************/ #include <avr/io.h> #include "m2c_tn10.h" ; ; void calc_pitch(int8_t gate_flag) ; ; arg1 -- int8_t gate_flag : 0 != GATE ON, 0 == GATE intact ; .global calc_pitch .func calc_pitch #define ROUND_CONST 0x20 calc_pitch: ldi ZL,lo8(ch_prop+1) ; ch_prop[0].MD_bend[0] ldi ZH,hi8(ch_prop+1) ; ch_prop[0].MD_bend[0] ld r21,Z+ ld r22,Z+ ; R22:R21 = ch_prop[0].MD_bend lsl r21 rol r22 ; R22:R21 <<= 1 sbc r23,r23 ; R23 <-- sign extension of R22:R21 lds r25,ch_prop+3 ; LIER (R25) = ch_prop[0].MD_bend_range clr r31 clr r30 clr r19 ; clear SUM (R31:R30:R19) ; calc_p1: lsl r21 rol r22 rol r23 ; CAND (R23:R22:R21) <<= 1 calc_p2: lsr r25 ; b0 of LIER (R25) --> C brcc calc_p3 ; don't add CAND add r19,r21 adc r30,r22 adc r31,r23 ; SUM (R31:R30:R19) += CAND (R23:R22:R21) calc_p3: tst r25 ; LIER (R25) == 0 ? brne calc_p1 ; loop again ; subi r30,lo8(-ROUND_CONST) ; fraction part sbci r31,hi8(-ROUND_CONST) ; rounding lds r19,ch_prop ; R19 = ch_prop[0].MD_note add r31,r19 ; add integer part clr r23 ; upper byte (b15..b8) lsl r30 rol r31 rol r23 lsl r30 rol r31 rol r23 ; R23:R31:R30 <<= 2 out _SFR_IO_ADDR(OCR0AH),r23 out _SFR_IO_ADDR(OCR0AL),r31 ; OCR0A duty register tst r24 ; test for GATE ON flag breq calc_p_ret ; immediate return lds r24,unit_prop+2 ; R24 = hi8(nit_prop[0].gate_que) ori r24,0x80 ; GATE ON flag sts unit_prop+2,r24 ; update GATE queue calc_p_ret: ret .endfunc ; ; void pitch_bend( void ) ; .global pitch_bend .func pitch_bend pitch_bend: clr r24 ; no GATE manipulation rjmp calc_pitch ; tail merge to 'calc_pitch()' .endfunc ; ; void midi_note_on(uint8_t MD_2nd, uint8_t MD_3rd) ; ; arg1 -- int8_t MD_2nd : MIDI note number ; ; arg2 -- int8_t MD_3rd : MIDI velocity (unused) ; .func midi_note_on .global midi_note_on midi_note_on: sts ch_prop,r24 ; ch_prop[0].MD_note = MD_2nd lds r24,unit_prop ; R24 = unit_prop[0].on_cnt subi r24,-1 ; R24 += 1 sts unit_prop,r24 ; unit_prop[0].on_cnt = R24 ldi r24,-1 ; GATE ON flag rjmp calc_pitch ; tail merge to 'calc_pitch()' .endfunc