Bit8u MPU401_ReadData(void) { /* SOFTMPU */ Bit8u ret=MSG_MPU_ACK; // HardMPU: we shouldn't be running this function if the queue is empty. //if (mpu.queue_used) { if (mpu.queue_pos>=MPU401_QUEUE) mpu.queue_pos-=MPU401_QUEUE; ret=mpu.queue[mpu.queue_pos]; mpu.queue_pos++;mpu.queue_used--; //} if (!mpu.intelligent) return ret; if (ret>=0xf0 && ret<=0xf7) { /* MIDI data request */ mpu.state.channel=ret&7; mpu.state.data_onoff=0; mpu.state.cond_req=false; } if (ret==MSG_MPU_COMMAND_REQ) { mpu.state.data_onoff=0; mpu.state.cond_req=true; if (mpu.condbuf.type!=T_OVERFLOW) { mpu.state.block_ack=true; MPU401_WriteCommand(mpu.condbuf.value[0]); if (mpu.state.command_byte) MPU401_WriteData(mpu.condbuf.value[1]); } mpu.condbuf.type=T_OVERFLOW; } if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { mpu.state.data_onoff=-1; MPU401_EOIHandlerDispatch(); } return ret; }
int main(void) { // init GPIO PORTB = 0b11111000; // bits 0-2 are driven externally DDRB = 0b00011000; // data read and data write latches PORTC = 0b11111111; // pullups enabled PORTD = 0b11111111; // pullups enabled // init UART UCSR0B = (1<<TXEN0);//|(1<<RXEN0); UBRR0 = BAUD_MIDI; // init timer TCCR1B |= (1<<WGM12)|(1<<CS10); // timer1 ctc mode, no prescaler TIMSK1 |= (1<<OCIE1A); // enable ctc interrupt OCR1A = F_CPU / RTCFREQ - 1; // ctc value // init emulator MPU401_Init(); // enable interrupts sei(); while(1) // main loop { // do isa i/o if (QueueUsed() && (~PINB & PIN_DSR)) { send_isa_byte(MPU401_ReadData()); // send data if there's any in the buffer } if (PINB & PIN_CRR) { // isa control input latch is full MPU401_WriteCommand(recv_isa_byte()); } if (PINB & PIN_DRR) { // isa data input latch is full MPU401_WriteData(recv_isa_byte()); } // do midi i/o send_midi_byte(); // see if we need to send a byte /* if (UCSR0A & (1<<RXC0)) { // midi uart rx buffer is full process_midi_byte(); } */ } }
static void mpu401_write(uint16_t addr, uint8_t val, void *p) { mpu_t *mpu = (mpu_t *)p; /* pclog("MPU401 Write Port %04X, val %x\n", addr, val); */ switch (addr & 1) { case 0: /*Data*/ MPU401_WriteData(mpu, val); pclog("Write Data (0x330) %X\n", val); break; case 1: /*Command*/ MPU401_WriteCommand(mpu, val); pclog("Write Command (0x331) %x\n", val); break; } }
uint8_t MPU401_ReadData(mpu_t *mpu) { uint8_t ret; ret = MSG_MPU_ACK; if (mpu->queue_used) { if (mpu->queue_pos>=MPU401_QUEUE) mpu->queue_pos-=MPU401_QUEUE; ret=mpu->queue[mpu->queue_pos]; mpu->queue_pos++;mpu->queue_used--; } if (!mpu->intelligent) return ret; if (mpu->queue_used == 0) picintc(1 << mpu->irq); if (ret>=0xf0 && ret<=0xf7) { /* MIDI data request */ mpu->state.channel=ret&7; mpu->state.data_onoff=0; mpu->state.cond_req=0; } if (ret==MSG_MPU_COMMAND_REQ) { mpu->state.data_onoff=0; mpu->state.cond_req=1; if (mpu->condbuf.type!=T_OVERFLOW) { mpu->state.block_ack=1; MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); if (mpu->state.command_byte) MPU401_WriteData(mpu, mpu->condbuf.value[1]); } mpu->condbuf.type=T_OVERFLOW; } if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { mpu->state.data_onoff=-1; MPU401_EOIHandlerDispatch(mpu); } return ret; }