Exemple #1
0
void error(const char *fmt, ...) {
    va_list va;
    va_start(va, fmt);
    gui_console_printf("Error (%06X): ", asic.cpu->registers.PC);
    gui_console_vprintf(fmt, va);
    gui_console_printf("\n");
    va_end(va);
    debugger(DBG_EXCEPTION, 0);
    cpu_events |= EVENT_RESET;
}
Exemple #2
0
static void watchdog_event(int index) {

    if (watchdog.control & 1) {
        watchdog.status = 1;
        if (watchdog.control & 2) {
            gui_console_printf("[CEmu] Watchdog reset triggered.\n");
            cpuEvents |= EVENT_RESET;
        }
        if (watchdog.control & 4) {
            cpu_nmi();
            gui_console_printf("[CEmu] Watchdog NMI triggered.\n");
        }
        event_repeat(index, watchdog.load);
    }
}
Exemple #3
0
static void plug_devices(void) {
    /* Port ranges 0x0 -> 0xF */
    port_map[0x0] = init_control();
    port_map[0x1] = init_flash();
    port_map[0x2] = init_sha256();
    port_map[0x3] = init_usb();
    port_map[0x4] = init_lcd();
    port_map[0x5] = init_intrpt();
    port_map[0x6] = init_watchdog();
    port_map[0x7] = init_gpt();
    port_map[0x8] = init_rtc();
    port_map[0x9] = init_protected();
    port_map[0xA] = init_keypad();
    port_map[0xB] = init_backlight();
    port_map[0xC] = init_cxxx();
    port_map[0xD] = init_dxxx();
    port_map[0xE] = init_exxx();
    port_map[0xF] = init_fxxx();

    reset_proc_count = 0;

    /* Populate reset callbacks */
    add_reset_proc(lcd_reset);
    add_reset_proc(keypad_reset);
    add_reset_proc(gpt_reset);
    add_reset_proc(rtc_reset);
    add_reset_proc(watchdog_reset);
    add_reset_proc(cpu_reset);

    gui_console_printf("[CEmu] Initialized APB...\n");
}
Exemple #4
0
void emu_loop(bool reset) {

    if (reset) {
        emu_reset();
    }

    exiting = false;

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(emu_inner_loop, -1, 1);
#else
    while (!exiting) {
        if (cpu_events & EVENT_RESET) {
            cpu_events = EVENT_NONE;
            gui_console_printf("CPU Reset triggered...");
            emu_reset();
        }
        if (cpu_events & EVENT_DEBUG_STEP) {
            cpu_events = EVENT_NONE;
            debugger(DBG_STEP, 0);
        }
        sched_process_pending_events();
        if (cycle_count_delta < 0) {
            cpu_execute();  // execute instructions with available clock cycles
        } else {
            QThread::yieldCurrentThread();
        }
    }

    emu_cleanup();
#endif
}
Exemple #5
0
void mem_init(void) {
    unsigned int i;

    mem.flash.block = (uint8_t*)malloc(flash_size);               /* allocate Flash memory */
    memset(mem.flash.block, 0xFF, flash_size);
    mem.flash.size = flash_size;

    for (i = 0; i < flash_sectors_8K; i++) {
        mem.flash.sector[i].ptr = mem.flash.block + (i*flash_sector_size_8K);
        mem.flash.sector[i].locked = true;
    }

    for (i = flash_sectors_8K; i < flash_sectors_64K+flash_sectors_8K; i++) {
        mem.flash.sector[i].ptr = mem.flash.block + (i*flash_sector_size_64K);
        mem.flash.sector[i].locked = false;
    }

    /* Sector 9 is locked */
    mem.flash.sector[9].locked = true;
    mem.flash.locked = true;

    mem.ram.block = (uint8_t*)calloc(ram_size, sizeof(uint8_t));      /* Allocate RAM */

    mem.debug.stepOverAddress = -1;
    mem.debug.block = (uint8_t*)calloc(0x1000000, sizeof(uint8_t));    /* Allocate Debug memory */
    mem.debug.ports = (uint8_t*)calloc(0x10000, sizeof(uint8_t));      /* Allocate Debug Port Monitor */

    mem.flash.mapped = false;
    mem.flash.write_index = 0;
    mem.flash.command = NO_COMMAND;
    gui_console_printf("Initialized memory...\n");
}
Exemple #6
0
void debugger_init(void) {
    debugger.stepOverAddress = -1;
    debugger.data.block = (uint8_t*)calloc(0x1000000, sizeof(uint8_t));    /* Allocate Debug memory */
    debugger.data.ports = (uint8_t*)calloc(0x10000, sizeof(uint8_t));      /* Allocate Debug Port Monitor */

    debugger.runUntilSet = false;
    gui_console_printf("Initialized Debugger...\n");
}
Exemple #7
0
void debugger_free(void) {
    if (debugger.data.block) {
        free(debugger.data.block);
    }
    if (debugger.data.ports) {
        free(debugger.data.ports);
    }
    gui_console_printf("Freed Debugger.\n");
}
Exemple #8
0
static void flash_erase(uint32_t addr, uint8_t byte) {
    (void)addr;
    (void)byte;

    mem.flash.command = FLASH_CHIP_ERASE;

    memset(mem.flash.block, 0xFF, flash_size);
    gui_console_printf("Erased entire Flash chip.\n");
}
Exemple #9
0
void asic_init(void) {
    /* First, initilize memory and CPU */
    mem_init();
    cpu_init();

    asic.ship_mode_enabled = false;

    plug_devices();
    gui_console_printf("[CEmu] Initialized ASIC...\n");
}
Exemple #10
0
eZ80portrange_t init_control(void) {
    memset(&control, 0, sizeof control);
    gui_console_printf("[CEmu] Initialized Control Ports...\n");

    /* Set default state to full battery and not charging */
    control.batteryCharging = false;
    control.setBatteryStatus = BATTERY_4;

    return device;
}
Exemple #11
0
void rtc_reset() {
    memset(&rtc, 0, sizeof rtc);
    rtc.revision = 0x00010500;

    sched.items[SCHED_RTC].callback.event = rtc_event;
    sched.items[SCHED_RTC].clock = CLOCK_1;
    sched_clear(SCHED_RTC);

    gui_console_printf("[CEmu] RTC reset.\n");
}
Exemple #12
0
void rtc_reset() {
    memset(&rtc, 0, sizeof rtc);
    rtc.revision = 0x00010500;

    sched.items[SCHED_RTC].clock = CLOCK_32K;
    sched.items[SCHED_RTC].second = -1;
    sched.items[SCHED_RTC].proc = rtc_event;

    gui_console_printf("[CEmu] RTC reset.\n");
}
Exemple #13
0
void debugger_init(void) {
    debugger.stepOverInstrEnd = -1;
    debugger.data.block = (uint8_t*)calloc(0x1000000, sizeof(uint8_t));    /* Allocate Debug memory */
    debugger.data.ports = (uint8_t*)calloc(0x10000, sizeof(uint8_t));      /* Allocate Debug Port Monitor */
    debugger.buffer = (char*)malloc(SIZEOF_DBG_BUFFER * sizeof(char));     /* Used for printing to the console */
    debugger.errBuffer = (char*)malloc(SIZEOF_DBG_BUFFER * sizeof(char));  /* Used for printing to the console */
    debugger.currentBuffPos = debugger.currentErrBuffPos = 0;

    gui_console_printf("[CEmu] Initialized Debugger...\n");
}
Exemple #14
0
void watchdog_reset() {
    /* Initialize device to default state */
    memset(&watchdog, 0, sizeof watchdog);

    sched.items[SCHED_WATCHDOG].clock = CLOCK_CPU;
    sched.items[SCHED_WATCHDOG].second = -1;
    sched.items[SCHED_WATCHDOG].proc = watchdog_event;
    watchdog.load = 0x03EF1480;   /* (66MHz) */
    watchdog.count = 0x03EF1480;

    gui_console_printf("Watchdog Timer Reset.\n");
}
Exemple #15
0
// TODO : Make sure it works with the recent commits.
void emu_inner_loop(void)
{
  while (!exiting) {
      sched_process_pending_events();
      if (cpu_events & EVENT_RESET) {
          gui_console_printf("CPU Reset triggered...");
          emu_reset();
      }
      if (cycle_count_delta < 0) {
          cpu_execute();  // execute instructions with available clock cycles
      }
  }
}
Exemple #16
0
eZ80portrange_t init_flash(void) {
    int i;

    /* Initialize device to default state */
    for(i = 0; i<0x100; i++) {
        flash.ports[i] = 0;
    }
    flash.ports[0x00] = 0x01; /* From WikiTI */
    flash.ports[0x07] = 0xFF; /* From WikiTI */
    flash.map = 0x06;         /* From WikiTI */

    gui_console_printf("Initialized flash device...\n");
    return device;
}
Exemple #17
0
void control_reset(void) {
    memset(&control.ports, 0, sizeof control.ports);

    control.privileged = 0xFFFFFF;
    control.protectedStart = control.protectedEnd = 0xD1887C;
    control.protectionStatus = 0;
    control.stackLimit = 0;
    control.cpuSpeed = 0;
    control.flashUnlocked = false;
    control.protectedPortsUnlocked = false;
    control.off = false;

    gui_console_printf("[CEmu] Control reset.\n");
}
Exemple #18
0
void open_debugger(int reason, uint32_t data) {
    if (inDebugger) {
        /* Prevent recurse */
        return;
    }

    if ((reason == DBG_STEP) && debugger.stepOverFirstStep) {
        if (((cpuEvents & EVENT_DEBUG_STEP_NEXT)
                && !(debugger.data.block[cpu.registers.PC] & DBG_TEMP_EXEC_BREAKPOINT)) || (cpuEvents & EVENT_DEBUG_STEP_OUT)) {
            debugger.stepOverFirstStep = false;
            gui_debugger_raise_or_disable(inDebugger = false);
            return;
        }
        debug_clear_temp_break();
    }

    debugger.cpu_cycles = cpu.cycles;
    debugger.cpu_next = cpu.next;
    debugger.total_cycles = cpu.cycles + cpu.cycles_offset;

    if (debugger.currentBuffPos) {
        debugger.buffer[debugger.currentBuffPos] = '\0';
        gui_console_printf("%s", debugger.buffer);
        debugger.currentBuffPos = 0;
    }

    if (debugger.currentErrBuffPos) {
        debugger.errBuffer[debugger.currentErrBuffPos] = '\0';
        gui_console_err_printf("%s", debugger.errBuffer);
        debugger.currentErrBuffPos = 0;
    }

    inDebugger = true;
    gui_debugger_send_command(reason, data);

    while (inDebugger) {
        gui_emu_sleep(50);
    }

    cpu.next = debugger.cpu_next;
    cpu.cycles = debugger.cpu_cycles;
    cpu.cycles_offset = debugger.total_cycles - cpu.cycles;

    if (cpuEvents & EVENT_DEBUG_STEP) {
        cpu.next = cpu.cycles + 1;
    }
}
Exemple #19
0
static void watchdog_event(int index) {
    (void)index;

    if (watchdog.control & 1) {
        if (--watchdog.count == 0) {
            watchdog.status = 1;
            watchdog.count = watchdog.load;
        }
    }

    if ((watchdog.count == 0) && ((watchdog.control & 2) || (watchdog.control & 1))) {
        cpu_events |= EVENT_RESET;
        gui_console_printf("Watchdog reset triggered...");
    } else {
        //intrpt_trigger(INT_WATCHDOG, INTERRUPT_SET);  // TODO
        event_repeat(SCHED_WATCHDOG, watchdog.load);
    }
}
Exemple #20
0
void mem_free(void) {
    if (mem.ram.block) {
        free(mem.ram.block);
        mem.ram.block = NULL;
    }
    if (mem.flash.block) {
        free(mem.flash.block);
        mem.flash.block = NULL;
    }
    if (mem.debug.block) {
        free(mem.debug.block);
        mem.debug.block = NULL;
    }
    if (mem.debug.ports) {
        free(mem.debug.ports);
        mem.debug.ports = NULL;
    }
    gui_console_printf("Freed memory...\n");
}
Exemple #21
0
/* Write to the 0xFXXX range of ports */
static void fxxx_write(const uint16_t pio, const uint8_t value) {
    /* 0xFFE appears to dump the contents of flash. Probably not a good thing to print to a console :) */

    if (pio != 0xFFF) {
        return;
    }

#ifdef DEBUG_SUPPORT
    debugger.buffer[debugger.currentBuffPos] = (char)value;
    debugger.currentBuffPos = (debugger.currentBuffPos + 1) % (SIZEOF_DBG_BUFFER);
    if (value == 0) {
        unsigned x;
        debugger.currentBuffPos = 0;
        gui_console_printf("%s",debugger.buffer);
        for(x=0; x<6; x++) {
            gui_emu_sleep();
        }
    }
#endif
}
Exemple #22
0
static void emu_main_loop_inner(void) {
    if (!emulationPaused) {
        if (cpuEvents & EVENT_RESET) {
            gui_console_printf("[CEmu] Calculator reset triggered...\n");
            cpu_reset();
            cpuEvents &= ~EVENT_RESET;
        }
#ifdef DEBUG_SUPPORT
        if (!cpu.halted && (cpuEvents & EVENT_DEBUG_STEP)) {
            cpuEvents &= ~EVENT_DEBUG_STEP;
            open_debugger(DBG_STEP, 0);
        }
#endif
        if (!asic.shipModeEnabled) {
            sched_process_pending_events();
            cpu_execute();
        } else {
            gui_emu_sleep(50);
        }
    } else {
        gui_emu_sleep(50);
    }
}
Exemple #23
0
eZ80portrange_t init_rtc(void) {
    gui_console_printf("[CEmu] Initialized RTC...\n");
    return device;
}
Exemple #24
0
eZ80portrange_t init_watchdog(void) {
    gui_console_printf("Initialized watchdog timer...\n");
    return pwatchdog;
}
Exemple #25
0
bool emu_start(const char *romImage, const char *savedImage) {
    bool ret = false;
    long lSize;
    FILE *imageFile = NULL;

    gui_set_busy(true);

    do {
        if(savedImage != NULL) {
            emu_image_t *image;
            imageFile = fopen_utf8(savedImage, "rb");

            if (!imageFile) {
                break;
            }
            if (fseek(imageFile, 0L, SEEK_END) < 0) {
                break;
            }
            lSize = ftell(imageFile);
            if (lSize < 0) {
                break;
            }
            if (fseek(imageFile, 0L, SEEK_SET) < 0) {
                break;
            }
            if((size_t)lSize < sizeof(emu_image_t)) {
                break;
            }

            image = (emu_image_t*)malloc(lSize);
            if(!image) {
                break;
            }
            if(fread(image, lSize, 1, imageFile) != 1) {
                free(image);
                break;
            }

            sched_reset();
            sched.items[SCHED_THROTTLE].clock = CLOCK_27M;
            sched.items[SCHED_THROTTLE].proc = throttle_interval_event;

            asic_init();
            asic_reset();

            if(image->version != imageVersion || !asic_restore(image)) {
                emu_cleanup();
                free(image);
                break;
            }
            free(image);
            ret = true;
        } else {
            asic_init();
            if (romImage == NULL) {
                gui_console_printf("[CEmu] No ROM image specified.\n");
                break;
            } else {
                FILE *romFile = fopen_utf8(romImage, "rb");
                do {
                    if (romFile) {
                        uint16_t field_type;
                        const uint8_t *outer;
                        const uint8_t *current;
                        const uint8_t *data;
                        uint32_t outer_field_size;
                        uint32_t data_field_size;
                        ti_device_t device_type;
                        uint32_t offset;

                        /* Get ROM file size */
                        if (fseek(romFile, 0L, SEEK_END) < 0) {
                            break;
                        }
                        lSize = ftell(romFile);
                        if (lSize < 0) {
                            break;
                        }
                        if (fseek(romFile, 0L, SEEK_SET) < 0) {
                            break;
                        }

                        /* Read whole ROM. */
                        if (fread(mem.flash.block, 1, lSize, romFile) < (size_t)lSize) {
                            break;
                        }

                        if (mem.flash.block[0x7E] == 0xFE) {
                            break;
                        }

                        /* Parse certificate fields to determine model.                            */
                        /* device_type = (ti_device_type)(asic.mem->flash.block[0x20017]);         */
                        /* We've heard of the OS base being at 0x30000 on at least one calculator. */
                        for (offset = 0x20000U; offset < 0x40000U; offset += 0x10000U) {
                            outer = mem.flash.block;
                            /* Outer 0x800(0) field. */
                            if (cert_field_get(outer + offset, mem.flash.size - offset, &field_type, &outer, &outer_field_size)) {
                                break;
                            }
                            if (field_type != 0x800F /*|| field_type == 0x800D || field_type == 0x800E*/) {
                                continue;
                            }
                            /*fprintf(stderr, "outer: %p\t%04X\t%p\t%u\n", asic.mem->flash.block, field_type, outer, outer_field_size);*/

                            /* Inner 0x801(0) field: calculator model */
                            if (cert_field_get(outer, outer_field_size, &field_type, &data, &data_field_size)) {
                                break;
                            }
                            /*fprintf(stderr, "inner 1: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            if (field_type != 0x8012 || data[0] != 0x13) {
                                break;
                            }

                            /* Inner 0x802(0) field: skip. */
                            data_field_size = outer_field_size - (data + data_field_size - outer);
                            data = outer;
                            if (cert_field_next(&data, &data_field_size)) {
                                break;
                            }
                            /*fprintf(stderr, "data: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            current = data;
                            if (cert_field_get(current, data_field_size, &field_type, &data, &data_field_size)) {
                                break;
                            }
                            /*fprintf(stderr, "inner 2: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            if (field_type != 0x8021) {
                                break;
                            }

                            /* Inner 0x803(0) field: skip. */
                            data_field_size = outer_field_size - (data + data_field_size - outer);
                            data = current;
                            if (cert_field_next(&data, &data_field_size)) {
                                break;
                            }
                            current = data;
                            /*fprintf(stderr, "data: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            if (cert_field_get(current, data_field_size, &field_type, &data, &data_field_size)) {
                                break;
                            }
                            /*fprintf(stderr, "inner 3: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            if (field_type != 0x8032) {
                                break;
                            }

                            /* Inner 0x80A(0) field: skip. */
                            data_field_size = outer_field_size - (data + data_field_size - outer);
                            data = current;
                            if (cert_field_next(&data, &data_field_size)) {
                                break;
                            }
                            current = data;
                            /*fprintf(stderr, "data: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            if (cert_field_get(current, data_field_size, &field_type, &data, &data_field_size)) {
                                break;
                            }
                            /*fprintf(stderr, "inner 4: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            if (field_type != 0x80A1) {
                                break;
                            }

                            /* Inner 0x80C(0) field: keep. */
                            data_field_size = outer_field_size - (data + data_field_size - outer);
                            data = current;
                            if (cert_field_next(&data, &data_field_size)) {
                                break;
                            }
                            current = data;
                            /*fprintf(stderr, "data: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            if (cert_field_get(current, data_field_size, &field_type, &data, &data_field_size)) {
                                break;
                            }
                            /*fprintf(stderr, "inner 5: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);*/
                            if (field_type != 0x80C2) {
                                break;
                            }

                            /*fprintf(stderr, "Found calculator type %02X\n", data[1]);*/
                            if (data[1] != 0 && data[1] != 1) {
                                break;
                            }
                            device_type = (ti_device_t)(data[1]);

                            /* If we come here, we've found something. */
                            ret = true;
                            break;
                        }

                        if (ret) {
                            set_device_type(device_type);
                        }
                    }
                } while(0);

                if (romFile) {
                    fclose(romFile);
                }
            }
        }
    } while(0);

    if (imageFile) {
        fclose(imageFile);
    }

    if (!ret) {
        gui_console_printf("[CEmu] Error opening image (Corrupted certificate?)\n");
        emu_cleanup();
    }

    gui_set_busy(false);

    return ret;
}
Exemple #26
0
bool emu_start() {
    bool ret = false;
    long lSize;

    asic_init();

    if (rom_image == NULL) {
        gui_console_printf("No ROM image specified.");
    }
    else {
        FILE *rom = fopen_utf8(rom_image, "rb");
        do {
            if (rom) {
                uint16_t field_type;
                const uint8_t *outer;
                const uint8_t *current;
                const uint8_t *data;
                uint32_t outer_field_size;
                uint32_t data_field_size;
                ti_device_type device_type;
                uint32_t offset;

                // Get ROM file size
                if (fseek(rom, 0L, SEEK_END) < 0) {
                    break;
                }

                lSize = ftell(rom);
                if (lSize < 0) {
                    break;
                }

                if (fseek(rom, 0L, SEEK_SET) < 0) {
                    break;
                }

                // Read whole ROM.
                if (fread(asic.mem->flash.block, 1, lSize, rom) < (size_t)lSize) {
                    break;
                }

                // Parse certificate fields to determine model.
                //device_type = (ti_device_type)(asic.mem->flash.block[0x20017]);
                // We've heard of the OS base being at 0x30000 on at least one calculator.
                for (offset = 0x20000U; offset < 0x40000U; offset += 0x10000U) {
                    outer = asic.mem->flash.block;
                    // Outer 0x800(0) field.
                    if (cert_field_get(outer + offset, asic.mem->flash.size - offset, &field_type, &outer, &outer_field_size)) {
                        break;
                    }
                    if (field_type != 0x800F /*|| field_type == 0x800D || field_type == 0x800E*/) {
                        continue;
                    }
                    //fprintf(stderr, "outer: %p\t%04X\t%p\t%u\n", asic.mem->flash.block, field_type, outer, outer_field_size);

                    // Inner 0x801(0) field: calculator model
                    if (cert_field_get(outer, outer_field_size, &field_type, &data, &data_field_size)) {
                        break;
                    }
                    //fprintf(stderr, "inner 1: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    if (field_type != 0x8012 || data[0] != 0x13) {
                        break;
                    }

                    // Inner 0x802(0) field: skip.
                    data_field_size = outer_field_size - (data + data_field_size - outer);
                    data = outer;
                    if (cert_field_next(&data, &data_field_size)) {
                        break;
                    }
                    //fprintf(stderr, "data: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    current = data;
                    if (cert_field_get(current, data_field_size, &field_type, &data, &data_field_size)) {
                        break;
                    }
                    //fprintf(stderr, "inner 2: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    if (field_type != 0x8021) {
                        break;
                    }

                    // Inner 0x803(0) field: skip.
                    data_field_size = outer_field_size - (data + data_field_size - outer);
                    data = current;
                    if (cert_field_next(&data, &data_field_size)) {
                        break;
                    }
                    current = data;
                    //fprintf(stderr, "data: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    if (cert_field_get(current, data_field_size, &field_type, &data, &data_field_size)) {
                        break;
                    }
                    //fprintf(stderr, "inner 3: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    if (field_type != 0x8032) {
                        break;
                    }

                    // Inner 0x80A(0) field: skip.
                    data_field_size = outer_field_size - (data + data_field_size - outer);
                    data = current;
                    if (cert_field_next(&data, &data_field_size)) {
                        break;
                    }
                    current = data;
                    //fprintf(stderr, "data: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    if (cert_field_get(current, data_field_size, &field_type, &data, &data_field_size)) {
                        break;
                    }
                    //fprintf(stderr, "inner 4: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    if (field_type != 0x80A1) {
                        break;
                    }

                    // Inner 0x80C(0) field: keep.
                    data_field_size = outer_field_size - (data + data_field_size - outer);
                    data = current;
                    if (cert_field_next(&data, &data_field_size)) {
                        break;
                    }
                    current = data;
                    //fprintf(stderr, "data: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    if (cert_field_get(current, data_field_size, &field_type, &data, &data_field_size)) {
                        break;
                    }
                    //fprintf(stderr, "inner 5: %p\t%04X\t%p\t%u\n", outer, field_type, data, data_field_size);
                    if (field_type != 0x80C2) {
                        break;
                    }

                    //fprintf(stderr, "Found calculator type %02X\n", data[1]);
                    if (data[1] != 0 && data[1] != 1) {
                        break;
                    }
                    device_type = (ti_device_type)(data[1]);

                    // If we come here, we've found something.
                    ret = true;
                    break;
                }


                if (ret) {
                    control.device_type = device_type;
                    asic.device_type = device_type;
                }

            }
        } while(0);

        if (!ret) {
            gui_console_printf("Error opening ROM image.\n", rom_image);
            emu_cleanup();
        }

        if (rom) {
            fclose(rom);
        }
    }

    return ret;
}
Exemple #27
0
eZ80portrange_t init_protected(void) {
    gui_console_printf("Initialized protected port range...\n");
    return p9xxx;
}
Exemple #28
0
/* Write to the 0x0XXX range of ports */
static void control_write(const uint16_t pio, const uint8_t byte) {
    uint8_t index = pio & 0x7F;

    switch (index) {
        case 0x00:
            control.ports[index] = byte;
            switch (control.readBatteryStatus) {
                case 3: /* Battery Level is 0 */
                    control.readBatteryStatus = (control.setBatteryStatus == BATTERY_0) ? 0 : (byte == 0x83) ? 5 : 0;
                    break;
                case 5: /* Battery Level is 1 */
                    control.readBatteryStatus = (control.setBatteryStatus == BATTERY_1) ? 0 : (byte == 0x03) ? 7 : 0;
                    break;
                case 7: /* Battery Level is 2 */
                    control.readBatteryStatus = (control.setBatteryStatus == BATTERY_2) ? 0 : (byte == 0x83) ? 9 : 0;
                    break;
                case 9: /* Battery Level is 3 (Or 4) */
                    control.readBatteryStatus = (control.setBatteryStatus == BATTERY_3) ? 0 : (byte == 0x03) ? 11 : 0;
                    break;
            }
            break;
        case 0x01:
            control.cpuSpeed = byte & 19;
            switch(control.cpuSpeed & 3) {
                case 0:
                    set_cpu_clock_rate(6e6);  /* 6 MHz  */
                    break;
                case 1:
                    set_cpu_clock_rate(12e6); /* 12 MHz */
                    break;
                case 2:
                    set_cpu_clock_rate(24e6); /* 24 MHz */
                    break;
                case 3:
                    set_cpu_clock_rate(48e6); /* 48 MHz */
                    break;
                default:
                    break;
            }
            gui_console_printf("[CEmu] CPU clock rate set to: %d MHz\n", 6*(1<<(control.cpuSpeed & 3)));
#ifdef DEBUG_SUPPORT
            if (cpuEvents & EVENT_DEBUG_STEP) {
                cpuEvents &= ~EVENT_DEBUG_STEP;
                open_debugger(DBG_STEP, 0);
            }
#endif
            break;
        case 0x06:
            control.ports[index] = byte & 7;
            break;
        case 0x07:
            control.readBatteryStatus = (byte & 0x90) ? 1 : 0;
            break;
        case 0x09:
            switch (control.readBatteryStatus) {
                case 1: /* Battery is bad */
                    control.readBatteryStatus = (control.setBatteryStatus == BATTERY_DISCHARGED) ? 0 : (byte & 0x80) ? 0 : 3;
                    break;
            }
            control.ports[index] = byte;

            /* Appears to enter low-power mode (For now; this will be fine) */
            if (byte == 0xD4) {
                asic.ship_mode_enabled = true;
                control.ports[0] |= 0x40; // Turn calc off
                cpuEvents |= EVENT_RESET;
            }
            break;
        case 0x0A:
            control.readBatteryStatus += (control.readBatteryStatus == 3) ? 1 : 0;
            control.ports[index] = byte;
            break;
        case 0x0B:
        case 0x0C:
            control.readBatteryStatus = 0;
            break;
        case 0x0D:
            control.ports[index] = (byte & 0xF) << 4 | (byte & 0xF);
            break;
        case 0x0F:
            control.ports[index] = byte & 3;
            break;
        case 0x1D:
        case 0x1E:
        case 0x1F:
            write8(control.privileged, (index - 0x1D) << 3, byte);
            break;
        case 0x28:
            if (cpu.registers.PC < control.privileged) {
                mem.flash.locked = (byte & 4) == 0;
            }
            control.ports[index] = byte & 247;
            break;
        default:
            control.ports[index] = byte;
            break;
    }
}
Exemple #29
0
void mem_reset(void) {
    memset(mem.ram.block, 0, ram_size);
    gui_console_printf("RAM reset.\n");
}
Exemple #30
0
void asic_free(void) {
    /* make sure the LCD doesn't use unalloced mem */
    lcd.upcurr = lcd.upbase = 0;
    mem_free();
    gui_console_printf("[CEmu] Freed ASIC.\n");
}