--- trunk/src/emul.c 2007/10/08 16:20:58 32 +++ trunk/src/emul.c 2007/10/08 16:21:17 34 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2006 Anders Gavare. All rights reserved. + * Copyright (C) 2003-2007 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: emul.c,v 1.272 2006/10/31 08:26:56 debug Exp $ + * $Id: emul.c,v 1.278 2007/02/10 14:37:38 debug Exp $ * * Emulation startup and misc. routines. */ @@ -57,6 +57,9 @@ #include "x11.h" +/* #define ISO_DEBUG */ + + extern int extra_argc; extern char **extra_argv; @@ -223,7 +226,9 @@ dirofs = (int64_t)(buf[0x8c] + (buf[0x8d] << 8) + (buf[0x8e] << 16) + ((uint64_t)buf[0x8f] << 24)) * 2048; - /* debug("root = %i bytes at 0x%llx\n", dirlen, (long long)dirofs); */ +#ifdef ISO_DEBUG + debug("root = %i bytes at 0x%llx\n", dirlen, (long long)dirofs); +#endif dirbuf = malloc(dirlen); if (dirbuf == NULL) { @@ -258,22 +263,30 @@ if (p == NULL) p = strchr(filename, '\\'); - /* debug("%i%s: %i, %i, \"", filenr, filenr == found_dir? - " [CURRENT]" : "", x, y); */ +#ifdef ISO_DEBUG + debug("%i%s: %i, %i, \"", filenr, filenr == found_dir? + " [CURRENT]" : "", x, y); +#endif for (i=0; imachine_type) { + + case MACHINE_DREAMCAST: + if (!diskimage_is_a_cdrom(cpu->machine, boot_disk_id, + boot_disk_type)) { + fatal("The Dreamcast emulation mode can only boot" + " from CD images, not from other disk types.\n"); + exit(1); + } + + bootblock_buf = malloc(32768); + if (bootblock_buf == NULL) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + debug("loading Dreamcast IP.BIN from %s id %i\n", + diskimage_types[boot_disk_type], boot_disk_id); + + res = diskimage_access(m, boot_disk_id, boot_disk_type, + 0, base_offset, bootblock_buf, 0x8000); + if (!res) { + fatal("Couldn't read the disk image. Aborting.\n"); + return 0; + } + + if (strncmp((char *)bootblock_buf, "SEGA ", 5) != 0) { + fatal("This is not a Dreamcast IP.BIN header.\n"); + free(bootblock_buf); + return 0; + } + + /* Store IP.BIN at 0x8c008000, and set entry point. */ + store_buf(cpu, 0x8c008000, (char *)bootblock_buf, 32768); + cpu->pc = 0x8c008300; + + /* Remember the name of the file to boot (1ST_READ.BIN): */ + if (cpu->machine->boot_kernel_filename == NULL || + cpu->machine->boot_kernel_filename[0] == '\0') { + int i = 0x60; + while (i < 0x70) { + if (bootblock_buf[i] == ' ') + bootblock_buf[i] = 0; + i ++; + } + cpu->machine->boot_kernel_filename = strdup( + (char *)bootblock_buf + 0x60); + } + + debug("boot filename: %s\n", + cpu->machine->boot_kernel_filename); + + free(bootblock_buf); + + break; + case MACHINE_PMAX: /* * The first few bytes of a disk contains information about @@ -641,36 +711,6 @@ debug(readofs == 0x18? ": no blocks?\n" : " blocks\n"); return 1; - - case MACHINE_X86: - /* TODO: "El Torito" etc? */ - if (diskimage_is_a_cdrom(cpu->machine, boot_disk_id, - boot_disk_type)) - break; - - bootblock_buf = malloc(512); - if (bootblock_buf == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(1); - } - - debug("loading PC bootsector from %s id %i\n", - diskimage_types[boot_disk_type], boot_disk_id); - - res = diskimage_access(m, boot_disk_id, boot_disk_type, 0, 0, - bootblock_buf, 512); - if (!res) { - fatal("Couldn't read the disk image. Aborting.\n"); - return 0; - } - - if (bootblock_buf[510] != 0x55 || bootblock_buf[511] != 0xaa) - debug("WARNING! The 0x55,0xAA marker is missing! " - "Booting anyway.\n"); - store_buf(cpu, 0x7c00, (char *)bootblock_buf, 512); - free(bootblock_buf); - - return 1; } @@ -678,7 +718,7 @@ * Try reading a kernel manually from the disk. The code here * does not rely on machine-dependent boot blocks etc. */ - /* ISO9660: (0x800 bytes at 0x8000) */ + /* ISO9660: (0x800 bytes at 0x8000 + base_offset) */ bootblock_buf = malloc(0x800); if (bootblock_buf == NULL) { fprintf(stderr, "Out of memory.\n"); @@ -686,7 +726,7 @@ } res = diskimage_access(m, boot_disk_id, boot_disk_type, - 0, 0x8000, bootblock_buf, 0x800); + 0, base_offset + 0x8000, bootblock_buf, 0x800); if (!res) { fatal("Couldn't read the disk image. Aborting.\n"); return 0; @@ -747,7 +787,7 @@ * * Returns a reasonably initialized struct emul. */ -struct emul *emul_new(char *name) +struct emul *emul_new(char *name, int id) { struct emul *e; e = malloc(sizeof(struct emul)); @@ -758,6 +798,13 @@ memset(e, 0, sizeof(struct emul)); + e->path = malloc(15); + if (e->path == NULL) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + snprintf(e->path, 15, "emul[%i]", id); + e->settings = settings_new(); settings_add(e->settings, "n_machines", 0, @@ -828,7 +875,7 @@ char tmpstr[20]; int i; - m = machine_new(name, e); + m = machine_new(name, e, e->n_machines); m->serial_nr = (e->next_serial_nr ++); i = e->n_machines; @@ -1242,20 +1289,6 @@ } } - /* Special things required _before_ loading the file: */ - switch (m->arch) { - case ARCH_X86: - /* - * X86 machines normally don't need to load any files, - * they can boot from disk directly. Therefore, an x86 - * machine usually boots up in 16-bit real mode. When - * loading a 32-bit (or even 64-bit) ELF, that's not - * very nice, hence this special case. - */ - pc_bios_simple_pmode_setup(cpu); - break; - } - byte_order = NO_BYTE_ORDER_OVERRIDE; /* @@ -1297,27 +1330,10 @@ } break; - case ARCH_AVR32: - cpu->pc = (uint32_t) cpu->pc; - if (cpu->pc & 1) { - fatal("AVR32: lowest bit of pc set: TODO\n"); - exit(1); - } - break; - case ARCH_RCA180X: cpu->pc &= 0xffff; break; - case ARCH_HPPA: - break; - - case ARCH_I960: - break; - - case ARCH_IA64: - break; - case ARCH_M68K: break; @@ -1355,24 +1371,6 @@ cpu->pc &= 0xffffffffULL; break; - case ARCH_X86: - /* - * NOTE: The toc field is used to indicate an ELF32 - * or ELF64 load. - */ - switch (toc) { - case 0: /* 16-bit? TODO */ - cpu->pc &= 0xffffffffULL; - break; - case 1: /* 32-bit. */ - cpu->pc &= 0xffffffffULL; - break; - case 2: /* 64-bit: TODO */ - fatal("64-bit x86 load. TODO\n"); - exit(1); - } - break; - default: fatal("emul_machine_setup(): Internal error: " "Unimplemented arch %i\n", m->arch); @@ -1469,11 +1467,6 @@ debug("0x%016llx", (long long)entrypoint); break; - case ARCH_X86: - debug("0x%04x:0x%llx", cpu->cd.x86.s[X86_S_CS], - (long long)cpu->pc); - break; - default: if (cpu->is_32bit) debug("0x%08x", (int)cpu->pc); @@ -1559,10 +1552,10 @@ * * Create an emul struct by reading settings from a configuration file. */ -struct emul *emul_create_from_configfile(char *fname) +struct emul *emul_create_from_configfile(char *fname, int id) { int iadd = DEBUG_INDENTATION; - struct emul *e = emul_new(fname); + struct emul *e = emul_new(fname, id); debug("Creating emulation from configfile \"%s\":\n", fname); debug_indentation(iadd);