Пример #1
0
int test_status() {
	asic_t *asic = asic_init(TI83p, NULL);
	z80iodevice_t status = init_status(asic);
	// Test battery status
	asic->battery = BATTERIES_GOOD;
	asic->battery_remove_check = 0;
	uint8_t value = status.read_in(status.device);
	if (!(value & 1)) {
		asic_free(asic);
		return 1;
	}
	// Test flash
	asic->mmu->flash_unlocked = 1;
	value = status.read_in(status.device);
	if (!(value & 4)) {
		asic_free(asic);
		return 1;
	}
	asic->mmu->flash_unlocked = 0;
	value = status.read_in(status.device);
	if (value & 4) {
		asic_free(asic);
		return 1;
	}
	asic_free(asic);
	return 0;
}
Пример #2
0
int test_link_assist_rx() {
	asic_t *asic = asic_init(TI83pSE, NULL);
	z80iodevice_t link_assist_rx_read = asic->cpu->devices[0x0A];
	z80iodevice_t link_assist_status = asic->cpu->devices[0x09];
	link_state_t *state = link_assist_rx_read.device;

	if (!link_recv_byte(asic, 0xBE)) {
		asic_free(asic);
		return 1;
	}
	if (link_recv_byte(asic, 0xEF)) {
		asic_free(asic);
		return 2;
	}

	uint8_t status = link_assist_status.read_in(state);
	if (status != state->assist.status.u8 ||
			!state->assist.status.rx_ready ||
			!state->assist.status.int_rx_ready) {
		return 3;
	}

	uint8_t val = link_assist_rx_read.read_in(state);
	if (val != 0xBE) {
		return 4;
	}

	status = link_assist_status.read_in(state);
	if (status != state->assist.status.u8 ||
			state->assist.status.rx_ready ||
			state->assist.status.int_rx_ready) {
		return 5;
	}
	return 0;
}
Пример #3
0
int test_LDDR() {
	asic_t *device = asic_init(TI83p, NULL);
	uint8_t test[] = { 0xED, 0xB8 }; // LDDR
	device->cpu->registers.HL = 0xC004;
	device->cpu->registers.DE = 0xD004;
	device->cpu->registers.BC = 5;
	cpu_write_byte(device->cpu, 0xC000, 0x11);
	cpu_write_byte(device->cpu, 0xC001, 0x22);
	cpu_write_byte(device->cpu, 0xC002, 0x33);
	cpu_write_byte(device->cpu, 0xC003, 0x44);
	cpu_write_byte(device->cpu, 0xC004, 0x55);
	flash(device, test, sizeof(test));
	int cycles = cpu_execute(device->cpu, 100);
	if (cpu_read_byte(device->cpu, 0xD000) != 0x11 ||
			cpu_read_byte(device->cpu, 0xD001) != 0x22 ||
			cpu_read_byte(device->cpu, 0xD002) != 0x33 ||
			cpu_read_byte(device->cpu, 0xD003) != 0x44 ||
			cpu_read_byte(device->cpu, 0xD004) != 0x55 ||
			device->cpu->registers.HL != 0xBFFF ||
			device->cpu->registers.DE != 0xCFFF ||
			device->cpu->registers.BC != 0 ||
			cycles != 0) {
		asic_free(device);
		return 1;
	}
	asic_free(device);
	return 0;
}
Пример #4
0
int test_CPD() {
	asic_t *device = asic_init(TI83p, NULL);
	uint8_t test[] = { 0xED, 0xA9 }; // CPD
	device->cpu->registers.HL = 0xC002;
	device->cpu->registers.BC = 5;
	device->cpu->registers.A = 0x11;
	cpu_write_byte(device->cpu, 0xC000, 0x11);
	cpu_write_byte(device->cpu, 0xC001, 0x22);
	cpu_write_byte(device->cpu, 0xC002, 0x33);
	flash(device, test, sizeof(test));
	int cycles = cpu_execute(device->cpu, 16);
	if (device->cpu->registers.flags.Z != 0 ||
			device->cpu->registers.HL != 0xC001 ||
			device->cpu->registers.BC != 4 ||
			cycles != 0) {
		asic_free(device);
		return 1;
	}
	device->cpu->registers.PC = 0;
	cpu_execute(device->cpu, 16);
	device->cpu->registers.PC = 0;
	cpu_execute(device->cpu, 16);
	if (device->cpu->registers.flags.Z != 1 ||
			device->cpu->registers.HL != 0xBFFF ||
			device->cpu->registers.BC != 2) {
		asic_free(device);
		return 1;
	}
	asic_free(device);
	return 0;
}
Пример #5
0
int hardware_sys_init() {
	/* Setup ASIC stuff */
	asic_init();

	/* VBlank multiplexer */
	vblank_init();

	initted = 1;

	return 0;
}
Пример #6
0
int test_memorymapping_others() {
	asic_t *asic = asic_init(TI84p, NULL);
	memory_mapping_state_t *state = asic->cpu->devices[0x04].device;


	state->ram_bank_page = 1;
	state->bank_a_page = 0;
	state->bank_a_flash = 0;

	reload_mapping(state);
	ti_write_byte(asic->mmu, 0x4000, 0x12);

	if (asic->mmu->ram[0] != 0x12) {
		asic_free(asic);
		return 1;
	}

	asic->mmu->ram[0x4000] = 0x34;
	if (ti_read_byte(asic->mmu, 0xC000) != 0x34) {
		asic_free(asic);
		return 2;
	}

	state->map_mode = 1;
	state->bank_a_page = 0;
	state->bank_a_flash = 0;
	state->bank_b_page = 0;
	state->bank_b_flash = 0;
	reload_mapping(state);

	if (ti_read_byte(asic->mmu, 0x4000) != 0x12) {
		asic_free(asic);
		return 3;
	}

	if (ti_read_byte(asic->mmu, 0x8000) != 0x34) {
		asic_free(asic);
		return 4;
	}

	if (ti_read_byte(asic->mmu, 0xC000) != 0x12) {
		asic_free(asic);
		return 5;
	}
	return 0;
}
Пример #7
0
int test_link_port() {
	asic_t *asic = asic_init(TI83p, NULL);
	z80iodevice_t link = asic->cpu->devices[0x00];
	link_state_t *state = link.device;
	uint8_t value = link.read_in(state);
	if (value != 0) {
		asic_free(asic);
		return 1;
	}
	link.write_out(state, 0x01);
	value = link.read_in(state);
	if (value != 0x11) {
		asic_free(asic);
		return 2;
	}
	return 0;
}
Пример #8
0
int test_CPDR() {
    asic_t *device = asic_init(TI83p);
    uint8_t test[] = { 0xED, 0xB9 }; // CPDR
    device->cpu->registers.HL = 0xC004;
    device->cpu->registers.BC = 5;
    device->cpu->registers.A = 0x33;
    cpu_write_byte(device->cpu, 0xC001, 0x22);
    cpu_write_byte(device->cpu, 0xC002, 0x33);
    cpu_write_byte(device->cpu, 0xC003, 0x44);
    cpu_write_byte(device->cpu, 0xC004, 0x55);
    flash(device, test, sizeof(test));
    int cycles = cpu_execute(device->cpu, 58);
    if (device->cpu->registers.HL != 0xC001 ||
        device->cpu->registers.BC != 2 ||
        cycles != 0) {
        asic_free(device);
        return 1;
    }
    asic_free(device);
    return 0;
}
Пример #9
0
int test_link_assist_tx() {
	asic_t *asic = asic_init(TI83pSE, NULL);
	z80iodevice_t link_assist_tx_read = asic->cpu->devices[0x0D];
	z80iodevice_t link_assist_status = asic->cpu->devices[0x09];
	link_state_t *state = link_assist_tx_read.device;

	if (link_read_tx_buffer(asic) != EOF) {
		asic_free(asic);
		return 1;
	}

	uint8_t status = link_assist_status.read_in(state);
	if (status != state->assist.status.u8 ||
			!state->assist.status.tx_ready ||
			!state->assist.status.int_tx_ready) {
		return 2;
	}

	link_assist_tx_read.write_out(state, 0xDE);

	status = link_assist_status.read_in(state);
	if (status != state->assist.status.u8 ||
			state->assist.status.tx_ready ||
			state->assist.status.int_tx_ready) {
		return 3;
	}

	if (link_read_tx_buffer(asic) != 0xDE) {
		return 4;
	}

	status = link_assist_status.read_in(state);
	if (status != state->assist.status.u8 ||
			!state->assist.status.tx_ready ||
			!state->assist.status.int_tx_ready) {
		return 5;
	}
	return 0;
}
Пример #10
0
int test_LDI() {
    asic_t *device = asic_init(TI83p);
    uint8_t test[] = { 0xED, 0xA0 }; // LDI
    device->cpu->registers.HL = 0xC000;
    device->cpu->registers.DE = 0xD000;
    device->cpu->registers.BC = 5;
    cpu_write_byte(device->cpu, 0xC000, 0x11);
    cpu_write_byte(device->cpu, 0xC001, 0x22);
    cpu_write_byte(device->cpu, 0xC002, 0x33);
    cpu_write_byte(device->cpu, 0xC003, 0x44);
    cpu_write_byte(device->cpu, 0xC004, 0x55);
    flash(device, test, sizeof(test));
    int cycles = cpu_execute(device->cpu, 16);
    if (cpu_read_byte(device->cpu, 0xD000) != 0x11 ||
        device->cpu->registers.HL != 0xC001 ||
        device->cpu->registers.DE != 0xD001 ||
        device->cpu->registers.BC != 4 ||
        cycles != 0) {
        asic_free(device);
        return 1;
    }
    asic_free(device);
    return 0;
}
Пример #11
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;
}
Пример #12
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;
}