uint32_t serial_cx_read(uint32_t addr) { switch (addr & 0xFFFF) { case 0x000: if (!(serial_cx.rx & 1)) error("Attempted to read empty RBR"); uint8_t byte = serial_cx.rx_char; serial_cx.rx = 0; serial_cx.int_status &= ~0x10; serial_cx_int_check(); xmodem_next_char(); return byte; case 0x018: return 0x90 & ~(serial_cx.rx << 4); case 0x024: return 0; case 0x028: return 0; case 0x02C: return 0; case 0x040: return serial_cx.int_status & serial_cx.int_mask; case 0x030: return serial_cx.cr; case 0x038: return 0; case 0xFE0: return 0x11; case 0xFE4: return 0x10; case 0xFE8: return 0x14; case 0xFEC: return 0x00; case 0xFF0: return 0x0d; case 0xFF4: return 0xf0; case 0xFF8: return 0x05; case 0xFFC: return 0xb1; } return bad_read_word(addr); }
uint32_t serial_read(uint32_t addr) { switch (addr & 0x3F) { case 0x00: if (serial.LCR & 0x80) return serial.DLL; /* Divisor Latch LSB */ if (!(serial.interrupts & 1)) error("Attempted to read empty RBR"); uint8_t byte = serial.rx_char; serial.interrupts &= ~1; serial_int_check(); xmodem_next_char(); return byte; case 0x04: if (serial.LCR & 0x80) return serial.DLM; /* Divisor Latch MSB */ return serial.IER; /* Interrupt Enable Register */ case 0x08: /* Interrupt Identification Register */ if (serial.interrupts & serial.IER & 1) { return 4; } else if (serial.interrupts & serial.IER & 2) { serial.interrupts &= ~2; serial_int_check(); return 2; } else { return 1; } case 0x0C: /* Line Control Register */ return serial.LCR; case 0x14: /* Line Status Register */ return 0x60 | (serial.interrupts & 1); } return bad_read_word(addr); }
static void xmodem_next_packet() { int len; int i, sum = 0; xmodem_buf[0] = 0x01; xmodem_buf[1]++; // sequence number xmodem_buf[2] = ~xmodem_buf[1]; // sequence number complement len = fread(&xmodem_buf[3], 1, 0x80, xmodem_file); if (len == 0) { serial_byte_in(0x04); fclose(xmodem_file); xmodem_file = NULL; return; } memset(&xmodem_buf[3 + len], 0x1A, 0x80 - len); for (i = 3; i < 0x83; i++) sum += xmodem_buf[i]; xmodem_buf[0x83] = sum; xmodem_buf_pos = 0; xmodem_next_char(); }