Blanks Off ;----------------------------------------------- ; ; Imported addresses ; ;----------------------------------------------- print off INCLUDE 'gcb.aii' INCLUDE 'Note.Macros' INCLUDE 'E16.NoteSyn' INCLUDE 'ns.equ' INCLUDE 'E16.MIDI' print on, nogen, nomdir, nohdr **************************************************************** * * NoteOff Tool Call * * Inputs: GenNum, Semitone * * Output: none * * This routine is reentrant: thou shalt not use scratch RAM * **************************************************************** EXPORT NoteOff NoteOff PROC longi on longa on SGenNum equ 9 * stack frame at entry Semitone equ 7 * RTL 1 4 * RTL 2 1 **************************************************************** * This routine uses the DP to point directly to the GCB it is using. * That means direct addressing takes an extra cycle, but its worth it. * Compute the gcb adress so that we have some workspace: tax ; check the z status flag. bne @1 ; if not equal we were started. ldx #nsNotInit ; otherwize we weren't startedd, jmp error ; return error and exit. @1 php sei ; no irq just yet! pha ; save my DP a moment lda SGenNum+3,s and #$000F ; qualify the gennum a bit tax asl a asl a ; mul by 16 to get gcb offset asl a asl a adc 1,s ; add offset to my DP ply ; and fix stack phd ; now push OLD DP tcd ; and install mine phb ; push user data bank too! mem_short lda >cubbyhole+2 pha plb ; install my data bank. * The stack is now 4 up from entry level; gennum is in x. lda gcb_ID ; is it still my gen? and #$000f cmp #my_ID bne exit4 lda gcb_semitone and #$007F ; is it still playing cmp Semitone+4,s ; the same note? bne exit4 * If we get here, then we have the gen in question. We now have * to send it into its release stage, which involves the envelope; * and jimmy the priority, to make it more stealable. * The stack is now 4 up from entry level. Memory is short. x has gen num. index short ldy #vcb_release_seg ; set envelope stage to lda (gcb_vcb),y ; release asl a ; each segment is 3 bytes. adc (gcb_vcb),y ldy #vcb_current_seg sta (gcb_vcb),y mem_long lda gcb_env_cur ; this will cause the env sta gcb_env_lim ; to go to the next stage lda #1 sta gcb_env_inc * Now we have to decrease the priority by half. both long pei gcb_vcb ; were up 6 again, saving this pointer lda >cubbyhole ; get the priority table back sta gcb_vcb lda Sgennum+6,s tay mem_short lda (gcb_vcb),y ; get priority lsr a sta (gcb_vcb),y ; and stick it in the table mem_long pla sta gcb_vcb ; restore my pointer **************************************************************** * restore the registers, fix the stack, and get out! exit4 plb ; get old data bank (1) pld ; get old direct reg (2) plp ; get old irq status ldx #0 ; no error. longa on longi on error lda 5,s sta 9,s pla sta 3,s pla sta 3,s ; wierd but it works txa ; get error code. cmp #1 ; set carry flag if error. rtl ; return happy ENDP eject **************************************************************** * * AllNotesOff * * Inputs: none * * Outputs: none * **************************************************************** * EXPORT AllNotesOff AllNotesOff PROC * for generator = 0 to num_of_gen-1 * if ID = note synth * dealloc generator * endif * next generator * endif longi on longa on **************************************************************** * Get my DP area and my workarea pointers * tax ; set the status regester. bne @1 ; if not equal then we're started. ldx #nsNotInit ; otherwize we aren't started. jmp error ; and return error and exit. @1 php sei phd ; save old dp tcd mem_short phb ; save the callers bank. lda myram_ptr+2 ; get my bank pha ; and put on stack. plb ; pull bank. * Stack is up 4. memory is short. D and b are set. **************************************************************** * * Repeat Loop. * * DP will be the Loop counter, incremented by 16's. * y will also count through the priority table. * memory is short index is long ; for rom ldy #priority_table must be replaced. lda >myram_ptr+1 ; get the priority table address. xba lda >myram_ptr tay ; and put in y. LOOP lda gcb_ID and #$0F cmp #my_ID bne not_note stz gcb_ID ; clear the ID byte lda gcb_doc clc adc #doc_ctrl sta >GAdrL lda >SysVol ora #GPtrInc sta >GStatReg lda #doc_halt_reset sta >GDataReg sta >GDataReg ; halt both oscillators lda #0 sta |0,y ; zero priority not_note iny tdc ; ( do this with 8 bit acc? ) clc adc #gcb_size ; advance direct page to next gcb tcd cmp #$40 ; time for first poll of midi. bne @1 ; if not go on. ; poll midi and save regesters. phx phy pha php both long jsl MIDIInputPoll ; poll midi. longa off plp pla ply plx ; restore regesters @1 cmp #$C0 ; time for second poll of midi. bne @2 ; if not go on. ; poll midi and save regesters. phx phy pha php both long jsl MIDIInputPoll ; poll midi. longa off plp pla ply plx ; restore regesters @2 cmp #gcb_size*num_of_gen bne loop **************************************************************** * Now leave the way we came, restoring registers. plb pld plp ;( both long, irq as before) ldx #0 ; no error. longa on longi on error txa ; get error code. cmp #1 ; set the carry flag. rtl ENDP ; append update.src -- this line is very silly since the file ; is copied at the top level anyways END