static void m68hc11sio_info (struct hw *me) { SIM_DESC sd; uint16 base = 0; sim_cpu *cpu; struct m68hc11sio *controller; uint8 val; long clock_cycle; sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); sim_io_printf (sd, "M68HC11 SIO:\n"); base = cpu_get_io_base (cpu); val = cpu->ios[M6811_BAUD]; print_io_byte (sd, "BAUD ", baud_desc, val, base + M6811_BAUD); sim_io_printf (sd, " (%ld baud)\n", (cpu->cpu_frequency / 4) / controller->baud_cycle); val = cpu->ios[M6811_SCCR1]; print_io_byte (sd, "SCCR1", sccr1_desc, val, base + M6811_SCCR1); sim_io_printf (sd, " (%d bits) (%dN1)\n", controller->data_length, controller->data_length - 2); val = cpu->ios[M6811_SCCR2]; print_io_byte (sd, "SCCR2", sccr2_desc, val, base + M6811_SCCR2); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_SCSR]; print_io_byte (sd, "SCSR ", scsr_desc, val, base + M6811_SCSR); sim_io_printf (sd, "\n"); clock_cycle = controller->data_length * controller->baud_cycle; if (controller->tx_poll_event) { signed64 t; int n; t = hw_event_remain_time (me, controller->tx_poll_event); n = (clock_cycle - t) / controller->baud_cycle; n = controller->data_length - n; sim_io_printf (sd, " Transmit finished in %s (%d bit%s)\n", cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE), n, (n > 1 ? "s" : "")); } if (controller->rx_poll_event) { signed64 t; t = hw_event_remain_time (me, controller->rx_poll_event); sim_io_printf (sd, " Receive finished in %s\n", cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE)); } }
/* Describe the state of the EEPROM device. */ static void m68hc11eepr_info (struct hw *me) { SIM_DESC sd; uint16 base = 0; sim_cpu *cpu; struct m68hc11eepr *controller; uint8 val; sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); base = cpu_get_io_base (cpu); sim_io_printf (sd, "M68HC11 EEprom:\n"); val = cpu->ios[M6811_PPROG]; print_io_byte (sd, "PPROG ", pprog_desc, val, base + M6811_PPROG); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_CONFIG]; print_io_byte (sd, "CONFIG ", config_desc, val, base + M6811_CONFIG); sim_io_printf (sd, "\n"); val = controller->eeprom[controller->size - 1]; print_io_byte (sd, "(*NEXT*) ", config_desc, val, base + M6811_CONFIG); sim_io_printf (sd, "\n"); /* Describe internal state of EEPROM. */ if (controller->eeprom_wmode) { if (controller->eeprom_waddr == controller->size - 1) sim_io_printf (sd, " Programming CONFIG register "); else sim_io_printf (sd, " Programming: 0x%04x ", controller->eeprom_waddr + controller->base_address); sim_io_printf (sd, "with 0x%02x\n", controller->eeprom_wbyte); } sim_io_printf (sd, " EEProm file: %s\n", controller->file_name); }
static void m68hc11spi_info (struct hw *me) { SIM_DESC sd; uint16 base = 0; sim_cpu *cpu; struct m68hc11spi *controller; uint8 val; sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); sim_io_printf (sd, "M68HC11 SPI:\n"); base = cpu_get_io_base (cpu); val = cpu->ios[M6811_SPCR]; print_io_byte (sd, "SPCR", spcr_desc, val, base + M6811_SPCR); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_SPSR]; print_io_byte (sd, "SPSR", spsr_desc, val, base + M6811_SPSR); sim_io_printf (sd, "\n"); if (controller->spi_event) { signed64 t; sim_io_printf (sd, " SPI has %d bits to send\n", controller->tx_bit + 1); t = hw_event_remain_time (me, controller->spi_event); sim_io_printf (sd, " SPI current bit-cycle finished in %s\n", cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE)); t += (controller->tx_bit + 1) * 2 * controller->clock; sim_io_printf (sd, " SPI operation finished in %s\n", cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE)); } }
static unsigned m68hc11eepr_io_write_buffer (struct hw *me, const void *source, int space, unsigned_word base, unsigned nr_bytes) { SIM_DESC sd; struct m68hc11eepr *controller; sim_cpu *cpu; uint8 val; HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); sd = hw_system (me); controller = hw_data (me); cpu = STATE_CPU (sd, 0); /* Programming several bytes at a time is not possible. */ if (space != io_map && nr_bytes != 1) { sim_memory_error (cpu, SIM_SIGBUS, base, "EEprom write error (only 1 byte can be programmed)"); return 0; } if (nr_bytes != 1) hw_abort (me, "Cannot write more than 1 byte to EEPROM device at a time"); val = *((const uint8*) source); /* Write to the EEPROM control register. */ if (space == io_map && base == M6811_PPROG) { uint8 wrong_bits; uint16 addr; addr = base + cpu_get_io_base (cpu); /* Setting EELAT and EEPGM at the same time is an error. Clearing them both is ok. */ wrong_bits = (cpu->ios[M6811_PPROG] ^ val) & val; wrong_bits &= (M6811_EELAT | M6811_EEPGM); if (wrong_bits == (M6811_EEPGM|M6811_EELAT)) { sim_memory_error (cpu, SIM_SIGBUS, addr, "Wrong eeprom programing value"); return 0; } if ((val & M6811_EELAT) == 0) { val = 0; } if ((val & M6811_EEPGM) && !(cpu->ios[M6811_PPROG] & M6811_EELAT)) { sim_memory_error (cpu, SIM_SIGBUS, addr, "EEProm high voltage applied after EELAT"); } if ((val & M6811_EEPGM) && controller->eeprom_wmode == 0) { sim_memory_error (cpu, SIM_SIGSEGV, addr, "EEProm high voltage applied without address"); } if (val & M6811_EEPGM) { controller->eeprom_wcycle = cpu_current_cycle (cpu); } else if (cpu->ios[M6811_PPROG] & M6811_PPROG) { int i; unsigned long t = cpu_current_cycle (cpu); t -= controller->eeprom_wcycle; if (t < controller->eeprom_min_cycles) { sim_memory_error (cpu, SIM_SIGILL, addr, "EEprom programmed only for %lu cycles", t); } /* Program the byte by clearing some bits. */ if (!(cpu->ios[M6811_PPROG] & M6811_ERASE)) { controller->eeprom[controller->eeprom_waddr] &= controller->eeprom_wbyte; } /* Erase a byte, row or the complete eeprom. Erased value is 0xFF. Ignore row or complete eeprom erase when we are programming the CONFIG register (last EEPROM byte). */ else if ((cpu->ios[M6811_PPROG] & M6811_BYTE) || controller->eeprom_waddr == controller->size - 1) { controller->eeprom[controller->eeprom_waddr] = 0xff; } else if (cpu->ios[M6811_BYTE] & M6811_ROW) { size_t max_size; /* Size of EEPROM (-1 because the last byte is the CONFIG register. */ max_size = controller->size; controller->eeprom_waddr &= 0xFFF0; for (i = 0; i < 16 && controller->eeprom_waddr < max_size; i++) { controller->eeprom[controller->eeprom_waddr] = 0xff; controller->eeprom_waddr ++; } } else { size_t max_size; max_size = controller->size; for (i = 0; i < max_size; i++) { controller->eeprom[i] = 0xff; } } /* Save the eeprom in a file. We have to save after each change because the simulator can be stopped or crash... */ if (m6811eepr_memory_rw (controller, O_WRONLY | O_CREAT) != 0) { sim_memory_error (cpu, SIM_SIGABRT, addr, "EEPROM programing failed: errno=%d", errno); } controller->eeprom_wmode = 0; } cpu->ios[M6811_PPROG] = val; return 1; } /* The CONFIG IO register is mapped at end of EEPROM. It's not visible. */ if (space == io_map && base == M6811_CONFIG) { base = controller->size - 1; } else { base = base - controller->base_address; } /* Writing the memory is allowed for the Debugger or simulator (cpu not running). */ if (cpu_is_running (cpu)) { if ((cpu->ios[M6811_PPROG] & M6811_EELAT) == 0) { sim_memory_error (cpu, SIM_SIGSEGV, base, "EEprom not configured for writing"); return 0; } if (controller->eeprom_wmode != 0) { sim_memory_error (cpu, SIM_SIGSEGV, base, "EEprom write error"); return 0; } controller->eeprom_wmode = 1; controller->eeprom_waddr = base; controller->eeprom_wbyte = val; } else { controller->eeprom[base] = val; m6811eepr_memory_rw (controller, O_WRONLY); } return 1; }
static void m68hc11tim_info (struct hw *me) { SIM_DESC sd; uint16 base = 0; sim_cpu *cpu; struct m68hc11tim *controller; uint8 val; uint16 val16; sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); sim_io_printf (sd, "M68HC11 Timer:\n"); base = cpu_get_io_base (cpu); /* Info for TIC1 */ val16 = (cpu->ios[M6811_TIC1_H] << 8) + cpu->ios[M6811_TIC1_L]; print_io_word (sd, "TIC1 ", 0, val16, base + M6811_TIC1); sim_io_printf (sd, "\n"); /* Info for TIC2 */ val16 = (cpu->ios[M6811_TIC2_H] << 8) + cpu->ios[M6811_TIC2_L]; print_io_word (sd, "TIC2 ", 0, val16, base + M6811_TIC2); sim_io_printf (sd, "\n"); /* Info for TIC3 */ val16 = (cpu->ios[M6811_TIC3_H] << 8) + cpu->ios[M6811_TIC3_L]; print_io_word (sd, "TIC3 ", 0, val16, base + M6811_TIC3); sim_io_printf (sd, "\n"); /* Info for TOC1 */ val16 = (cpu->ios[M6811_TOC1_H] << 8) + cpu->ios[M6811_TOC1_L]; print_io_word (sd, "TOC1 ", 0, val16, base + M6811_TOC1); sim_io_printf (sd, "\n"); /* Info for TOC2 */ val16 = (cpu->ios[M6811_TOC2_H] << 8) + cpu->ios[M6811_TOC2_L]; print_io_word (sd, "TOC2 ", 0, val16, base + M6811_TOC2); sim_io_printf (sd, "\n"); /* Info for TOC3 */ val16 = (cpu->ios[M6811_TOC3_H] << 8) + cpu->ios[M6811_TOC3_L]; print_io_word (sd, "TOC3 ", 0, val16, base + M6811_TOC3); sim_io_printf (sd, "\n"); /* Info for TOC4 */ val16 = (cpu->ios[M6811_TOC4_H] << 8) + cpu->ios[M6811_TOC4_L]; print_io_word (sd, "TOC4 ", 0, val16, base + M6811_TOC4); sim_io_printf (sd, "\n"); /* Info for TOC5 */ val16 = (cpu->ios[M6811_TOC5_H] << 8) + cpu->ios[M6811_TOC5_L]; print_io_word (sd, "TOC5 ", 0, val16, base + M6811_TOC5); sim_io_printf (sd, "\n"); /* Info for TMSK1 */ val = cpu->ios[M6811_TMSK1]; print_io_byte (sd, "TMSK1 ", tmsk1_desc, val, base + M6811_TMSK1); sim_io_printf (sd, "\n"); /* Info for TFLG1 */ val = cpu->ios[M6811_TFLG1]; print_io_byte (sd, "TFLG1", tflg1_desc, val, base + M6811_TFLG1); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_TMSK2]; print_io_byte (sd, "TMSK2 ", tmsk2_desc, val, base + M6811_TMSK2); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_TFLG2]; print_io_byte (sd, "TFLG2", tflg2_desc, val, base + M6811_TFLG2); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_PACTL]; print_io_byte (sd, "PACTL", pactl_desc, val, base + M6811_PACTL); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_PACNT]; print_io_byte (sd, "PACNT", 0, val, base + M6811_PACNT); sim_io_printf (sd, "\n"); /* Give info about the next timer interrupts. */ m68hc11tim_print_timer (me, "RTI", controller->rti_timer_event); m68hc11tim_print_timer (me, "COP", controller->cop_timer_event); m68hc11tim_print_timer (me, "OVERFLOW", controller->tof_timer_event); m68hc11tim_print_timer (me, "COMPARE", controller->cmp_timer_event); }