Beispiel #1
0
int forward_seek_entry(int segment_id, byte ** ptr, unsigned long *map)
{
	byte *tmp_ptr;
	unsigned long sector;
	int segment;
	int count;

	do {
		sector = get_sector(ptr, forward);
		segment = cvt2segment(sector);
	} while (sector != 0 && segment < segment_id);
	tmp_ptr = *ptr - 3;	/* point to first sector >= segment_id */
	/*  Get all sectors in segment_id
	 */
	if (format_code == 4 && (sector & 0x800000) && segment == segment_id) {
		*map = EMPTY_SEGMENT;
		count = 32;
	} else {
		*map = 0;
		count = 0;
		while (sector != 0 && segment == segment_id) {
			*map |= cvt2map(sector);
			sector = get_sector(ptr, forward);
			segment = cvt2segment(sector);
			++count;
		}
	}
	*ptr = tmp_ptr;
	return count;
}
int get_clickshift(u32_t ksec, struct image_header *hdr)
/* Get the click shift and special flags from kernel text. */
{
	char *textp;

	if ((textp= get_sector(ksec)) == nil) return 0;

	if (hdr->process.a_flags & A_PAL) textp+= hdr->process.a_hdrlen;
	click_shift= * (u16_t *) (textp + CLICK_OFF);
	k_flags= * (u16_t *) (textp + FLAGS_OFF);

	if ((k_flags & ~K_ALL) != 0) {
		printf("%s requires features this monitor doesn't offer\n",
			hdr->name);
		return 0;
	}

	if (click_shift < HCLICK_SHIFT || click_shift > 16) {
		printf("%s click size is bad\n", hdr->name);
		errno= 0;
		return 0;
	}

	click_size= 1 << click_shift;

	return 1;
}
void
EditorSectorsMenu::create_sector()
{
  auto level = Editor::current()->get_level();

  auto new_sector = SectorParser::from_nothing(*level);

  if (!new_sector) {
    log_warning << "Failed to create a new sector." << std::endl;
    return;
  }

  // Find an unique name
  std::string sector_name;
  int num = 2;
  do {
    sector_name = "sector" + std::to_string(num);
    num++;
  } while ( level->get_sector(sector_name) );
  new_sector->set_name(sector_name);

  level->add_sector(std::move(new_sector));
  Editor::current()->load_sector(sector_name);
  MenuManager::instance().clear_menu_stack();
  Editor::current()->m_reactivate_request = true;
}
Beispiel #4
0
int get_segment(u32_t *vsec, long *size, u32_t *addr, u32_t limit)
/* Read *size bytes starting at virtual sector *vsec to memory at *addr. */
{
    char *buf;
    size_t cnt, n;

    cnt= 0;
    while (*size > 0) {
        if (cnt == 0) {
            if ((buf= get_sector((*vsec)++)) == nil) return 0;
            cnt= SECTOR_SIZE;
        }
        if (*addr + click_size > limit) {
            errno= ENOMEM;
            return 0;
        }
        n= click_size;
        if (n > cnt) n= cnt;
        raw_copy(*addr, mon2abs(buf), n);
        *addr+= n;
        *size-= n;
        buf+= n;
        cnt-= n;
    }

    /* Zero extend to a click. */
    n= align(*addr, click_size) - *addr;
    raw_clear(*addr, n);
    *addr+= n;
    *size-= n;
    return 1;
}
Beispiel #5
0
int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
{
	struct burn_drive *d = o->drive;
	unsigned char subs[96];
	unsigned char *data;

	data = get_sector(o, t, t->mode);
	if (data == NULL)
		return 0;
	/* ts A61010 */
	if (convert_data(o, t, t->mode, data) <= 0)
		return 0;

	/* ts A61031 */
	if ((t->open_ended || t->end_on_premature_eoi) && t->track_data_done) {
		unget_sector(o, t->mode);
		return 2;
	}

	/* ts A61219 : allow track without .entry */
	if (t->entry == NULL)
		;
	else if (!t->source->read_sub)
		subcode_user(o, subs, t->entry->point,
			     t->entry->control, 1, &t->isrc, psub);
	else if (!t->source->read_sub(t->source, subs, 96))
		subcode_user(o, subs, t->entry->point,
			     t->entry->control, 1, &t->isrc, psub);
	convert_subs(o, t->mode, subs, data);

	if (sector_headers(o, data, t->mode, 0) <= 0)
		return 0;
	sector_common(++)
	return 1;
}
Beispiel #6
0
int backwards_seek_entry(int segment_id, byte ** ptr, unsigned long *map)
{
	unsigned long sector;
	int segment;
	int count;

	*map = 0;
	if (*ptr > bad_sector_map) {
		do {
			sector = get_sector(ptr, backward);
			segment = cvt2segment(sector);
		} while (*ptr > bad_sector_map && segment > segment_id);
		count = 0;
		if (segment > segment_id) {
			/*  at start of list, no entry found */
		} else if (segment < segment_id) {
			/*  before smaller entry, adjust for overshoot */
			*ptr += 3;
		} else {
			/*  get all sectors in segment_id */
			if (format_code == 4 && (sector & 0x800000)) {
				*map = EMPTY_SEGMENT;
				count = 32;
			} else {
				do {
					*map |= cvt2map(sector);
					++count;
					if (*ptr <= bad_sector_map) {
						break;
					}
					sector = get_sector(ptr, backward);
					segment = cvt2segment(sector);
				} while (segment == segment_id);
				if (segment < segment_id) {
					*ptr += 3;
				}
			}
		}
	} else {
		count = 0;
	}
	return count;
}
Beispiel #7
0
void
Level::add_sector(std::unique_ptr<Sector> sector)
{
  Sector* test = get_sector(sector->get_name());
  if (test != nullptr) {
    throw std::runtime_error("Trying to add 2 sectors with same name");
  } else {
    m_sectors.push_back(std::move(sector));
  }
}
Beispiel #8
0
int TRKCACHE::write_sector(unsigned sec, unsigned char *data)
{
   const SECHDR *h = get_sector(sec);
   if (!h || !h->data)
       return 0;
   unsigned sz = h->datlen;
   if(h->data != data)
      memcpy(h->data, data, sz);
   *(unsigned short*)(h->data+sz) = (unsigned short)wd93_crc(h->data-1, sz+1);
   return sz;
}
Beispiel #9
0
static size_t fat_read(struct fat_fs *filesystem, uint32_t cluster_no, uint8_t *buf,
                       size_t byte_count, size_t offset) {
    uint32_t cur_cluster = cluster_no;
    size_t cluster_size = filesystem->bytes_per_sector * filesystem->sectors_per_cluster;
    size_t file_loc = 0;
    int buf_ptr = 0;
    while(cur_cluster < 0x0ffffff8) {
        if(( file_loc + cluster_size) > offset) {
            if( file_loc < (offset + byte_count)) {
                //  load this cluster, as it contains the requested file
                uint32_t sector = get_sector(filesystem, cur_cluster);
                uint8_t * r_buf = (uint8_t*)malloc(cluster_size);
                int ret = sd_read(r_buf, cluster_size, sector);
                // check for error
                if(ret < 0) {
                    return ret;
                }

                int len;
                int c_ptr;
                // what part of this sector is in the file
                if(offset >= file_loc) {
                    // first cluster of file
                    buf_ptr = 0;
                    c_ptr = offset - file_loc;
                    len = byte_count;
                    if(len > (int)cluster_size) {
                        len = cluster_size;
                    }
                } else {
                    // not first cluster of file
                    c_ptr = 0;
                    len = byte_count - buf_ptr;
                    if(len > (int)cluster_size)             {
                        len = cluster_size;
                    }
                    if(len > (int)(byte_count - buf_ptr))   {
                        len = byte_count - buf_ptr;
                    }
                }
                memcpy(buf + buf_ptr, r_buf + c_ptr, len);
                free(r_buf);
                buf_ptr += len;
            }
        }
        cur_cluster = get_next_fat_entry( filesystem, cur_cluster);
        file_loc += cluster_size;
    }
    return buf_ptr;
}
Beispiel #10
0
int hal_nvm_init_sector(HAL_NVM_HANDLE handle, unsigned long address)
{
    int sector = get_sector(address);
    int rv = HAL_NVM_E_SUCCESS;

    FLASH_Unlock();

    if (FLASH_EraseSector(sector, VoltageRange_3) != FLASH_COMPLETE)
    {
        rv = HAL_NVM_E_ERROR;
    }

    FLASH_Lock();

    return rv;
}
Beispiel #11
0
int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
{
	struct burn_drive *d = o->drive;
	unsigned char subs[96];
	unsigned char *data;

	data = get_sector(o, NULL, mode);
	if (!data)
		return 0;
	/* ts A61010 */
	if (convert_data(o, NULL, mode, data) <= 0)
		return 0;
	subcode_lout(o, control, subs);
	convert_subs(o, mode, subs, data);
	if (sector_headers(o, data, mode, 0) <= 0)
		return 0;
	sector_common(++)
	return 1;
}
Beispiel #12
0
int sector_toc(struct burn_write_opts *o, int mode)
{
	struct burn_drive *d = o->drive;
	unsigned char *data;
	unsigned char subs[96];

	data = get_sector(o, NULL, mode);
	if (data == NULL)
		return 0;
	/* ts A61010 */
	if (convert_data(o, NULL, mode, data) <= 0)
		return 0;
	subcode_toc(d, mode, subs);
	convert_subs(o, mode, subs, data);
	if (sector_headers(o, data, mode, 1) <= 0)
		return 0;
	sector_common(++)
	return 1;
}
Beispiel #13
0
int sector_pregap(struct burn_write_opts *o,
		   unsigned char tno, unsigned char control, int mode)
{
	struct burn_drive *d = o->drive;
	unsigned char *data;
	unsigned char subs[96];

	data = get_sector(o, NULL, mode);
	if (data == NULL)
		return 0;
	/* ts A61010 */
	if (convert_data(o, NULL, mode, data) <= 0)
		return 0;
	subcode_user(o, subs, tno, control, 0, NULL, 1);
	convert_subs(o, mode, subs, data);
	if (sector_headers(o, data, mode, 0) <= 0)
		return 0;
	sector_common(--)
	return 1;
}
Beispiel #14
0
void get_data(DRIVE_PARAMS *drive_params, uint8_t track[]) {
   int block;
   int rc;

   block = (get_cyl() * drive_params->num_head + get_head()) *
       drive_params->num_sectors + get_sector();

   if (lseek(drive_params->ext_fd, 
          block * drive_params->sector_size, SEEK_SET) == -1) {
      msg(MSG_FATAL, "Failed to seek to sector in extracted data file %s\n", 
           strerror(errno));
      exit(1);
   }
   if ((rc = read(drive_params->ext_fd, track, 
         drive_params->sector_size)) != drive_params->sector_size) {
      msg(MSG_FATAL, "Failed to read extracted data file rc %d %s\n", rc,
            rc == -1 ? strerror(errno): "");
      exit(1);
   };
}
Beispiel #15
0
int get_segment(u32_t *vsec, long *size, u32_t *addr, u32_t limit)
/* Read *size bytes starting at virtual sector *vsec to memory at *addr. */
{
	char *buf;
	size_t cnt, n;

	cnt= 0;
	while (*size > 0) {
		if (cnt == 0) {
			if ((buf= get_sector((*vsec)++)) == nil) return 0;
			cnt= SECTOR_SIZE;
		}
		if (*addr + click_size > limit) 
		{ 
			DEBUGEXTRA(("get_segment: out of memory; "
				"addr=0x%lx; limit=0x%lx; size=%lx\n", 
				*addr, limit, size));
			errno= ENOMEM; 
			return 0; 
		}
		n= click_size;
		if (n > cnt) n= cnt;
		DEBUGMAX(("raw_copy(0x%lx, 0x%lx/0x%x, 0x%lx)... ", 
			*addr, mon2abs(buf), buf, n));
		raw_copy(*addr, mon2abs(buf), n);
		DEBUGMAX(("done\n"));
		*addr+= n;
		*size-= n;
		buf+= n;
		cnt-= n;
	}

	/* Zero extend to a click. */
	n= align(*addr, click_size) - *addr;
	DEBUGMAX(("raw_clear(0x%lx, 0x%lx)... ", *addr, n));
	raw_clear(*addr, n);
	DEBUGMAX(("done\n"));
	*addr+= n;
	*size-= n;
	return 1;
}
Beispiel #16
0
void put_bad_sector_entry(int segment_id, unsigned long new_map)
{
	byte *ptr = bad_sector_map;
	int count;
	int new_count;
	unsigned long map;

	if (format_code == 3 || format_code == 4) {
		count = forward_seek_entry(segment_id, &ptr, &map);
		new_count = count_ones(new_map);
		/*  If format code == 4 put empty segment instead of 32 bad sectors.
		 */
		if (new_count == 32 && format_code == 4) {
			new_count = 1;
		}
		if (count != new_count) {
			/*  insert (or delete if < 0) new_count - count entries.
			 *  Move trailing part of list including terminating 0.
			 */
			byte *hi_ptr = ptr;

			do {
			} while (get_sector(&hi_ptr, forward) != 0);
			memmove(ptr + new_count, ptr + count, hi_ptr - (ptr + count));
		}
		if (new_count == 1 && new_map == EMPTY_SEGMENT) {
			put_sector(&ptr, 0x800001 + segment_id * SECTORS_PER_SEGMENT);
		} else {
			int i = 0;

			while (new_map) {
				if (new_map & 1) {
					put_sector(&ptr, 1 + segment_id * SECTORS_PER_SEGMENT + i);
				}
				++i;
				new_map >>= 1;
			}
		}
	} else {
Beispiel #17
0
static uint32_t fat_get_next_bdev_block_num(uint32_t f_block_idx, fs_file *s, void *opaque, int add_blocks)
{
	struct fat_file_block_offset *ffbo = (struct fat_file_block_offset *)opaque;

	// Iterate through the cluster chain until we reach the appropriate one
	while((ffbo->f_block != f_block_idx) && (ffbo->cluster < 0x0ffffff8))
	{
		ffbo->cluster = get_next_fat_entry((struct fat_fs *)s->fs, ffbo->cluster);
		ffbo->f_block++;
	}

	if(ffbo->cluster < 0x0ffffff8)
		return get_sector((struct fat_fs *)s->fs, ffbo->cluster);
	else
	{
		if(add_blocks)
		{
			printf("FAT: request to extend cluster chain not currently supported\r\n");
		}
		s->flags |= EOF;
		return 0xffffffff;
	}
}
Beispiel #18
0
int main(int, char** argv)
{
    FILE* file;

    int result = get_sector(0x80, 0, 0, 1, sector);

    if(0 != result)
    {
        fprintf(stderr, "%s: error reading sector\n", argv[0]);
        result = 1;
    }
    else if((file = fopen(file_name, "wb")) == 0)
    {
        fprintf(stderr, "%s: error opening %s\n", argv[0], file_name);
        result = 1;
    }
    else
    {
        fwrite(sector, sector_size, 1, file);
        fclose(file);
        result = 0;
    }
    return result;
}
Beispiel #19
0
long rread(Rfile tpf, void *buf, long count)
/* Read a buffer from an open ram-disk file. */
{
char ***platter;
char **track;
char *data;
int i;
int ssize, so;
int flags;
long filept;
long  readin;
long fsize;

flags = tpf->flags;
if (!(flags&TF_OPEN))
	{
	rerr = Err_file_not_open;
	return(0);
	}
if (!(flags&TF_READ))
	{
	rerr = Err_read;
	return(0);
	}
data = buf;
readin = 0;
filept = tpf->filep;
fsize  = tpf->size;
if ((tpf->filep = filept+count) > fsize)
	{
	rerr = Err_eof;
	if ((count = fsize-filept) <= 0)
		return(0);
	}
platter = tpf->platters + get_platter(filept);
for (;;)
	{
	i = get_track(filept);
	track = *platter  +  i;
	for ( ; i< TRD_TRACK; i++)
		{
		so = get_sector(filept);
		ssize = TRD_SECTOR - so;
		if (count > ssize)
			{
			memcpy(data, *track + so, ssize);
			readin += ssize;
			data +=  ssize;
			count -= ssize;
			filept += ssize;
			}
		else
			{
			memcpy(data,  *track + so, (size_t)count);
			return(readin+count);
			}
		track++;
		}
	platter++;
	}
}
Beispiel #20
0
int main(int argc, char* argv[]) {
    char q[512];
    MYSQL_ROW row;
    MYSQL_RES* res;

    int err = init_network();
    if (err) {
        return err;
    }

    for (int year = 1990; year <= 2011; year++) {
        std::cout << "Querying " << year << "\n";

        snprintf(q, 512, "select count(value) from entries where year=%d and inserted>(select updated from visualizations where name='GAP2' and year=%d)", year, year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }
        res = mysql_use_result(mysql);
        if ((row = mysql_fetch_row(res)) == 0 || atoi(row[0]) == 0) {
            mysql_free_result(res);
            continue;
        }
        mysql_free_result(res);

        err = read_network(year);
        if (err) {
            return err;
        }

        std::cout << "Calculating " << year << "\n";

        Basetype* in_flow = create_array(0);
        Basetype* out_flow = create_array(0);
        int regions_size = regions.size();
        Basetype* total_output = new Basetype[regions_size];
        for (int r = 0; r < regions_size; r++) {
            total_output[r] = 0;
        }
        for (int v = 0; v < network_size; v++) {
            for (int w = 0; w < network_size; w++) {
                in_flow[v] += flows[w][v];
                out_flow[v] += flows[v][w];
            }
            total_output[get_region(v)] += out_flow[v];
        }
        int sectors_size = sectors.size();
        Basetype** in_flow_by_sector = new Basetype*[sectors_size];
        for (int i = 0; i < sectors_size; i++) {
            in_flow_by_sector[i] = create_array(0);
        }
        for (int v = 0; v < network_size; v++) {
            for (int w = 0; w < network_size; w++) {
                in_flow_by_sector[get_sector(v)][w] += flows[v][w];
            }
        }

        snprintf(q, 512, "delete from visualization_data where visualization in (select id from visualizations where (name='GAP1' or name='GAP2') and year=%d)", year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }

        snprintf(q, 512, "select id from visualizations where name='GAP1' and year=%d", year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }
        res = mysql_use_result(mysql);
        row = mysql_fetch_row(res);
        int id1 = atoi(row[0]);
        mysql_free_result(res);

        snprintf(q, 512, "select id from visualizations where name='GAP2' and year=%d", year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }
        res = mysql_use_result(mysql);
        row = mysql_fetch_row(res);
        int id2 = atoi(row[0]);
        mysql_free_result(res);

        for (int r = 0; r < regions_size; r++) {
            Basetype* damage1 = create_array(0);
            Basetype* damage2 = create_array(0);
            int js;

            #pragma omp parallel default(shared) private(js)
            {
                #pragma omp for schedule(guided) nowait
                for (js = 0; js < network_size; js++) {
                    if (get_region(js) == r) {
                        damage1[js] = 1;
                    } else {
                        for (int i = 0; i < sectors_size; i++) {
                            Basetype damage = flows[get_index(i, r)][js] / in_flow_by_sector[i][js];
                            if (damage1[js] < damage) {
                                damage1[js] = damage;
                            }
                        }
                    }
                }
            }
            #pragma omp parallel default(shared) private(js)
            {
                #pragma omp for schedule(guided) nowait
                for (js = 0; js < network_size; js++) {
                    if (get_region(js) == r) {
                        damage2[js] = 1;
                    } else {
                        for (int i = 0; i < sectors_size; i++) {
                            Basetype damage = 0;
                            for (int r = 0; r < regions_size; r++) {
                                int ir = get_index(i, r);
                                damage += damage1[ir] * flows[ir][js] / in_flow_by_sector[i][js];
                            }
                            if (damage2[js] < damage) {
                                damage2[js] = damage;
                            }
                        }
                    }
                }
            }

            Basetype* region_damage1 = new Basetype[regions_size];
            Basetype* region_damage2 = new Basetype[regions_size];
            for (int r = 0; r < regions_size; r++) {
                region_damage1[r] = 0;
                region_damage2[r] = 0;
            }
            for (int js = 0; js < network_size; js++) {
                int s = get_region(js);
                if (total_output[s] > 0) {
                    region_damage1[s] += damage1[js] * out_flow[js] / total_output[s];
                    region_damage2[s] += damage2[js] * out_flow[js] / total_output[s];
                }
            }
            delete[] damage1;
            delete[] damage2;

            std::stringstream query1("insert into visualization_data (visualization, region_from, region_to, value) values ", std::ios_base::app | std::ios_base::out);
            bool first1 = true;
            std::stringstream query2("insert into visualization_data (visualization, region_from, region_to, value) values ", std::ios_base::app | std::ios_base::out);
            bool first2 = true;
            for (int s = 0; s < regions_size; s++) {
                region_damage1[s] = round(region_damage1[s] * 1000) / 1000;
                if (region_damage1[s] > 0) {
                    if (first1) {
                        first1 = false;
                    } else {
                        query1 << ",";
                    }
                    query1 << "(" << id1 << ",'" << regions[r] << "','" << regions[s] << "'," << region_damage1[s] << ")";
                }
                region_damage2[s] = round(region_damage2[s] * 1000) / 1000;
                if (region_damage2[s] > 0) {
                    if (first2) {
                        first2 = false;
                    } else {
                        query2 << ",";
                    }
                    query2 << "(" << id2 << ",'" << regions[r] << "','" << regions[s] << "'," << region_damage2[s] << ")";
                }
            }
            if (!first1) {
                if (mysql_query(mysql, query1.str().c_str())) {
                    std::cerr << mysql_error(mysql) << "\n";
                    return -2;
                }
            }
            if (!first2) {
                if (mysql_query(mysql, query2.str().c_str())) {
                    std::cerr << mysql_error(mysql) << "\n";
                    return -2;
                }
            }

            delete[] region_damage1;
            delete[] region_damage2;
        }

        delete[] in_flow;
        delete[] out_flow;
        free_double_array(flows);
        for (int i = 0; i < sectors_size; i++) {
            delete[] in_flow_by_sector[i];
        }
        delete[] in_flow_by_sector;
        delete[] total_output;

        snprintf(q, 512, "update visualizations set updated=now() where (name='GAP1' or name='GAP2') and year=%d", year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }
    }

    return disconnect();
}
Beispiel #21
0
int spimem_write_h(uint8_t spi_chip, uint32_t addr, uint8_t* data_buff, uint32_t size)
{
	uint32_t size1, size2, low, dirty = 0, page, sect_num, check;
		
	if (size > 256)				// Invalid size to write.
		return -2;
	if (addr > 0xFFFFF)			// Invalid address to write to.
		return -2;
	
	low = addr & 0x000000FF;
	if ((size + low) > 256)		// Requested write flows into a second page.
	{
		size1 = 256 - low;
		size2 = size - size1;
	}
	else
	{
		size1 = size;
		size2 = 0;
	}
	if ((addr + (size - 1)) > 0xFFFFF)	// Address too high, can't write all requested bytes.
	{
		size1 = 256 - low;
		size2 = 0;
	}

	if (xSemaphoreTake(Spi0_Mutex, (TickType_t) 1) == pdTRUE)	// Only Block for a single tick.
	{
		enter_atomic();											// Atomic operation begins.
		
		if(ready_for_command_h(spi_chip) != 1)
		{
			exit_atomic();
			xSemaphoreGive(Spi0_Mutex);
			return -4;
		}
					
		page = get_page(addr);
		dirty = check_page(page);
		if(dirty)
		{
			sect_num = get_sector(addr);
			check = load_sector_into_spibuffer(spi_chip, sect_num);			// if check != 4096, FAILURE_RECOVERY.
			check = update_spibuffer_with_new_page(addr, data_buff, size1);	// if check != size1, FAILURE_RECOVERY.
			check = erase_sector_on_chip(spi_chip, sect_num);				// FAILURE_RECOVERY
			check = write_sector_back_to_spimem(spi_chip);					// FAILURE_RECOVERY
		}
		else
		{		
			if(write_page_h(spi_chip, addr, data_buff, size1) != 1)
			{
				exit_atomic();						// Atomic operation ends.
				xSemaphoreGive(Spi0_Mutex);
				return -1;
			}
		}
		if(size2)	// Requested write flows into a second page.
		{
			page = get_page(addr + size1);
			dirty = check_page(page);
			
			if(ready_for_command_h(spi_chip) != 1)
			{
				exit_atomic();
				xSemaphoreGive(Spi0_Mutex);
				return size1;
			}
			if(dirty)
			{
				sect_num = get_sector(addr + size1);
				check = load_sector_into_spibuffer(spi_chip, sect_num);						// if check != 4096, FAILURE_RECOVERY.
				if(check != 4096)
					return -4;
				check = update_spibuffer_with_new_page(addr + size1, (data_buff + size1), size2);	// if check != size1, FAILURE_RECOVERY.
				if(check != size1)
					return -4;
				check = erase_sector_on_chip(spi_chip, sect_num);				// FAILURE_RECOVERY
				if(check != 1)
					return -4;
				check = write_sector_back_to_spimem(spi_chip);					// FAILURE_RECOVERY
				if(check == 0xFFFFFFFF)
					return -4;
			}
			else
			{		
				if(write_page_h(spi_chip, addr + size1, (data_buff + size1), size2) != 1)
				{
					exit_atomic();
					xSemaphoreGive(Spi0_Mutex);
					return size1;
				}
			}
		}
		
		exit_atomic();
		xSemaphoreGive(Spi0_Mutex);
		return (size1 + size2);	
	}

	else
		return -3;												// SPI0 is currently being used or there is an error.
}
Beispiel #22
0
bool TF20::process_cmd()
{
	int drv, trk, sec, dst;
	uint8 *sctr, *sctw;
	
	switch(bufr[3]) {
	case FNC_RESET_P:
	case FNC_RESET_M:
		SET_HEAD(0);
		SET_CODE(ERR_SUCCESS);
		return true;
		
	case FNC_READ:
		drv = (bufr[1] == DID_FIRST) ? 0 : (bufr[1] == DID_SECOND) ? 2 : 4;
		drv += bufr[7] - 1;
		trk = bufr[8];
		sec = bufr[9];
		if(!disk_inserted(drv)) {
			// drive error
			SET_HEAD(0x80);
			for(int i = 0; i < 128; i++) {
				SET_DATA(0xff);
			}
			SET_CODE(ERR_DRIVE);
			return true;
		}
		if((sctr = get_sector(drv, trk, sec)) == NULL) {
			// read error
			SET_HEAD(0x80);
			for(int i = 0; i < 128; i++) {
				SET_DATA(0xff);
			}
			SET_CODE(ERR_READ);
			return true;
		}
		SET_HEAD(0x80);
		for(int i = 0; i < 128; i++) {
			SET_DATA(sctr[i]);
		}
		SET_CODE(ERR_SUCCESS);
		return true;
		
	case FNC_WRITE:
		drv = (bufr[1] == DID_FIRST) ? 0 : (bufr[1] == DID_SECOND) ? 2 : 4;
		drv += bufr[7] - 1;
		trk = bufr[8];
		sec = bufr[9];
		if(!disk_inserted(drv)) {
			// drive error
			SET_HEAD(0);
			SET_CODE(ERR_DRIVE);
			return true;
		}
		if(disk_protected(drv)) {
			// write protect
			SET_HEAD(0);
			SET_CODE(ERR_PROTECTED);
			return true;
		}
		if((sctw = get_sector(drv, trk, sec)) == NULL) {
			// write error
			SET_HEAD(0);
			SET_CODE(ERR_WRITE);
			return true;
		}
		// dont care write type
		for(int i = 0; i < 128; i++) {
			sctw[i] = bufr[11 + i];
		}
		SET_HEAD(0);
		SET_CODE(ERR_SUCCESS);
		return true;
		
	case FNC_WRITEHST:
		SET_HEAD(0);
		SET_CODE(ERR_SUCCESS);
		return true;
		
	case FNC_COPY:
		drv = (bufr[1] == DID_FIRST) ? 0 : (bufr[1] == DID_SECOND) ? 2 : 4;
		drv += bufr[7] - 1;
		dst = (drv & ~1) | (~drv & 1);
		if(!disk_inserted(drv)) {
			// drive error
			SET_HEAD(0);
			SET_CODE(ERR_DRIVE);
			return true;
		}
		if(!disk_inserted(dst)) {
			// drive error
			SET_HEAD(0);
			SET_CODE(ERR_DRIVE);
			return true;
		}
		if(disk_protected(dst)) {
			// write protect
			SET_HEAD(0);
			SET_CODE(ERR_PROTECTED);
			return true;
		}
		for(trk = 0; trk < 40; trk++) {
			for(sec = 1; sec <= 64; sec++) {
				if((sctr = get_sector(drv, trk, sec)) == NULL) {
					// read error
					SET_HEAD(0);
					SET_CODE(ERR_READ);
					return true;
				}
				if((sctw = get_sector(dst, trk, sec)) == NULL) {
					// write error
					SET_HEAD(0);
					SET_CODE(ERR_WRITE);
					return true;
				}
				memcpy(sctw, sctr, 128);
			}
			SET_HEAD(2);
			SET_DATA(trk == 39 ? 0xff : 0);		// high-order
			SET_DATA(trk == 39 ? 0xff : trk);	// low-order
			SET_CODE(ERR_SUCCESS);
		}
		return true;
		
	case FNC_FORMAT:
		drv = (bufr[1] == DID_FIRST) ? 0 : (bufr[1] == DID_SECOND) ? 2 : 4;
		drv += bufr[7] - 1;
		if(!disk_inserted(drv)) {
			// drive error
			SET_HEAD(0);
			SET_CODE(ERR_DRIVE);
			return true;
		}
		if(disk_protected(drv)) {
			// write protect
			SET_HEAD(0);
			SET_CODE(ERR_PROTECTED);
			return true;
		}
		for(trk = 0; trk < 40; trk++) {
			for(sec = 1; sec <= 64; sec++) {
				if((sctw = get_sector(drv, trk, sec)) == NULL) {
					// write error
					SET_HEAD(0);
					SET_CODE(ERR_WRITE);
					return true;
				}
				memset(sctw, 0xe5, 128);
			}
			SET_HEAD(2);
			SET_DATA(trk == 39 ? 0xff : 0);		// high-order
			SET_DATA(trk == 39 ? 0xff : trk);	// low-order
			SET_CODE(ERR_SUCCESS);
		}
		return true;
	}
	// unknown command
	return false;
}
int main(int argc, char* argv[]) {
    char q[512];
    MYSQL_ROW row;
    MYSQL_RES* res;

    int err = init_network();
    if (err) {
        return err;
    }

    for (int year = 1990; year <= 2011; year++) {
        std::cout << "Querying " << year << "\n";

        snprintf(q, 512, "select count(value) from entries where year=%d and inserted>(select updated from visualizations where name='Flow Centrality' and year=%d)", year, year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }
        res = mysql_use_result(mysql);
        if((row = mysql_fetch_row(res)) == 0 || atoi(row[0]) == 0) {
            mysql_free_result(res);
            continue;
        }
        mysql_free_result(res);

        err = read_network(year);
        if (err) {
            return err;
        }

        std::cout << "Calculating " << year << "\n";
        err = disconnect();
        if (err) {
            return err;
        }

        Basetype* betweenness = create_array(0);
        Basetype* in_flow = create_array(0);
        Basetype* out_flow = create_array(0);
        for (int v = 0; v < network_size; v++) {
            for (int w = 0; w < network_size; w++) {
                in_flow[v] += flows[w][v];
                out_flow[v] += flows[v][w];
            }
        }

        // Algorithm according to "A space-efficient parallel algorithm for computing betweenness centrality in distributed memory", p. 2
        int s;
    #pragma omp parallel default(none) shared(betweenness, flows, network_size, in_flow, std::cerr)
        {
    #pragma omp for schedule(guided) nowait
            for (s = 0; s < network_size; s++) {
                std::vector<int> S;
                std::queue<int> PQ;
                BasetypeInt* sigma;
                Basetype* delta;
                Basetype* dist;
                BasetypeInt** P;
                BasetypeInt* P_size;
                Basetype* pipe;
                sigma = create_array_int(0);
                sigma[s] = 1;
                delta = create_array(0);
                P = create_double_int_array(0);
                P_size = create_array_int(0);
                dist = create_array(-1);
                dist[s] = 0;
                pipe = create_array(0);
                pipe[s] = -1;
                PQ.push(s);
                while (!PQ.empty()) {
                    int v = PQ.front();
                    PQ.pop();
                    for (std::vector<int>::iterator it = S.begin(); it != S.end(); it++) {
                        if (*it == v) {
                            S.erase(it);
                            break;
                        }
                    }
                    S.push_back(v);
                    for (int w = 0; w < network_size; w++) {
                        if (w != v && w != s && flows[v][w] > 0) {
                            Basetype c_v_w = flows[v][w];
                            Basetype new_pipe;
                            if (pipe[v] < 0) {
                                new_pipe = c_v_w;
                            } else {
                                new_pipe = std::min(pipe[v], c_v_w);
                            }
                            if (pipe[w] < new_pipe || (pipe[w] == new_pipe && dist[w] > dist[v] + 1)) { // Better best path via v
                                PQ.push(w);
                                pipe[w] = new_pipe;
                                dist[w] = dist[v] + 1;
                                sigma[w] = 0;
                                P_size[w] = 0;
                            }
                            if (pipe[w] == new_pipe && dist[w] == dist[v] + 1 && !in_array(v,P[w],P_size[w])) { // Some best path via v
                                sigma[w] += sigma[v];
                                P[w][P_size[w]] = v;
                                P_size[w]++;
                            }
                        }
                    }
                }

                while (!S.empty()) {
                    int w = S.back();
                    S.pop_back();

                    for (int v_index = 0; v_index < P_size[w]; v_index++) {
                        int v = P[w][v_index];
                        delta[v] += ((1 + delta[w]) * (Basetype) sigma[v]) / (Basetype) sigma[w];
                    }

                    if (w != s) {
                        #pragma omp atomic
                            betweenness[w] += delta[w];
                    }
                }
                delete[] delta;
                delete[] sigma;
                delete[] dist;
                delete[] P_size;
                free_double_int_array(P);
                delete[] pipe;
            }
        }

        err = connect();
        if (err) {
            return err;
        }

        snprintf(q, 512, "delete from visualization_data where visualization in (select id from visualizations where name='Flow Centrality' and year=%d)", year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }

        snprintf(q, 512, "select id from visualizations where name='Flow Centrality' and year=%d", year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }
        res = mysql_use_result(mysql);
        row = mysql_fetch_row(res);
        int id = atoi(row[0]);
        mysql_free_result(res);

        std::stringstream query("insert into visualization_data (visualization, sector_from, region_from, value) values ", std::ios_base::app | std::ios_base::out);
        for (int js = 0; js < network_size; js++) {
            if (js > 0) {
                query << ",";
            }
            query << "(" << id << ",'" << sectors[get_sector(js)] << "','" << regions[get_region(js)] << "'," << betweenness[js] << ")";
        }
        if (mysql_query(mysql, query.str().c_str())) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }

        snprintf(q, 512, "update visualizations set updated=now() where name='Flow Centrality' and year=%d", year);
        if (mysql_query(mysql, q)) {
            std::cerr << mysql_error(mysql) << "\n";
            return -2;
        }

        delete[] betweenness;
        free_double_array(flows);

    }

    return 0;
}
Beispiel #24
0
/* ----------------------------------------------------------------------------
 * Handles the events for the area editor.
 */
void area_editor::handle_controls(const ALLEGRO_EVENT &ev) {

    if(fade_mgr.is_fading()) return;
    
    gui->handle_event(ev);
    
    //Update mouse cursor in world coordinates.
    if(
        ev.type == ALLEGRO_EVENT_MOUSE_AXES ||
        ev.type == ALLEGRO_EVENT_MOUSE_WARPED ||
        ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN ||
        ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP
    ) {
        mouse_cursor_x =
            ev.mouse.x / cam_zoom - cam_x - (gui_x / 2 / cam_zoom);
        mouse_cursor_y =
            ev.mouse.y / cam_zoom - cam_y - (scr_h / 2 / cam_zoom);
        lafi::widget* wum;
        if(!is_mouse_in_gui(ev.mouse.x, ev.mouse.y)) {
            wum = NULL;
        } else {
            wum = gui->get_widget_under_mouse(ev.mouse.x, ev.mouse.y);
        }
        ((lafi::label*) gui->widgets["lbl_status_bar"])->text =
            (
                wum ?
                wum->description :
                "(" + i2s(mouse_cursor_x) + "," + i2s(mouse_cursor_y) + ")"
            );
    }
    
    
    //Moving vertexes, camera, etc.
    if(ev.type == ALLEGRO_EVENT_MOUSE_AXES) {
    
        if(
            !is_mouse_in_gui(ev.mouse.x, ev.mouse.y)
            && moving_thing == INVALID && sec_mode != ESM_TEXTURE_VIEW &&
            mode != EDITOR_MODE_OBJECTS
        ) {
            on_sector = get_sector(mouse_cursor_x, mouse_cursor_y, NULL, false);
        } else {
            on_sector = NULL;
        }
        
        //Move guide.
        if(sec_mode == ESM_GUIDE_MOUSE) {
        
            if(holding_m1) {
                guide_x += ev.mouse.dx / cam_zoom;
                guide_y += ev.mouse.dy / cam_zoom;
                
            } else if(holding_m2) {
            
                float new_w = guide_w + ev.mouse.dx / cam_zoom;
                float new_h = guide_h + ev.mouse.dy / cam_zoom;
                
                if(guide_aspect_ratio) {
                    //Find the most significant change.
                    if(ev.mouse.dx != 0 || ev.mouse.dy != 0) {
                        bool most_is_width =
                            fabs((double) ev.mouse.dx) >
                            fabs((double) ev.mouse.dy);
                            
                        if(most_is_width) {
                            float ratio = guide_h / guide_w;
                            guide_w = new_w;
                            guide_h = new_w * ratio;
                        } else {
                            float ratio = guide_w / guide_h;
                            guide_h = new_h;
                            guide_w = new_h * ratio;
                        }
                    }
                } else {
                    guide_w = new_w;
                    guide_h = new_h;
                }
                
            }
            
            guide_to_gui();
            
        } else if(holding_m2) {
            //Move camera.
            cam_x += ev.mouse.dx / cam_zoom;
            cam_y += ev.mouse.dy / cam_zoom;
        }
        
        //Move thing.
        if(moving_thing != INVALID) {
            if(mode == EDITOR_MODE_SECTORS) {
                vertex* v_ptr = cur_area_data.vertexes[moving_thing];
                v_ptr->x = snap_to_grid(mouse_cursor_x);
                v_ptr->y = snap_to_grid(mouse_cursor_y);
            } else if(mode == EDITOR_MODE_OBJECTS) {
                mob_gen* m_ptr = cur_area_data.mob_generators[moving_thing];
                m_ptr->x = snap_to_grid(mouse_cursor_x);
                m_ptr->y = snap_to_grid(mouse_cursor_y);
            } else if(mode == EDITOR_MODE_PATHS) {
                path_stop* s_ptr = cur_area_data.path_stops[moving_thing];
                s_ptr->x = snap_to_grid(mouse_cursor_x);
                s_ptr->y = snap_to_grid(mouse_cursor_y);
                s_ptr->calculate_dists();
                path_preview_timeout.start(false);
            } else if(mode == EDITOR_MODE_SHADOWS) {
                tree_shadow* s_ptr = cur_area_data.tree_shadows[moving_thing];
                s_ptr->x = snap_to_grid(mouse_cursor_x - moving_thing_x);
                s_ptr->y = snap_to_grid(mouse_cursor_y - moving_thing_y);
                shadow_to_gui();
            }
            
            made_changes = true;
        }
        
        //Move path checkpoints.
        if(moving_path_preview_checkpoint != -1) {
            path_preview_checkpoints_x[moving_path_preview_checkpoint] =
                snap_to_grid(mouse_cursor_x);
            path_preview_checkpoints_y[moving_path_preview_checkpoint] =
                snap_to_grid(mouse_cursor_y);
            path_preview_timeout.start(false);
        }
        
        
        if(ev.mouse.dz != 0 && !is_mouse_in_gui(ev.mouse.x, ev.mouse.y)) {
            //Zoom.
            float new_zoom = cam_zoom + (cam_zoom * ev.mouse.dz * 0.1);
            new_zoom = max(ZOOM_MIN_LEVEL_EDITOR, new_zoom);
            new_zoom = min(ZOOM_MAX_LEVEL_EDITOR, new_zoom);
            float new_mc_x =
                ev.mouse.x / new_zoom - cam_x - (gui_x / 2 / new_zoom);
            float new_mc_y =
                ev.mouse.y / new_zoom - cam_y - (scr_h / 2 / new_zoom);
                
            cam_x -= (mouse_cursor_x - new_mc_x);
            cam_y -= (mouse_cursor_y - new_mc_y);
            mouse_cursor_x = new_mc_x;
            mouse_cursor_y = new_mc_y;
            cam_zoom = new_zoom;
        }
        
        if(sec_mode == ESM_NEW_SECTOR) {
            new_sector_valid_line =
                is_new_sector_line_valid(
                    snap_to_grid(mouse_cursor_x),
                    snap_to_grid(mouse_cursor_y)
                );
        }
        
        
    } else if(
        ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN &&
        !is_mouse_in_gui(ev.mouse.x, ev.mouse.y)
    ) {
        //Clicking.
        
        if(ev.mouse.button == 1) holding_m1 = true;
        else if(ev.mouse.button == 2) holding_m2 = true;
        else if(ev.mouse.button == 3) cam_zoom = 1.0;
        
        if(ev.mouse.button != 1) return;
        
        //If the user was editing, save it.
        if(mode == EDITOR_MODE_SECTORS) {
            gui_to_sector();
        } else if(mode == EDITOR_MODE_OBJECTS) {
            gui_to_mob();
        } else if(mode == EDITOR_MODE_SHADOWS) {
            gui_to_shadow();
        }
        
        //Sector-related clicking.
        if(sec_mode == ESM_NONE && mode == EDITOR_MODE_SECTORS) {
        
            moving_thing = INVALID;
            
            edge* clicked_edge_ptr = NULL;
            size_t clicked_edge_nr = INVALID;
            bool created_vertex = false;
            
            for(size_t e = 0; e < cur_area_data.edges.size(); ++e) {
                edge* e_ptr = cur_area_data.edges[e];
                
                if(!is_edge_valid(e_ptr)) continue;
                
                if(
                    circle_intersects_line(
                        mouse_cursor_x, mouse_cursor_y, 8 / cam_zoom,
                        e_ptr->vertexes[0]->x, e_ptr->vertexes[0]->y,
                        e_ptr->vertexes[1]->x, e_ptr->vertexes[1]->y
                    )
                ) {
                    clicked_edge_ptr = e_ptr;
                    clicked_edge_nr = e;
                    break;
                }
            }
            
            if(double_click_time == 0) double_click_time = 0.5;
            else if(clicked_edge_ptr) {
                //Create a new vertex.
                double_click_time = 0;
                
                //New vertex, on the split point.
                //TODO create it on the edge, not on the cursor.
                vertex* new_v_ptr = new vertex(mouse_cursor_x, mouse_cursor_y);
                cur_area_data.vertexes.push_back(new_v_ptr);
                
                //New edge, copied from the original one.
                edge* new_e_ptr = new edge(*clicked_edge_ptr);
                cur_area_data.edges.push_back(new_e_ptr);
                
                //Save the original end vertex for later.
                vertex* end_v_ptr = clicked_edge_ptr->vertexes[1];
                
                //Set vertexes on the new and original edges.
                new_e_ptr->vertex_nrs[0] = cur_area_data.vertexes.size() - 1;
                new_e_ptr->vertexes[0] = new_v_ptr;
                clicked_edge_ptr->vertex_nrs[1] = new_e_ptr->vertex_nrs[0];
                clicked_edge_ptr->vertexes[1] = new_v_ptr;
                
                //Set sectors on the new edge.
                if(new_e_ptr->sectors[0]) {
                    new_e_ptr->sectors[0]->edge_nrs.push_back(
                        cur_area_data.edges.size() - 1
                    );
                    new_e_ptr->sectors[0]->edges.push_back(new_e_ptr);
                }
                if(new_e_ptr->sectors[1]) {
                    new_e_ptr->sectors[1]->edge_nrs.push_back(
                        cur_area_data.edges.size() - 1
                    );
                    new_e_ptr->sectors[1]->edges.push_back(new_e_ptr);
                }
                
                //Set edges of the new vertex.
                new_v_ptr->edge_nrs.push_back(cur_area_data.edges.size() - 1);
                new_v_ptr->edge_nrs.push_back(clicked_edge_nr);
                new_v_ptr->edges.push_back(new_e_ptr);
                new_v_ptr->edges.push_back(clicked_edge_ptr);
                
                //Update edge data on the end vertex of the original edge
                //(it now links to the new edge, not the old).
                for(size_t ve = 0; ve < end_v_ptr->edges.size(); ++ve) {
                    if(end_v_ptr->edges[ve] == clicked_edge_ptr) {
                        end_v_ptr->edges[ve] =
                            new_e_ptr;
                        end_v_ptr->edge_nrs[ve] =
                            cur_area_data.edges.size() - 1;
                        break;
                    }
                }
                
                //Start dragging the new vertex.
                moving_thing = cur_area_data.vertexes.size() - 1;
                
                created_vertex = true;
                made_changes = true;
            }
            
            //Find a vertex to drag.
            if(!created_vertex) {
                for(size_t v = 0; v < cur_area_data.vertexes.size(); ++v) {
                    if(
                        dist(
                            mouse_cursor_x, mouse_cursor_y,
                            cur_area_data.vertexes[v]->x,
                            cur_area_data.vertexes[v]->y
                        ) <= 6.0 / cam_zoom
                    ) {
                        moving_thing = v;
                        break;
                    }
                }
            }
            
            //Find a sector to select.
            if(moving_thing == INVALID) {
                cur_sector =
                    get_sector(mouse_cursor_x, mouse_cursor_y, NULL, false);
                sector_to_gui();
            }
            
            
        } else if(sec_mode == ESM_NONE && mode == EDITOR_MODE_OBJECTS) {
            //Object-related clicking.
            
            cur_mob = NULL;
            moving_thing = INVALID;
            for(size_t m = 0; m < cur_area_data.mob_generators.size(); ++m) {
                mob_gen* m_ptr = cur_area_data.mob_generators[m];
                float radius =
                    m_ptr->type ? m_ptr->type->radius == 0 ? 16 :
                    m_ptr->type->radius : 16;
                if(
                    dist(m_ptr->x, m_ptr->y, mouse_cursor_x, mouse_cursor_y) <=
                    radius
                ) {
                
                    cur_mob = m_ptr;
                    moving_thing = m;
                    break;
                }
            }
            mob_to_gui();
            
        } else if(sec_mode == ESM_NONE && mode == EDITOR_MODE_PATHS) {
            //Path-related clicking.
            
            cur_stop = NULL;
            moving_thing = INVALID;
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                if(
                    dist(s_ptr->x, s_ptr->y, mouse_cursor_x, mouse_cursor_y)
                    <= STOP_RADIUS
                ) {
                
                    cur_stop = s_ptr;
                    moving_thing = s;
                    break;
                }
            }
            
            moving_path_preview_checkpoint = -1;
            if(show_path_preview) {
                for(unsigned char c = 0; c < 2; ++c) {
                    if(
                        bbox_check(
                            path_preview_checkpoints_x[c],
                            path_preview_checkpoints_y[c],
                            mouse_cursor_x, mouse_cursor_y,
                            PATH_PREVIEW_CHECKPOINT_RADIUS / cam_zoom
                        )
                    ) {
                        moving_path_preview_checkpoint = c;
                        break;
                    }
                }
            }
            
        } else if(sec_mode == ESM_NONE && mode == EDITOR_MODE_SHADOWS) {
            //Shadow-related clicking.
            
            cur_shadow = NULL;
            moving_thing = INVALID;
            for(size_t s = 0; s < cur_area_data.tree_shadows.size(); ++s) {
            
                tree_shadow* s_ptr = cur_area_data.tree_shadows[s];
                float min_x, min_y, max_x, max_y;
                get_shadow_bounding_box(s_ptr, &min_x, &min_y, &max_x, &max_y);
                
                if(
                    mouse_cursor_x >= min_x && mouse_cursor_x <= max_x &&
                    mouse_cursor_y >= min_y && mouse_cursor_y <= max_y
                ) {
                    cur_shadow = s_ptr;
                    moving_thing = s;
                    moving_thing_x = mouse_cursor_x - s_ptr->x;
                    moving_thing_y = mouse_cursor_y - s_ptr->y;
                    break;
                }
            }
            shadow_to_gui();
            
        }
        
        if(sec_mode == ESM_NEW_SECTOR) {
            //Next vertex in a new sector.
            float hotspot_x = snap_to_grid(mouse_cursor_x);
            float hotspot_y = snap_to_grid(mouse_cursor_y);
            new_sector_valid_line =
                is_new_sector_line_valid(
                    snap_to_grid(mouse_cursor_x),
                    snap_to_grid(mouse_cursor_y)
                );
                
            if(new_sector_valid_line) {
                if(
                    !new_sector_vertexes.empty() &&
                    dist(
                        hotspot_x, hotspot_y,
                        new_sector_vertexes[0]->x,
                        new_sector_vertexes[0]->y
                    ) <= VERTEX_MERGE_RADIUS
                ) {
                    //Back to the first vertex.
                    sec_mode = ESM_NONE;
                    create_sector();
                    sector_to_gui();
                    made_changes = true;
                } else {
                    //Add a new vertex.
                    vertex* merge =
                        get_merge_vertex(
                            hotspot_x, hotspot_y,
                            cur_area_data.vertexes,
                            VERTEX_MERGE_RADIUS / cam_zoom
                        );
                    if(merge) {
                        new_sector_vertexes.push_back(
                            new vertex(merge->x, merge->y)
                        );
                    } else {
                        new_sector_vertexes.push_back(
                            new vertex(hotspot_x, hotspot_y)
                        );
                    }
                }
            }
            
            
        } else if(sec_mode == ESM_NEW_OBJECT) {
            //Create a mob where the cursor is.
            
            sec_mode = ESM_NONE;
            float hotspot_x = snap_to_grid(mouse_cursor_x);
            float hotspot_y = snap_to_grid(mouse_cursor_y);
            
            cur_area_data.mob_generators.push_back(
                new mob_gen(hotspot_x, hotspot_y)
            );
            
            cur_mob = cur_area_data.mob_generators.back();
            mob_to_gui();
            made_changes = true;
            
        } else if(sec_mode == ESM_DUPLICATE_OBJECT) {
            //Duplicate the current mob to where the cursor is.
            
            sec_mode = ESM_NONE;
            
            if(cur_mob) {
                float hotspot_x = snap_to_grid(mouse_cursor_x);
                float hotspot_y = snap_to_grid(mouse_cursor_y);
                
                mob_gen* new_mg = new mob_gen(*cur_mob);
                new_mg->x = hotspot_x;
                new_mg->y = hotspot_y;
                cur_area_data.mob_generators.push_back(
                    new_mg
                );
                
                cur_mob = new_mg;
                mob_to_gui();
                made_changes = true;
            }
            
        } else if(sec_mode == ESM_NEW_STOP) {
            //Create a new stop where the cursor is.
            
            float hotspot_x = snap_to_grid(mouse_cursor_x);
            float hotspot_y = snap_to_grid(mouse_cursor_y);
            
            cur_area_data.path_stops.push_back(
                new path_stop(hotspot_x, hotspot_y, vector<path_link>())
            );
            
            cur_stop = cur_area_data.path_stops.back();
            made_changes = true;
            
            
        } else if (sec_mode == ESM_NEW_LINK1 || sec_mode == ESM_NEW_1WLINK1) {
            //Pick a stop to start the link on.
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                
                if(
                    dist(mouse_cursor_x, mouse_cursor_y, s_ptr->x, s_ptr->y) <=
                    STOP_RADIUS
                ) {
                    new_link_first_stop = s_ptr;
                    sec_mode =
                        sec_mode == ESM_NEW_LINK1 ? ESM_NEW_LINK2 :
                        ESM_NEW_1WLINK2;
                    break;
                }
            }
            
            path_preview_timeout.start(false);
            made_changes = true;
            
        } else if (sec_mode == ESM_NEW_LINK2 || sec_mode == ESM_NEW_1WLINK2) {
            //Pick a stop to end the link on.
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                
                if(
                    dist(mouse_cursor_x, mouse_cursor_y, s_ptr->x, s_ptr->y) <=
                    STOP_RADIUS
                ) {
                
                    if(new_link_first_stop == s_ptr) continue;
                    
                    //Check if these two stops already have a link.
                    //Delete it if so.
                    for(
                        size_t l = 0; l < new_link_first_stop->links.size();
                        ++l
                    ) {
                        if(new_link_first_stop->links[l].end_ptr == s_ptr) {
                            new_link_first_stop->links.erase(
                                new_link_first_stop->links.begin() + l
                            );
                            break;
                        }
                    }
                    for(size_t l = 0; l < s_ptr->links.size(); ++l) {
                        if(s_ptr->links[l].end_ptr == new_link_first_stop) {
                            s_ptr->links.erase(s_ptr->links.begin() + l);
                            break;
                        }
                    }
                    
                    
                    new_link_first_stop->links.push_back(
                        path_link(s_ptr, s)
                    );
                    
                    if(sec_mode == ESM_NEW_LINK2) {
                        s_ptr->links.push_back(
                            path_link(new_link_first_stop, INVALID)
                        );
                        s_ptr->fix_nrs(cur_area_data);
                    }
                    
                    new_link_first_stop->calculate_dists();
                    
                    sec_mode =
                        sec_mode == ESM_NEW_LINK2 ? ESM_NEW_LINK1 :
                        ESM_NEW_1WLINK1;
                    break;
                }
            }
            
            path_preview_timeout.start(false);
            made_changes = true;
            
        } else if(sec_mode == ESM_DEL_STOP) {
            //Pick a stop to delete.
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                
                if(
                    dist(mouse_cursor_x, mouse_cursor_y, s_ptr->x, s_ptr->y) <=
                    STOP_RADIUS
                ) {
                
                    //Check all links to this stop.
                    for(
                        size_t s2 = 0; s2 < cur_area_data.path_stops.size();
                        ++s2
                    ) {
                        path_stop* s2_ptr = cur_area_data.path_stops[s2];
                        for(size_t l = 0; l < s2_ptr->links.size(); ++l) {
                            if(s2_ptr->links[l].end_ptr == s_ptr) {
                                s2_ptr->links.erase(s2_ptr->links.begin() + l);
                                break;
                            }
                        }
                    }
                    
                    //Finally, delete the stop.
                    delete s_ptr;
                    cur_area_data.path_stops.erase(
                        cur_area_data.path_stops.begin() + s
                    );
                    break;
                }
            }
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                cur_area_data.path_stops[s]->fix_nrs(cur_area_data);
            }
            
            path_preview.clear();
            path_preview_timeout.start(false);
            made_changes = true;
            
        } else if(sec_mode == ESM_DEL_LINK) {
            //Pick a link to delete.
            
            bool deleted = false;
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                
                for(size_t s2 = 0; s2 < s_ptr->links.size(); ++s2) {
                    path_stop* s2_ptr = s_ptr->links[s2].end_ptr;
                    if(
                        circle_intersects_line(
                            mouse_cursor_x, mouse_cursor_y, 8 / cam_zoom,
                            s_ptr->x, s_ptr->y,
                            s2_ptr->x, s2_ptr->y
                        )
                    ) {
                    
                        s_ptr->links.erase(s_ptr->links.begin() + s2);
                        
                        for(size_t s3 = 0; s3 < s2_ptr->links.size(); ++s3) {
                            if(s2_ptr->links[s3].end_ptr == s_ptr) {
                                s2_ptr->links.erase(
                                    s2_ptr->links.begin() + s3
                                );
                                break;
                            }
                        }
                        
                        deleted = true;
                        break;
                    }
                }
                
                if(deleted) break;
            }
            
            path_preview.clear();
            path_preview_timeout.start(false);
            made_changes = true;
            
        } else if(sec_mode == ESM_NEW_SHADOW) {
            //Create a new shadow where the cursor is.
            
            sec_mode = ESM_NONE;
            float hotspot_x = snap_to_grid(mouse_cursor_x);
            float hotspot_y = snap_to_grid(mouse_cursor_y);
            
            tree_shadow* new_shadow = new tree_shadow(hotspot_x, hotspot_y);
            new_shadow->bitmap = bmp_error;
            
            cur_area_data.tree_shadows.push_back(new_shadow);
            
            cur_shadow = new_shadow;
            shadow_to_gui();
            made_changes = true;
            
        }
        
        
    } else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
        //Mouse button release.
        
        if(ev.mouse.button == 1) holding_m1 = false;
        else if(ev.mouse.button == 2) holding_m2 = false;
        
        if(
            ev.mouse.button == 1 &&
            mode == EDITOR_MODE_SECTORS && sec_mode == ESM_NONE &&
            moving_thing != INVALID
        ) {
            //Release the vertex.
            
            vertex* moved_v_ptr = cur_area_data.vertexes[moving_thing];
            vertex* final_vertex = moved_v_ptr;
            
            unordered_set<sector*> affected_sectors;
            
            //Check if we should merge.
            for(size_t v = 0; v < cur_area_data.vertexes.size(); ++v) {
                vertex* dest_v_ptr = cur_area_data.vertexes[v];
                if(dest_v_ptr == moved_v_ptr) continue;
                
                if(
                    dist(
                        moved_v_ptr->x, moved_v_ptr->y,
                        dest_v_ptr->x, dest_v_ptr->y
                    ) <= (VERTEX_MERGE_RADIUS / cam_zoom)
                ) {
                    merge_vertex(
                        moved_v_ptr, dest_v_ptr, &affected_sectors
                    );
                    final_vertex = dest_v_ptr;
                    break;
                }
            }
            
            //Finally, re-triangulate the affected sectors.
            for(size_t e = 0; e < final_vertex->edges.size(); ++e) {
                edge* e_ptr = final_vertex->edges[e];
                for(size_t s = 0; s < 2; ++s) {
                    if(e_ptr->sectors[s]) {
                        affected_sectors.insert(e_ptr->sectors[s]);
                    }
                }
            }
            for(
                auto s = affected_sectors.begin();
                s != affected_sectors.end(); ++s
            ) {
                if(!(*s)) continue;
                triangulate(*s);
            }
            
            //If somewhere along the line, the current sector
            //got marked for deletion, unselect it.
            if(cur_sector) {
                if(cur_sector->edges.empty()) {
                    cur_sector = NULL;
                    sector_to_gui();
                }
            }
            
            //Check if the edge's vertexes intersect with any other edges.
            //If so, they're marked with red.
            check_edge_intersections(moved_v_ptr);
            
            moving_thing = INVALID;
            
            
            
        } else if(
            ev.mouse.button == 1 && sec_mode == ESM_NONE &&
            moving_thing != INVALID
        ) {
            //Release thing.
            
            moving_thing = INVALID;
            
        }
        
        moving_path_preview_checkpoint = -1;
        
        
    } else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
        //Key press.
        
        if(
            ev.keyboard.keycode == ALLEGRO_KEY_LSHIFT ||
            ev.keyboard.keycode == ALLEGRO_KEY_RSHIFT
        ) {
            shift_pressed = true;
        } else if(ev.keyboard.keycode == ALLEGRO_KEY_F1) {
            debug_edge_nrs = !debug_edge_nrs;
        } else if(ev.keyboard.keycode == ALLEGRO_KEY_F2) {
            debug_sector_nrs = !debug_sector_nrs;
        } else if(ev.keyboard.keycode == ALLEGRO_KEY_F3) {
            debug_vertex_nrs = !debug_vertex_nrs;
        } else if(ev.keyboard.keycode == ALLEGRO_KEY_F4) {
            debug_triangulation = !debug_triangulation;
        }
        
        
    } else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
        //Key release.
        
        if(
            ev.keyboard.keycode == ALLEGRO_KEY_LSHIFT ||
            ev.keyboard.keycode == ALLEGRO_KEY_RSHIFT
        ) {
            shift_pressed = false;
        }
    }
}
Beispiel #25
0
void extract_bad_sector_map(byte * buffer)
{
	TRACE_FUN(8, "extract_bad_sector_map");

	/*  Fill the bad sector map with the contents of buffer.
	 */
	if (format_code == 4) {
		/* QIC-3010/3020 and wide QIC-80 tapes no longer have a failed
		 * sector log but use this area to extend the bad sector map.
		 */
		memcpy(bad_sector_map, buffer + 256, sizeof(bad_sector_map));
	} else {
		/* non-wide QIC-80 tapes have a failed sector log area that
		 * mustn't be included in the bad sector map.
		 */
		memcpy(bad_sector_map, buffer + 256 + FAILED_SECTOR_LOG_SIZE,
		       sizeof(bad_sector_map) - FAILED_SECTOR_LOG_SIZE);
	}
#if 0
	/* for testing of bad sector handling at end of tape
	 */
	((unsigned long *) bad_sector_map)[segments_per_track * tracks_per_tape - 3] = 0x000003e0;
	((unsigned long *) bad_sector_map)[segments_per_track * tracks_per_tape - 2] = 0xff3fffff;
	((unsigned long *) bad_sector_map)[segments_per_track * tracks_per_tape - 1] = 0xffffe000;
#endif
#if 0
	/*  Enable to test bad sector handling
	 */
	((unsigned long *) bad_sector_map)[30] = 0xfffffffe;
	((unsigned long *) bad_sector_map)[32] = 0x7fffffff;
	((unsigned long *) bad_sector_map)[34] = 0xfffeffff;
	((unsigned long *) bad_sector_map)[36] = 0x55555555;
	((unsigned long *) bad_sector_map)[38] = 0xffffffff;
	((unsigned long *) bad_sector_map)[50] = 0xffff0000;
	((unsigned long *) bad_sector_map)[51] = 0xffffffff;
	((unsigned long *) bad_sector_map)[52] = 0xffffffff;
	((unsigned long *) bad_sector_map)[53] = 0x0000ffff;
#endif
#if 0
	/*  Enable when testing multiple volume tar dumps.
	 */
	for (i = first_data_segment; i <= ftape_last_segment.id - 7; ++i) {
		((unsigned long *) bad_sector_map)[i] = EMPTY_SEGMENT;
	}
#endif
#if 0
	/*  Enable when testing bit positions in *_error_map
	 */
	for (i = first_data_segment; i <= ftape_last_segment.id; ++i) {
		((unsigned long *) bad_sector_map)[i] |= 0x00ff00ff;
	}
#endif
	if (tracing > 2) {
		unsigned int map;
		int good_sectors = 0;
		int bad_sectors;
		unsigned int total_bad = 0;
		int i;

		if (format_code == 4 || format_code == 3) {
			byte *ptr = bad_sector_map;
			unsigned sector;

			do {
				sector = get_sector(&ptr, forward);
				if (sector != 0) {
					if (format_code == 4 && sector & 0x800000) {
						total_bad += SECTORS_PER_SEGMENT - 3;
						TRACEx1(6, "bad segment at sector: %6d", sector & 0x7fffff);
					} else {
						++total_bad;
						TRACEx1(6, "bad sector: %6d", sector);
					}
				}
			} while (sector != 0);
			/*  Display end-of-file marks
			 */
			do {
				sector = *((unsigned short *) ptr)++;
				if (sector) {
					TRACEx2(4, "eof mark: %4d/%2d", sector,
					    *((unsigned short *) ptr)++);
				}
			} while (sector);
		} else {
			for (i = first_data_segment;
			 i < segments_per_track * tracks_per_tape; ++i) {
				map = ((unsigned long *) bad_sector_map)[i];
				bad_sectors = count_ones(map);
				if (bad_sectors > 0) {
					TRACEx2(6, "bsm for segment %4d: 0x%08x", i, map);
					if (bad_sectors > SECTORS_PER_SEGMENT - 3) {
						bad_sectors = SECTORS_PER_SEGMENT - 3;
					}
					total_bad += bad_sectors;
				}
			}
		}
		good_sectors = ((segments_per_track * tracks_per_tape - first_data_segment)
				* (SECTORS_PER_SEGMENT - 3)) - total_bad;
		TRACEx1(3, "%d Kb usable on this tape",
			good_sectors - ftape_last_segment.free);
		if (total_bad == 0) {
			TRACE(1, "WARNING: this tape has no bad blocks registered !");
		} else {
			TRACEx1(2, "%d bad sectors", total_bad);
		}
	}
	TRACE_EXIT;
}
Beispiel #26
0
void
main(int argc, char **argv)
{
	unsigned long countdown = 0;
	int wntDiskAdmin = 0;
	char char0 = 'a';
	char defltr = 0;
	char force = 0;

	char const *dev_name;
	int fd_dev;

	if (argc < 2) {
		usage();
		exit(1);
	}
	dev_name = argv[1];
	fd_dev = open(dev_name, 0);
	if (fd_dev < 0) {
		perror(dev_name);
		exit(1);
	}
	get_sector(fd_dev, &dev_mbr, 0);
	uread(0, &new_mbr, 5, ".bin hdr");  /* discard header */
	uread(0, &new_mbr, sizeof(new_mbr), "new mbr");  /* prototype mbr */
	chk_magic(&new_mbr, "new mbr");

	for (	(argv+=2), (argc-=2);
		argc > 0;
		(++argv), (--argc)
	) if ('-'==**argv) {
		char *value = strchr(*argv, '=');
		if (0!=value) {
			*value++ = 0;
		}
		if (0==strcmp("-wait", *argv)) {
			if (0!=value) {
				countdown = atoi(value);
				if (0 < countdown && countdown < 4000) {
					countdown *= 1000000;
				}
			}
		}
		else if (0==strcmp("-char0", *argv)) {
			if (0!=value) {
				char0 = *value;
			}
		}
		else if (0==strcmp("-default", *argv)) {
			if (0!=value) {
				defltr = *value;
			}
		}
		else if (0==strcmp("-force", *argv)) {
			if (0!=value) {
				force = *value;
			}
		}
		else if (0==strcmp("-WNTDiskAdmin", *argv)) {
			wntDiskAdmin = 6;
		}
		else {
			fprintf(stderr,"ignoring option %s\n", *argv);
		}
	}
	else {
		break;
	}

	/* Somebody please tell me how to read an .obj symbol table
	   so I can do these magic offsets symbolically!
	*/
#define COUNT  0x184
#define DEFLTR 0x172
#define DESLTR 0x038
#define NAMES  0x19a
	memcpy(&new_mbr.random[COUNT -4], &countdown, sizeof(countdown));
	memcpy(&new_mbr.random[DEFLTR -1], &defltr, sizeof(defltr));
	memcpy(&new_mbr.random[DESLTR -2], &char0, sizeof(char0));
	memcpy(&new_mbr.random[DESLTR -1], &force, sizeof(force));
	if (0==countdown) {/* wait forever: no count at all */
		new_mbr.random[COUNT -6] = 0xeb;  /* JMP rel8 */
		new_mbr.random[COUNT -5] = 0x0d;  /* skip to getcWait */
	}

    if (0 < argc) {
	char *labels = &new_mbr.random[NAMES];
	int avail = (0x200 - 2 - 4*16 - wntDiskAdmin) - NAMES;
		qsort(argv, argc, sizeof(*argv), (qsort_fn_t)strcmp);
	for (	;
		0!=argc;
		++argv, --argc
	) {
		int const len = 1+strlen(2+*argv);
		if ((avail -= len) < 0) {
			fprintf(stderr,"Use shorter labels; "
				"`%c=%s' won't fit.\n",
				**argv, 2+*argv);
		}
		else {
			strcpy(labels, 2+*argv);
			labels += len;
		}
		if (1 < argc  /* not last */
		&& (1 + *argv[0]) != *argv[1] ) {
			fprintf(stderr, "letters must be consecutive: %s %s\n",
				argv[0], argv[1] );
			exit(1);
		}
	}
	fprintf(stderr, "%d bytes available.\n", avail);
    }

    if (0!=wntDiskAdmin) {
	/* WindowsNT disk administrator uses these 6 bytes */
	memcpy(&new_mbr.random[446-6], &dev_mbr.random[446-6], 6);
    }

	memcpy(&new_mbr.part[0], &dev_mbr.part[0], 4*16);
	uwrite(1, &new_mbr, sizeof(new_mbr), "stdout");
	exit(0);
}
Beispiel #27
0
/*
 * read_extended_partition --
 *      recursively reads extended partition sector from the device
 *      and constructs the partition table tree
 *
 * PARAMETERS:
 *      fd       - file descriptor
 *      start    - start sector of primary extended partition, used for
 *                 calculation of absolute partition sector address
 *      ext_part - description of extended partition to process
 *
 * RETURNS:
 *      RTEMS_SUCCESSFUL if success,
 *      RTEMS_NO_MEMOTY if cannot allocate memory for part_desc_t strucure,
 *      RTEMS_INTERNAL_ERROR if other error occurs.
 */
static rtems_status_code
read_extended_partition(int fd, uint32_t start, rtems_part_desc_t *ext_part)
{
    int                  i;
    rtems_sector_data_t *sector = NULL;
    uint32_t             here;
    uint8_t             *data;
    rtems_part_desc_t   *new_part_desc;
    rtems_status_code    rc;

    if ((ext_part == NULL) || (ext_part->disk_desc == NULL))
    {
        return RTEMS_INTERNAL_ERROR;
    }

    /* get start sector of current extended partition */
    here = ext_part->start;

    /* get first extended partition sector */

    rc = get_sector(fd, here, &sector);
    if (rc != RTEMS_SUCCESSFUL)
    {
        if (sector)
            free(sector);
        return rc;
    }

    if (!msdos_signature_check(sector))
    {
        free(sector);
        return RTEMS_INTERNAL_ERROR;
    }

    /* read and process up to 4 logical partition descriptors */

    data = sector->data + RTEMS_IDE_PARTITION_TABLE_OFFSET;

    for (i = 0; i < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER; i++)
    {
        /* if data_to_part_desc fails skip this partition
         * and parse the next one
         */
        rc = data_to_part_desc(data, &new_part_desc);
        if (rc != RTEMS_SUCCESSFUL)
        {
            free(sector);
            return rc;
        }

        if (new_part_desc == NULL)
        {
            data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE;
            continue;
        }

        ext_part->sub_part[i] = new_part_desc;
        new_part_desc->ext_part = ext_part;
        new_part_desc->disk_desc = ext_part->disk_desc;

        if (is_extended(new_part_desc->sys_type))
        {
            new_part_desc->log_id = EMPTY_PARTITION;
            new_part_desc->start += start;
            read_extended_partition(fd, start, new_part_desc);
        }
        else
        {
            rtems_disk_desc_t *disk_desc = new_part_desc->disk_desc;
            disk_desc->partitions[disk_desc->last_log_id] = new_part_desc;
            new_part_desc->log_id = ++disk_desc->last_log_id;
            new_part_desc->start += here;
            new_part_desc->end = new_part_desc->start + new_part_desc->size - 1;
        }
        data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE;
    }

    free(sector);

    return RTEMS_SUCCESSFUL;
}
Beispiel #28
0
/*
 * read_mbr --
 *      reads Master Boot Record (sector 0) of physical device and
 *      constructs disk description structure
 *
 * PARAMETERS:
 *      disk_desc - returned disc description structure
 *
 * RETURNS:
 *      RTEMS_SUCCESSFUL if success,
 *      RTEMS_INTERNAL_ERROR otherwise
 */
static rtems_status_code
read_mbr(int fd, rtems_disk_desc_t *disk_desc)
{
    int                  part_num;
    rtems_sector_data_t *sector = NULL;
    rtems_part_desc_t   *part_desc;
    uint8_t             *data;
    rtems_status_code    rc;

    /* get MBR sector */
    rc = get_sector(fd, 0, &sector);
    if (rc != RTEMS_SUCCESSFUL)
    {
        if (sector)
            free(sector);
        return rc;
    }

    /* check if the partition table structure is MS-DOS style */
    if (!msdos_signature_check(sector))
    {
        free(sector);
        return RTEMS_INTERNAL_ERROR;
    }

    /* read and process 4 primary partition descriptors */

    data = sector->data + RTEMS_IDE_PARTITION_TABLE_OFFSET;

    for (part_num = 0;
         part_num < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER;
         part_num++)
    {
        rc = data_to_part_desc(data, &part_desc);
        if (rc != RTEMS_SUCCESSFUL)
        {
            free(sector);
            return rc;
        }

        if (part_desc != NULL)
        {
            part_desc->log_id = part_num + 1;
            part_desc->disk_desc = disk_desc;
            part_desc->end = part_desc->start + part_desc->size - 1;
            disk_desc->partitions[part_num] = part_desc;
        }
        else
        {
            disk_desc->partitions[part_num] = NULL;
        }

        data += RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE;
    }

    free(sector);

    disk_desc->last_log_id = RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER;

    /* There cannot be more than one extended partition,
       but we are to process each primary partition */
    for (part_num = 0;
         part_num < RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER;
         part_num++)
    {
        part_desc = disk_desc->partitions[part_num];
        if (part_desc != NULL && is_extended(part_desc->sys_type))
        {
            read_extended_partition(fd, part_desc->start, part_desc);
            free(part_desc);
            disk_desc->partitions[part_num] = NULL;
        }
    }

    return RTEMS_SUCCESSFUL;
}
Beispiel #29
0
void exec_image(char *image)
/* Get a Minix image into core, patch it up and execute. */
{
	int i;
	struct image_header hdr;
	char *buf;
	u32_t vsec, addr, limit, aout, n, totalmem = 0;
	struct process *procp;		/* Process under construction. */
	long a_text, a_data, a_bss, a_stack;
	int banner= 0;
	long processor= a2l(b_value("processor"));
	u16_t kmagic, mode;
	char *console;
	char params[SECTOR_SIZE];
	extern char *sbrk(int);
	char *verb;

	/* The stack is pretty deep here, so check if heap and stack collide. */
	(void) sbrk(0);

	if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil)
		verboseboot = a2l(verb);

	printf("\nLoading ");
	pretty_image(image);
	printf(".\n");

	vsec= 0;			/* Load this sector from image next. */
	addr= mem[0].base;		/* Into this memory block. */
	limit= mem[0].base + mem[0].size;
	if (limit > caddr) limit= caddr;

	/* Allocate and clear the area where the headers will be placed. */
	aout = (limit -= PROCESS_MAX * A_MINHDR);

	/* Clear the area where the headers will be placed. */
	raw_clear(aout, PROCESS_MAX * A_MINHDR);

	/* Read the many different processes: */
	for (i= 0; vsec < image_size; i++) {
		u32_t startaddr;
		startaddr = addr;
		if (i == PROCESS_MAX) {
			printf("There are more then %d programs in %s\n",
				PROCESS_MAX, image);
			errno= 0;
			return;
		}
		procp= &process[i];

		/* Read header. */
		DEBUGEXTRA(("Reading header... "));
		for (;;) {
			if ((buf= get_sector(vsec++)) == nil) return;

			memcpy(&hdr, buf, sizeof(hdr));

			if (BADMAG(hdr.process)) { errno= ENOEXEC; return; }

			/* Check the optional label on the process. */
			if (selected(hdr.name)) break;

			/* Bad label, skip this process. */
			vsec+= proc_size(&hdr);
		}
		DEBUGEXTRA(("done\n"));

		/* Sanity check: an 8086 can't run a 386 kernel. */
		if (hdr.process.a_cpu == A_I80386 && processor < 386) {
			printf("You can't run a 386 kernel on this 80%ld\n",
				processor);
			errno= 0;
			return;
		}

		/* Get the click shift from the kernel text segment. */
		if (i == KERNEL_IDX) {
			if (!get_clickshift(vsec, &hdr)) return;
			addr= align(addr, click_size);

			/* big kernels must be loaded into extended memory */
			if (k_flags & K_KHIGH) {
				addr= mem[1].base;
				limit= mem[1].base + mem[1].size;
			}
		}

		/* Save a copy of the header for the kernel, with a_syms
		 * misused as the address where the process is loaded at.
		 */
		DEBUGEXTRA(("raw_copy(0x%x, 0x%lx, 0x%x)... ", 
			aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR));
		hdr.process.a_syms= addr;
		raw_copy(aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR);
		DEBUGEXTRA(("done\n"));

		if (!banner) {
			DEBUGBASIC(("     cs       ds     text     data      bss"));
			if (k_flags & K_CHMEM) DEBUGBASIC(("    stack"));
			DEBUGBASIC(("\n"));
			banner= 1;
		}

		/* Segment sizes. */
		DEBUGEXTRA(("a_text=0x%lx; a_data=0x%lx; a_bss=0x%lx; a_flags=0x%x)\n",
			hdr.process.a_text, hdr.process.a_data, 
			hdr.process.a_bss, hdr.process.a_flags));

		a_text= hdr.process.a_text;
		a_data= hdr.process.a_data;
		a_bss= hdr.process.a_bss;
		if (k_flags & K_CHMEM) {
			a_stack= hdr.process.a_total - a_data - a_bss;
			if (!(hdr.process.a_flags & A_SEP)) a_stack-= a_text;
		} else {
			a_stack= 0;
		}

		/* Collect info about the process to be. */
		procp->cs= addr;

		/* Process may be page aligned so that the text segment contains
		 * the header, or have an unmapped zero page against vaxisms.
		 */
		procp->entry= hdr.process.a_entry;
		if (hdr.process.a_flags & A_PAL) a_text+= hdr.process.a_hdrlen;
		if (hdr.process.a_flags & A_UZP) procp->cs-= click_size;

		/* Separate I&D: two segments.  Common I&D: only one. */
		if (hdr.process.a_flags & A_SEP) {
			/* Read the text segment. */
			DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
				vsec, a_text, addr, limit));
			if (!get_segment(&vsec, &a_text, &addr, limit)) return;
			DEBUGEXTRA(("get_segment done vsec=0x%lx a_text=0x%lx "
				"addr=0x%lx\n", 
				vsec, a_text, addr));

			/* The data segment follows. */
			procp->ds= addr;
			if (hdr.process.a_flags & A_UZP) procp->ds-= click_size;
			procp->data= addr;
		} else {
			/* Add text to data to form one segment. */
			procp->data= addr + a_text;
			procp->ds= procp->cs;
			a_data+= a_text;
		}

		/* Read the data segment. */
		DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", 
			vsec, a_data, addr, limit));
		if (!get_segment(&vsec, &a_data, &addr, limit)) return;
		DEBUGEXTRA(("get_segment done vsec=0x%lx a_data=0x%lx "
			"addr=0x%lx\n", 
			vsec, a_data, addr));

		/* Make space for bss and stack unless... */
		if (i != KERNEL_IDX && (k_flags & K_CLAIM)) a_bss= a_stack= 0;

		DEBUGBASIC(("%07lx  %07lx %8ld %8ld %8ld",
			procp->cs, procp->ds, hdr.process.a_text,
			hdr.process.a_data, hdr.process.a_bss));
		if (k_flags & K_CHMEM) DEBUGBASIC((" %8ld", a_stack));

		/* Note that a_data may be negative now, but we can look at it
		 * as -a_data bss bytes.
		 */

		/* Compute the number of bss clicks left. */
		a_bss+= a_data;
		n= align(a_bss, click_size);
		a_bss-= n;

		/* Zero out bss. */
		DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit));
		if (addr + n > limit) { errno= ENOMEM; return; }
		raw_clear(addr, n);
		DEBUGEXTRA(("done\n"));
		addr+= n;

		/* And the number of stack clicks. */
		a_stack+= a_bss;
		n= align(a_stack, click_size);
		a_stack-= n;

		/* Add space for the stack. */
		addr+= n;

		/* Process endpoint. */
		procp->end= addr;

		if (verboseboot >= VERBOSEBOOT_BASIC)
			printf("  %s\n", hdr.name);
		else {
			u32_t mem;
			mem = addr-startaddr;
			printf("%s ", hdr.name);
			totalmem += mem;
		}

		if (i == 0 && (k_flags & (K_HIGH | K_KHIGH)) == K_HIGH) {
			/* Load the rest in extended memory. */
			addr= mem[1].base;
			limit= mem[1].base + mem[1].size;
		}
	}

	if (verboseboot < VERBOSEBOOT_BASIC)
		printf("(%dk)\n", totalmem/1024);

	if ((n_procs= i) == 0) {
		printf("There are no programs in %s\n", image);
		errno= 0;
		return;
	}

	/* Check the kernel magic number. */
	raw_copy(mon2abs(&kmagic), 
		process[KERNEL_IDX].data + MAGIC_OFF, sizeof(kmagic));
	if (kmagic != KERNEL_D_MAGIC) {
		printf("Kernel magic number is incorrect (0x%x@0x%lx)\n", 
			kmagic, process[KERNEL_IDX].data + MAGIC_OFF);
		errno= 0;
		return;
	}

	/* Patch sizes, etc. into kernel data. */
	DEBUGEXTRA(("patch_sizes()... "));
	patch_sizes();
	DEBUGEXTRA(("done\n"));

#if !DOS
	if (!(k_flags & K_MEML)) {
		/* Copy the a.out headers to the old place. */
		raw_copy(HEADERPOS, aout, PROCESS_MAX * A_MINHDR);
	}
#endif

	/* Run the trailer function just before starting Minix. */
	DEBUGEXTRA(("run_trailer()... "));
	if (!run_trailer()) { errno= 0; return; }
	DEBUGEXTRA(("done\n"));

	/* Translate the boot parameters to what Minix likes best. */
	DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params)));
	if (!params2params(params, sizeof(params))) { errno= 0; return; }
	DEBUGEXTRA(("done\n"));

	/* Set the video to the required mode. */
	if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) {
		mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE :
								MONO_MODE;
	}
	DEBUGEXTRA(("set_mode(%d)... ", mode));
	set_mode(mode);
	DEBUGEXTRA(("done\n"));

	/* Close the disk. */
	DEBUGEXTRA(("dev_close()... "));
	(void) dev_close();
	DEBUGEXTRA(("done\n"));

	/* Minix. */
	DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n", 
		process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
		process[KERNEL_IDX].ds, params, sizeof(params), aout));
	minix(process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
			process[KERNEL_IDX].ds, params, sizeof(params), aout);

	if (!(k_flags & K_BRET)) {
		extern u32_t reboot_code;
		raw_copy(mon2abs(params), reboot_code, sizeof(params));
	}
	parse_code(params);

	/* Return from Minix.  Things may have changed, so assume nothing. */
	fsok= -1;
	errno= 0;

	/* Read leftover character, if any. */
	scan_keyboard();

	/* Restore screen contents. */
	restore_screen();
}
Beispiel #30
0
long rwrite(Rfile tpf, void *buf, long count)
/* Write a buffer to an open ram-disk file. */
{
char ***platter;
char **track;
char *data;
int i;
int ssize, so;
int flags;
long filept;
long  written;
long new_size;

flags = tpf->flags;
if (!(flags&TF_OPEN))
	{
	rerr = Err_file_not_open;
	return(0);
	}
if (!(flags&TF_WRITE))
	{
	rerr = Err_write;
	return(0);
	}
if (count <= 0)
	return(0);

	data = buf;
	written = 0;
	filept = tpf->filep;
	new_size = filept + count;
	platter = tpf->platters + get_platter(filept);

	for (;;)
	{
		if ((track = *platter) == NULL)
			if ((*platter = track = tget_clear()) == NULL)
				goto OUT;
		i = get_track(filept);
		track += i;
		for ( ; i< TRD_TRACK; i++)
		{
			if (*track == NULL)
				if ((*track = tget_sector()) == NULL)
					goto OUT;
			so = get_sector(filept);
			ssize = TRD_SECTOR - so;
			if (count > ssize)
			{
				memcpy(*track + so, data, ssize);
				written += ssize;
				data +=  ssize;
				count -= ssize;
				filept += ssize;
			}
			else
			{
				memcpy(*track + so, data, (size_t)count);
				written += count;
				filept += count;
				goto OUT;
			}
			track++;
		}
		platter++;
	}
OUT:
	if (tpf->size < (tpf->filep = filept))
		tpf->size = filept;
	return(written);
}