static void schedule_ready_event(device *me, ide_controller *controller) { if (controller->event_tag != 0) device_error(me, "controller %d - attempting to schedule multiple events", controller->nr); controller->event_tag = device_event_queue_schedule(me, controller->ready_delay, do_event, controller); }
static void write_com(device *me, hw_com_device *com, unsigned_word a, char val) { unsigned_word addr = a % 8; /* the divisor latch is special */ if (com->reg[3] & 0x8 && addr < 2) { com->dlab[addr] = val; return; } switch (addr) { case 0: /* fifo */ if (com->output.file == NULL) { sim_io_write_stdout(&val, 1); } else { fwrite(&val, 1, 1, com->output.file); } /* setup for next write */ if (com->output.ready && com->output.delay > 0) { com->output.ready = 0; device_event_queue_schedule(me, com->output.delay, make_write_ready, me); } break; default: com->reg[addr] = val; break; } update_com_interrupts(me, com); }
static void read_com(device *me, hw_com_device *com, unsigned_word a, char val[1]) { unsigned_word addr = a % 8; /* the divisor latch is special */ if (com->reg[3] & 0x8 && addr < 2) { *val = com->dlab[addr]; return; } switch (addr) { case 0: /* fifo */ if (!com->modem.carrier) *val = '\0'; if (com->input.ready) { /* read the char in */ if (com->input.file == NULL) { if (sim_io_read_stdin(val, 1) < 0) com->modem.carrier_changed = 1; } else { if (fread(val, 1, 1, com->input.file) == 0) com->modem.carrier_changed = 1; } /* setup for next read */ if (com->modem.carrier_changed) { /* once lost carrier, never ready */ com->modem.carrier = 0; com->input.ready = 0; *val = '\0'; } else if (com->input.delay > 0) { com->input.ready = 0; device_event_queue_schedule(me, com->input.delay, make_read_ready, me); } } else { /* discard it? */ /* overflow input fifo? */ *val = '\0'; } break; case 2: /* interrupt ident */ if (com->interrupting) { if (com->input.interrupting) *val = 0x4; else if (com->output.interrupting) *val = 0x2; else if (com->modem.interrupting == 0) *val = 0; else device_error(me, "bad elif for interrupts\n"); } else *val = 0x1; break; case 5: /* line status */ *val = ((com->input.ready ? 0x1 : 0) | (com->output.ready ? 0x60 : 0) ); break; case 6: /* modem status */ *val = ((com->modem.carrier_changed ? 0x08 : 0) | (com->modem.carrier ? 0x80 : 0) ); com->modem.carrier_changed = 0; break; default: *val = com->reg[addr]; break; } update_com_interrupts(me, com); }