📄 dv-mn103ser.c
字号:
} else { hw_abort (me, "bad read size of %d bytes from SC%dRXB.", nr_bytes, serial_reg); }}static voidread_status_reg (struct hw *me, struct mn103ser *serial, unsigned_word serial_reg, void *dest, unsigned nr_bytes){ char c; int count; if ( (serial->device[serial_reg].status & SIO_STAT_RRDY) == 0 ) { /* FIFO is empty */ /* Kill current poll event */ if ( NULL != serial->device[serial_reg].event ) { hw_event_queue_deschedule (me, serial->device[serial_reg].event); serial->device[serial_reg].event = NULL; } if(USE_SOCKSER_P) { int rd; rd = dv_sockser_read (hw_system (me)); if(rd != -1) { c = (char) rd; count = 1; } else { count = HW_IO_NOT_READY; } } else { count = do_hw_poll_read (me, serial->reader, 0/*STDIN*/, &c, sizeof(c)); } switch (count) { case HW_IO_NOT_READY: case HW_IO_EOF: serial->device[serial_reg].rxb = 0; serial->device[serial_reg].status &= ~SIO_STAT_RRDY; break; default: serial->device[serial_reg].rxb = c; serial->device[serial_reg].status |= SIO_STAT_RRDY; hw_port_event (me, serial_reg+SERIAL0_RECEIVE, 1); } /* schedule polling event */ serial->device[serial_reg].event = hw_event_queue_schedule (me, 1000, do_polling_event, (void *) (long) serial_reg); } if ( nr_bytes == 1 ) { *(unsigned8 *)dest = (unsigned8)serial->device[serial_reg].status; } else if ( nr_bytes == 2 && serial_reg != SC2STR ) { *(unsigned16 *)dest = H2LE_2 (serial->device[serial_reg].status); } else { hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes, serial_reg); }}static voidread_serial2_timer_reg (struct hw *me, struct mn103ser *serial, void *dest, unsigned nr_bytes){ if ( nr_bytes == 1 ) { * (unsigned8 *) dest = (unsigned8) serial->serial2_timer_reg; } else { hw_abort (me, "bad read size of %d bytes to SC2TIM.", nr_bytes); }}static unsignedmn103ser_io_read_buffer (struct hw *me, void *dest, int space, unsigned_word base, unsigned nr_bytes){ struct mn103ser *serial = hw_data (me); enum serial_register_types serial_reg; HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); serial_reg = decode_addr (me, serial, base); switch (serial_reg) { /* control registers */ case SC0CTR: case SC1CTR: case SC2CTR: read_control_reg(me, serial, serial_reg-SC0CTR, dest, nr_bytes); HW_TRACE ((me, "read - ctrl reg%d has 0x%x\n", serial_reg-SC0CTR, *(unsigned8 *)dest)); break; /* interrupt mode registers */ case SC0ICR: case SC1ICR: case SC2ICR: read_intmode_reg(me, serial, serial_reg-SC0ICR, dest, nr_bytes); HW_TRACE ((me, "read - intmode reg%d has 0x%x\n", serial_reg-SC0ICR, *(unsigned8 *)dest)); break; /* transmission buffers */ case SC0TXB: case SC1TXB: case SC2TXB: read_txb(me, serial, serial_reg-SC0TXB, dest, nr_bytes); HW_TRACE ((me, "read - txb%d has %c\n", serial_reg-SC0TXB, *(char *)dest)); break; /* reception buffers */ case SC0RXB: case SC1RXB: case SC2RXB: read_rxb(me, serial, serial_reg-SC0RXB, dest, nr_bytes); HW_TRACE ((me, "read - rxb%d has %c\n", serial_reg-SC0RXB, *(char *)dest)); break; /* status registers */ case SC0STR: case SC1STR: case SC2STR: read_status_reg(me, serial, serial_reg-SC0STR, dest, nr_bytes); HW_TRACE ((me, "read - status reg%d has 0x%x\n", serial_reg-SC0STR, *(unsigned8 *)dest)); break; case SC2TIM: read_serial2_timer_reg(me, serial, dest, nr_bytes); HW_TRACE ((me, "read - serial2 timer reg %d\n", *(unsigned8 *)dest)); break; default: hw_abort(me, "invalid address"); } return nr_bytes;} static voidwrite_control_reg (struct hw *me, struct mn103ser *serial, unsigned_word serial_reg, const void *source, unsigned nr_bytes){ unsigned16 val = LE2H_2 (*(unsigned16 *)source); /* really allow 1 byte write, too */ if ( nr_bytes == 2 ) { if ( serial_reg == 2 && (val & 0x0C04) != 0 ) { hw_abort(me, "Cannot write to read-only bits of SC2CTR."); } else { serial->device[serial_reg].control = val; } } else { hw_abort (me, "bad read size of %d bytes from SC%dSTR.", nr_bytes, serial_reg); }}static voidwrite_intmode_reg (struct hw *me, struct mn103ser *serial, unsigned_word serial_reg, const void *source, unsigned nr_bytes){unsigned8 val = *(unsigned8 *)source; if ( nr_bytes == 1 ) { /* Check for attempt to write to read-only bits of register. */ if ( ( serial_reg == 2 && (val & 0xCA) != 0 ) || ( serial_reg != 2 && (val & 0x4A) != 0 ) ) { hw_abort(me, "Cannot write to read-only bits of SC%dICR.", serial_reg); } else { serial->device[serial_reg].intmode = val; } } else { hw_abort (me, "bad write size of %d bytes to SC%dICR.", nr_bytes, serial_reg); }}static voidwrite_txb (struct hw *me, struct mn103ser *serial, unsigned_word serial_reg, const void *source, unsigned nr_bytes){ if ( nr_bytes == 1 ) { serial->device[serial_reg].txb = *(unsigned8 *)source; if(USE_SOCKSER_P) { dv_sockser_write(hw_system (me), * (char*) source); } else { sim_io_write_stdout(hw_system (me), (char *)source, 1); sim_io_flush_stdout(hw_system (me)); } hw_port_event (me, serial_reg+SERIAL0_SEND, 1); } else { hw_abort (me, "bad write size of %d bytes to SC%dTXB.", nr_bytes, serial_reg); }}static voidwrite_serial2_timer_reg (struct hw *me, struct mn103ser *serial, const void *source, unsigned nr_bytes){ if ( nr_bytes == 1 ) { serial->serial2_timer_reg = *(unsigned8 *)source; } else { hw_abort (me, "bad write size of %d bytes to SC2TIM.", nr_bytes); }}static unsignedmn103ser_io_write_buffer (struct hw *me, const void *source, int space, unsigned_word base, unsigned nr_bytes){ struct mn103ser *serial = hw_data (me); enum serial_register_types serial_reg; HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); serial_reg = decode_addr (me, serial, base); switch (serial_reg) { /* control registers */ case SC0CTR: case SC1CTR: case SC2CTR: HW_TRACE ((me, "write - ctrl reg%d has 0x%x, nrbytes=%d.\n", serial_reg-SC0CTR, *(unsigned8 *)source, nr_bytes)); write_control_reg(me, serial, serial_reg-SC0CTR, source, nr_bytes); break; /* interrupt mode registers */ case SC0ICR: case SC1ICR: case SC2ICR: HW_TRACE ((me, "write - intmode reg%d has 0x%x, nrbytes=%d.\n", serial_reg-SC0ICR, *(unsigned8 *)source, nr_bytes)); write_intmode_reg(me, serial, serial_reg-SC0ICR, source, nr_bytes); break; /* transmission buffers */ case SC0TXB: case SC1TXB: case SC2TXB: HW_TRACE ((me, "write - txb%d has %c, nrbytes=%d.\n", serial_reg-SC0TXB, *(char *)source, nr_bytes)); write_txb(me, serial, serial_reg-SC0TXB, source, nr_bytes); break; /* reception buffers */ case SC0RXB: case SC1RXB: case SC2RXB: hw_abort(me, "Cannot write to reception buffer."); break; /* status registers */ case SC0STR: case SC1STR: case SC2STR: hw_abort(me, "Cannot write to status register."); break; case SC2TIM: HW_TRACE ((me, "read - serial2 timer reg %d (nrbytes=%d)\n", *(unsigned8 *)source, nr_bytes)); write_serial2_timer_reg(me, serial, source, nr_bytes); break; default: hw_abort(me, "invalid address"); } return nr_bytes;} const struct hw_descriptor dv_mn103ser_descriptor[] = { { "mn103ser", mn103ser_finish, }, { NULL },};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -