Het Basiamo-duo spande samen met Kristof Lauwers om een werkstuk klaar te krijgen onder de titel "Springs and Strings". Sebastian Bradt orkestreerde naast delen uit Strawinsky's Canticum Sacrum, ook enkele waanzinnige fugas van Godfried-Willem Raes. Ook de Australische komponist Warren Burt schreef enkele gloednieuwe stukken voor zowel als voor de player piano. ---- Wat de gloednieuwe -robot zoal in petto heeft, kon U in vorig Logos Blad reeds lezen. Een deel van de literaire schoonheid die het wezen uitmaakt van de besturing van deze nieuwe robotelg willen we onze lezers toch niet onthouden: Main: setf LATA ; Address strobes high clrf LATB ; All outputs low - data port setf LATC ; All outputs low - adresses clrf TRISA ; Config PORTA as all outputs clrf TRISB ; Config PORTB as all outputs movlw 0x80 ; movwf TRISC ; Config PORTC all outputs + tristate for serial rx movlw 0x07 ; init adc movwf ADCON1 ; init adc clrf ADCON0 ; poweroff adc clrf TRISA ; Config PORTA again as all outputs setf LATA ; Address strobes high clrf LATB ; All outputs low - data port setf LATC ; All outputs low nop nop ; 1 to 4 microseconds hold nop clrf LATA ; strobe low clrf LATB ; data low nop nop ; 1 to 4 microseconds hold. nop setf LATA ; Address strobes high setf LATC ; All outputs low clrf ExtLatAData; clrf ExtLatBData; clrf ExtLatCData; clrf ExtLatDData; clrf ExtLatEData; clrf ExtLatFData; clrf ExtLatGData; clrf ExtLatHData; clrf ExtLatIData; movlw 03Fh; movwf ExtLatAAddrA; movlw 00Ch; movwf ExtLatAAddrC; movlw 03Fh; movwf ExtLatBAddrA; movlw 00Ah; movwf ExtLatBAddrC; movlw 03Fh; movwf ExtLatCAddrA; movlw 006h; movwf ExtLatCAddrC; movlw 03Eh; movwf ExtLatIAddrA; movlw 00Eh; movwf ExtLatIAddrC; movlw 03Dh; movwf ExtLatHAddrA; movlw 00Eh; movwf ExtLatHAddrC; movlw 03Bh; movwf ExtLatGAddrA; movlw 00Eh; movwf ExtLatGAddrC; movlw 037h; movwf ExtLatFAddrA; movlw 00Eh; movwf ExtLatFAddrC; movlw 02Fh; movwf ExtLatEAddrA; movlw 00Eh; movwf ExtLatEAddrC; movlw 01Fh; movwf ExtLatDAddrA; movlw 00Eh; movwf ExtLatDAddrC; movlw ExtLatAData; movwf Fifo0LatPtr; movlw ExtLatBData; movwf Fifo1LatPtr; movlw ExtLatCData; movwf Fifo2LatPtr; movlw ExtLatDData; movwf Fifo3LatPtr; movlw ExtLatEData; movwf Fifo4LatPtr; movlw ExtLatFData; movwf Fifo5LatPtr; movlw ExtLatGData; movwf Fifo6LatPtr; movlw ExtLatHData; movwf Fifo7LatPtr; movlw ExtLatIData; movwf Fifo8LatPtr; movlw ExtLatAData; movwf Fifo9LatPtr; movlw ExtLatBData; movwf Fifo10LatPtr; movlw ExtLatCData; movwf Fifo11LatPtr; movlw ExtLatDData; movwf Fifo12LatPtr; movlw ExtLatEData; movwf Fifo13LatPtr; movlw ExtLatFData; movwf Fifo14LatPtr; movlw ExtLatGData; movwf Fifo15LatPtr; ; pwm init movlw 0x80; movwf PR2; movlw 0x00; movwf CCPR1L; movlw 0x01; movwf TMR2; movlw 0x04; movwf T2CON; movlw 0x0C; movwf CCP1CON; bsf LATC,0 ; Light error LED on powerup ; Wait a second with ALoop and BLoop setf TmpM BLoop1: movlw 0xff; ALoop1: decfsz WREG; goto ALoop1 decfsz TmpM; goto BLoop1 bcf LATC,0 ; Been patient enough, dim error LED and start movlw Fifo0LatPtr; movwf FifoRdIndx; movlw Fifo5LatPtr; movwf FifoWrIndx; lfsr FSR0 ,0000h lfsr FSR1 ,0000h rcall SetupSerial ;set up serial port and buffers rcall SetupTimer3 MainLoop: call PollMidiIn; bra MainLoop ;go wait for more data ;---------------------------------------------------------------------------- ;Set up serial port and buffers. SetupSerial: movlw 0x80 ;set tris bits for Tx and RX iorwf TRISC,F movlw SPBRG_VAL ;set baud rate movwf SPBRG movlw 0x04 ;no transmission, high baud rate ;0x24 ;enable transmission and high baud rate movwf TXSTA movlw 0x90 ;enable serial port and reception movwf RCSTA clrf Flags ;clear all flags rcall InitTxBuffer ;initialize transmit buffer rcall InitRxBuffer ;initialize receive buffer movlw 0x30 ;enable Tx and Rx interrupts movwf PIE1 movlw 0x00 ;set Rx low and Tx low priority movwf IPR1 bsf RCON,IPEN ;enable interrupt priorities movlw 0xc0 ;enable global high and low ints movwf INTCON return ;---------------------------------------------------------------------------- ;Circular buffer routines. InitRxBuffer: movlw HIGH RxBuffer ;take high address of receive buffer movwf RxStartPtrH ;and place in receive start pointer movwf RxEndPtrH ;and place in receive end pointer movlw LOW RxBuffer ;take low address of receive buffer movwf RxStartPtrL ;and place in receive start pointer movwf RxEndPtrL ;and place in receive end pointer bcf Flags,RxBufFull ;indicate Rx buffer is not full bsf Flags,RxBufEmpty ;indicate Rx buffer is empty return ;Add a byte (in WREG) to the end of the receive buffer. PutRxBuffer: btfsc Flags,RxBufFull ;check if receive buffer full bra ErrRxBufFull ;go handle error if full movff RxEndPtrH,FSR0H ;put EndPointer into FSR0 movff RxEndPtrL,FSR0L ;put EndPointer into FSR0 movwf POSTINC0 ;copy data to buffer ;test if buffer pointer needs to wrap around to beginning of buffer memory movlw HIGH (RxBuffer+RX_BUF_LEN) ;get last address of buffer cpfseq FSR0H ;and compare with end pointer bra PutRxBuf1 ;skip low bytes if high bytes not equal movlw LOW (RxBuffer+RX_BUF_LEN) ;get last address of buffer cpfseq FSR0L ;and compare with end pointer bra PutRxBuf1 ;go save new pointer if not at end lfsr 0,RxBuffer ;point to beginning of buffer if at end PutRxBuf1: movff FSR0H,RxEndPtrH ;save new EndPointer high byte movff FSR0L,RxEndPtrL ;save new EndPointer low byte ;test if buffer is full movf RxStartPtrH,W ;get start pointer cpfseq RxEndPtrH ;and compare with end pointer bra PutRxBuf2 ;skip low bytes if high bytes not equal movf RxStartPtrL,W ;get start pointer cpfseq RxEndPtrL ;and compare with end pointer bra PutRxBuf2 bsf Flags,RxBufFull ;if same then indicate buffer full PutRxBuf2: bcf Flags,RxBufEmpty ;Rx buffer cannot be empty return ErrRxBufFull: return ;no save of data because buffer is full ;Remove and return (in WREG) the byte at the start of the receive buffer. GetRxBuffer: bcf PIE1,RCIE ;disable Rx interrupt to avoid conflict btfsc Flags,RxBufEmpty ;check if receive buffer empty bra ErrRxBufEmpty ;go handle error if empty movff RxStartPtrH,FSR0H ;put StartPointer into FSR0 movff RxStartPtrL,FSR0L ;put StartPointer into FSR0 movff POSTINC0,TempRxData ;save data from buffer ;test if buffer pointer needs to wrap around to beginning of buffer memory movlw HIGH (RxBuffer+RX_BUF_LEN) ;get last address of buffer cpfseq FSR0H ;and compare with start pointer bra GetRxBuf1 ;skip low bytes if high bytes not equal movlw LOW (RxBuffer+RX_BUF_LEN) ;get last address of buffer cpfseq FSR0L ;and compare with start pointer bra GetRxBuf1 ;go save new pointer if at end lfsr 0,RxBuffer ;point to beginning of buffer if at end GetRxBuf1: movff FSR0H,RxStartPtrH ;save new StartPointer value movff FSR0L,RxStartPtrL ;save new StartPointer value ;test if buffer is now empty movf RxEndPtrH,W ;get end pointer cpfseq RxStartPtrH ;and compare with start pointer bra GetRxBuf2 ;skip low bytes if high bytes not equal movf RxEndPtrL,W ;get end pointer cpfseq RxStartPtrL ; and compare with start pointer bra GetRxBuf2 bsf Flags,RxBufEmpty ;if same then indicate buffer empty GetRxBuf2: bcf Flags,RxBufFull ;Rx buffer cannot be full movf TempRxData,W ;restore data from buffer bsf PIE1,RCIE ;enable receive interrupt return ErrRxBufEmpty: bsf PIE1,RCIE ;enable receive interrupt retlw 0 ;buffer empty, return zero SetupTimer3: movlw 0x01 movwf T3CON ; timer3 on, other bits cleared bsf IPR2,1 ; timer3 = high priority interrupt bsf PIE2,1 ; timer3 interrupt enable return Timer3ISR: bcf PIR2,TMR3IF ; clear interrupt flag movlw 0E0h ;0x7F; 0xA0 movwf TMR3L ; preset timer setf TMR3H ; preset timer movf LatWriteState,0; bz T3ISRProcessFifo; decf WREG; bz T3ISR_LWS1; decf WREG; bz T3ISR_LWS2; decf WREG; bz T3ISR_LWS3; decf WREG; setf ErrorLed; clrf LatWriteState; bra T3ISRProcessFifo; T3ISR_LWS1: incf LatWriteState movff TISRData,LATB; bra TISRDone; T3ISR_LWS2: incf LatWriteState movff TISRAddrA,LATA; movff TISRAddrC,LATC; bra TISRDone; T3ISR_LWS3: clrf LatWriteState movlw 00Fh; movwf LATA; movlw 070h; movwf LATC; bra TISRDone; T3ISRProcessFifo: lfsr FSR0 ,0000h movf FifoRdIndx, W; subwf FifoWrIndx, W ; result in w bz TISRDone; no new task on cmd queue movff FifoRdIndx, FSR0L; incf FifoRdIndx; bnz NoWrap; movlw Fifo0LatPtr; Wrap to start movwf FifoRdIndx; NoWrap: movf INDF0, 0; W = ExtLatPtr movwf FSR0L; movff POSTINC0,TISRData; movff POSTINC0,TISRAddrA; movff POSTINC0,TISRAddrC; movlw 1; movwf LatWriteState; TISRDone: bra EndHighInt ; resume ; MIDI Input parser PollMidiIn: btfsc Flags,RxBufEmpty ;check if Rx buffer is empty return ;if so then return rcall GetRxBuffer ;get data from receive buffer MidiInParser: movwf MidiInByte; btfss MidiInByte,7; bra MidiInData; ; jump if it wasn't a status byte movwf MidiByte0; MidiInStatus: movlw 0; clrf MidiCurData; btfss MidiByte0,6; bra MidiInStatus2words; btfss MidiByte0,5; movlw 1; movwf MidiNumData; bra MidiInStatusEnd; MidiInStatus2words: movlw 2; movwf MidiNumData; MidiInStatusEnd: return MidiInData: tstfsz MidiCurData; bra MidiInDataM2; bra MidiInDataM1; MidiInDataM2: ; 2nd byte movff MidiInByte,MidiByte2; clrf MidiCurData; bra MidiInAction2Bytes; MidiInDataM1: movff MidiInByte,MidiByte1; incf MidiCurData,1; movf MidiCurData,0; subwf MidiNumData,0; bz MidiInAction1Byte; return; MidiInAction1Byte: return; MidiInAction2Bytes: movlw 098h; noteOn, ch 8 - dec. 152 subwf MidiByte0,0; bz MidiInNoteOn; movlw 088h; noteOff, ch 8 - dec. 136 subwf MidiByte0,0; bz MidiInNoteOff; movlw 0B8h; cc, ch 8 - not used on Ake Pic1 subwf MidiByte0,0; bz MidiInCC; return; MidiInNoteOn: ;************** ; lookup timer #, read from table in PM:0Fvv movf MidiByte2,0; bz MidiInNoteOff; ; velocity=0 -> NOTE OFF movlw 10h; movwf TBLPTRH; page = note number to latch pointer table MOVFF MidiByte1,TBLPTRL TBLRD* ; read into TABLAT movf TABLAT,0 bz MidiInNoteOn2; movwf TmpT ; TmpT = Latch pointer ; modify data with OR mask lfsr FSR2 ,0000h movff TmpT, FSR2L; incf TBLPTRH; page = note number to OR mask table TBLRD* ; read into TABLAT movf TABLAT,0; iorwf INDF2; ; add to fifo movff FifoWrIndx, FSR2L; movff TmpT,POSTINC2; ; update FifoWrIndex movf FSR2L,0; bz NoWrap2; corrected: was: bnz movff FSR2L, FifoWrIndx; return NoWrap2 movlw Fifo0LatPtr; Wrap to start movwf FifoWrIndx; return MidiInNoteOff: ;************** ; lookup timer #, read from table in PM:0Fvv movlw 10h; movwf TBLPTRH; page = note number to latch pointer table MOVFF MidiByte1,TBLPTRL TBLRD* ; read into TABLAT movf TABLAT,0 bz MidiInNoteOff2; movwf TmpT ; TmpT = Latch pointer ; modify data with OR mask lfsr FSR2 ,0000h movff TmpT, FSR2L; incf TBLPTRH; page = note number to OR mask table incf TBLPTRH; page = note number to AND mask table TBLRD* ; read into TABLAT movf TABLAT,0; andwf INDF2; ; add to fifo movff FifoWrIndx, FSR2L; movff TmpT,POSTINC2; ; update FifoWrIndex movf FSR2L,0; bz NoWrap3; corrected: was: bnz movff FSR2L, FifoWrIndx; return NoWrap3 movlw Fifo0LatPtr; Wrap to start movwf FifoWrIndx; return MidiInNoteOn2 return MidiInNoteOff2 return MidiInCC movlw 0x7B; CC NotesOff, ch F subwf MidiByte1,0; bz MidiInCCAllNotesOff; return MidiInCCAllNotesOff: clrf ExtLatAData; clrf ExtLatBData; clrf ExtLatCData; clrf ExtLatDData; clrf ExtLatEData; clrf ExtLatFData; movlw ExtLatAData; movwf Fifo0LatPtr; movlw ExtLatBData; movwf Fifo1LatPtr; movlw ExtLatCData; movwf Fifo2LatPtr; movlw ExtLatDData; movwf Fifo3LatPtr; movlw ExtLatEData; movwf Fifo4LatPtr; movlw ExtLatFData; movwf Fifo5LatPtr; movlw ExtLatAData; movwf Fifo6LatPtr; movlw Fifo0LatPtr; movwf FifoRdIndx; movlw Fifo6LatPtr; movwf FifoWrIndx; movlw Fifo0LatPtr; movwf FifoRdIndx; movlw Fifo6LatPtr; movwf FifoWrIndx; return ;************************************************************* ; latch pointer per note Mapping for - checked gwr. 19.09.2004 ; must have bugs... org 1000h ; NoteLatchPtr: DB 0,0,0,0,0,0,0,0; 0..7 DB 0,0,0,0,0,0,0,0; 8..15 DB 0 , 0 ,0 ,ExtLatAData,ExtLatAData,ExtLatAData,ExtLatAData,ExtLatAData; 16..23 19-23 DB ExtLatAData,ExtLatAData,ExtLatAData,ExtLatBData,ExtLatBData,ExtLatBData,ExtLatBData,ExtLatBData; 24..31 DB ExtLatBData,ExtLatBData,ExtLatBData,ExtLatCData,ExtLatCData,ExtLatCData,ExtLatCData,ExtLatCData; 32..39 DB ExtLatCData,ExtLatCData,ExtLatCData, 0 ,0 ,0 ,0 ,0 ; 40..47 40-42 DB 0 ,ExtLatDData,ExtLatDData,ExtLatDData,ExtLatDData,ExtLatDData,ExtLatDData,ExtLatDData; 48..55 49-55 DB ExtLatDData,ExtLatEData,ExtLatEData,ExtLatEData,ExtLatEData,ExtLatEData,ExtLatEData,ExtLatEData; 56..63 56-63 DB ExtLatEData,ExtLatFData,ExtLatFData,ExtLatFData,ExtLatFData,ExtLatFData,ExtLatFData,ExtLatFData; 64..71 64-71 DB ExtLatFData,ExtLatGData,ExtLatGData,ExtLatGData,ExtLatGData,ExtLatGData,ExtLatGData,ExtLatGData; 72..79 72-79 DB ExtLatGData,ExtLatHData,ExtLatHData,ExtLatHData,ExtLatHData,ExtLatHData,ExtLatHData,ExtLatHData; 80..87 80-87 DB ExtLatHData,ExtLatIData,ExtLatIData,ExtLatIData,ExtLatIData,ExtLatIData,ExtLatIData,ExtLatIData; 88..95 88-94 95=light DB ExtLatIData,0,0,0,0,0,0,0; 96.. 96=light DB 0,0,0,0,0,0,0,0; 104.. DB 0,0,0,0,0,0,0,0; 112.. DB 0,0,0,0,0,0,0,0; 120..127 org 1100h ; NoteLatchOnOrMask: DB 0,0,0,0,0,0,0,0; 0..7 DB 0,0,0,0,0,0,0,0; 8.. DB 0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x08; 16.. 'klopt dit wel? DB 0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08; 24.. DB 0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00; 32.. DB 0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x02; 40.. DB 0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02; 48.. DB 0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02; 56.. DB 0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02; 64.. DB 0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02; 72.. DB 0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02; 80.. DB 0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02; 88.. DB 0x01,0,0,0,0,0,0,0; 96.. DB 0,0,0,0,0,0,0,0; 104.. DB 0,0,0,0,0,0,0,0; 112.. DB 0,0,0,0,0,0,0,0; 120..127 org 1200h ; NoteLatchOffAndMask: DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF; 0..7 DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF; 8.. DB 0xFF,0xFF,0xFF,0x7F,0xBF,0xDB,0xE7,0xF7; 16.. DB 0xFB,0xFD,0xFE,0x7F,0xBF,0xDB,0xE7,0xF7; 24.. DB 0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF; 32.. DB 0x00,0x7F,0xBF,0xDB,0xE7,0xF7,0xFB,0xFD; 40.. DB 0xFE,0x7F,0xBF,0xDB,0xE7,0xF7,0xFB,0xFD; 48.. DB 0xFE,0x7F,0xBF,0xDB,0xE7,0xF7,0xFB,0xFD;56.. DB 0xFE,0x7F,0xBF,0xDB,0xE7,0xF7,0xFB,0xFD; 64.. DB 0xFE,0x7F,0xBF,0xDB,0xE7,0xF7,0xFB,0xFD; 72.. DB 0xFE,0x7F,0xBF,0xDB,0xE7,0xF7,0xFB,0xFD; 80.. DB 0xFE,0x7F,0xBF,0xDB,0xE7,0xF7,0xFB,0xFD; 88.. DB 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF; 96.. DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF; 104.. DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF; 112.. DB 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF; 120..127 END Deze PIC kode werd geredigeerd door Johannes Taelman terwijl Godfried-Willem Raes in het grootste geheim aan het werk is aan alweer een nieuwe robot die zal worden gedoopt. Voor meer informatie daarover moet de lezer toch wachten tot een van onze volgende Logos bladen.