コード例 #1
0
ファイル: memory.c プロジェクト: borti4938/sd2snes
void sram_hexdump(uint32_t addr, uint32_t len) {
  static uint8_t buf[16];
  uint32_t ptr;
  for(ptr=0; ptr < len; ptr += 16) {
    sram_readblock((void*)buf, ptr+addr, 16);
    uart_trace(buf, 0, 16);
  }
}
コード例 #2
0
ファイル: lpc-uart.c プロジェクト: 1312mukesh/skiboot
static void __uart_do_poll(u8 trace_ctx)
{
	if (!in_buf)
		return;

	lock(&uart_lock);
	uart_read_to_buffer();
	uart_con_flush();
	uart_trace(trace_ctx, 0, tx_full, in_count);
	unlock(&uart_lock);

	uart_adjust_opal_event();
}
コード例 #3
0
ファイル: lpc-uart.c プロジェクト: 1312mukesh/skiboot
/* This is called with the console lock held */
static int64_t uart_opal_read(int64_t term_number, int64_t *length,
			      uint8_t *buffer)
{
	size_t req_count = *length, read_cnt = 0;
	uint8_t lsr = 0;

	if (term_number != 0)
		return OPAL_PARAMETER;
	if (!in_buf)
		return OPAL_INTERNAL_ERROR;

	lock(&uart_lock);

	/* Read from buffer first */
	if (in_count) {
		read_cnt = in_count;
		if (req_count < read_cnt)
			read_cnt = req_count;
		memcpy(buffer, in_buf, read_cnt);
		req_count -= read_cnt;
		if (in_count != read_cnt)
			memmove(in_buf, in_buf + read_cnt, in_count - read_cnt);
		in_count -= read_cnt;
	}

	/*
	 * If there's still room in the user buffer, read from the UART
	 * directly
	 */
	while(req_count) {
		lsr = uart_read(REG_LSR);
		if ((lsr & LSR_DR) == 0)
			break;
		buffer[read_cnt++] = uart_read(REG_RBR);
		req_count--;
	}

	/* Finally, flush whatever's left in the UART into our buffer */
	uart_read_to_buffer();

	uart_trace(TRACE_UART_CTX_READ, read_cnt, tx_full, in_count);

	unlock(&uart_lock);
	
	/* Adjust the OPAL event */
	uart_adjust_opal_event();

	*length = read_cnt;
	return OPAL_SUCCESS;
}
コード例 #4
0
ファイル: fileops.c プロジェクト: cbmeeks/sd2iec
/**
 * file_open - open a file on given secondary
 * @secondary: secondary address used in OPEN call
 *
 * This function opens the file named in command_buffer on the given
 * secondary address. All special names and prefixes/suffixed are handled
 * here, e.g. $/#/@/,S,W
 */
void file_open(uint8_t secondary) {
  buffer_t *buf;
  uint8_t i = 0;
  uint8_t recordlen = 0;

  /* If the secondary is already in use, close the existing buffer */
  buf = find_buffer(secondary);
  if (buf != NULL) {
    /* FIXME: What should we do if an error occurs? */
    cleanup_and_free_buffer(buf);
  }

  /* Assume everything will go well unless proven otherwise */
  set_error(ERROR_OK);

  /* Strip 0x0d characters from end of name (C2BD-C2CA) */
  if (command_length > 1) {
    if (command_buffer[command_length-1] == 0x0d)
      command_length -= 1;
    else if (command_buffer[command_length-2] == 0x0d)
      command_length -= 2;
  }

  /* Clear the remainder of the command buffer, simplifies parsing */
  memset(command_buffer+command_length, 0, sizeof(command_buffer)-command_length);

  uart_trace(command_buffer,0,command_length);

  /* Direct access? */
  if (command_buffer[0] == '#') {
    open_buffer(secondary);
    return;
  }

  /* Parse type+mode suffixes */
  uint8_t *ptr = command_buffer;
  enum open_modes mode = OPEN_READ;
  uint8_t filetype = TYPE_DEL;

  while(i++ < 2 && *ptr && (ptr = ustrchr(ptr, ','))) {
    *ptr = 0;
    ptr++;
    switch (*ptr) {
    case 0:
      break;

    case 'R': /* Read */
      mode = OPEN_READ;
      break;

    case 'W': /* Write */
      mode = OPEN_WRITE;
      break;

    case 'A': /* Append */
      mode = OPEN_APPEND;
      break;

    case 'M': /* Modify */
      mode = OPEN_MODIFY;
      break;

    case 'D': /* DEL */
      filetype = TYPE_DEL;
      break;

    case 'S': /* SEQ */
      filetype = TYPE_SEQ;
      break;

    case 'P': /* PRG */
      filetype = TYPE_PRG;
      break;

    case 'U': /* USR */
      filetype = TYPE_USR;
      break;

    case 'L': /* REL */
      filetype = TYPE_REL;
      mode = OPEN_WRITE;
      if((ptr = ustrchr(ptr, ',')))
        recordlen = *(++ptr);
      i = 2;  // stop the scan
      break;
    }
  }

  /* Load directory? */
  if (command_buffer[0] == '$') {
    load_directory(secondary);
    return;
  }

  /* Parse path+partition numbers */
  uint8_t *fname;
  int8_t res;
  cbmdirent_t dent;
  path_t path;

  /* Parse path and file name */
  if (parse_path(command_buffer, &path, &fname, 0))
      return;

#ifdef CONFIG_M2I
  /* For M2I only: Remove trailing spaces from name */
  if (partition[path.part].fop == &m2iops) {
    res = ustrlen(fname);
    while (--res && fname[res] == ' ')
      fname[res] = 0;
  }
#endif

  /* Filename matching */
  if (opendir(&matchdh, &path))
    return;

  do {
    res = next_match(&matchdh, fname, NULL, NULL, FLAG_HIDDEN, &dent);
    if (res > 0)
      /* Error, abort */
      return;

    /* Don't match on DEL or DIR */
    if ((dent.typeflags & TYPE_MASK) != TYPE_DEL &&
        (dent.typeflags & TYPE_MASK) != TYPE_DIR)
      break;

    /* But do match if it's for writing */
    if (mode == OPEN_WRITE || secondary == 1)
      break;
  } while (res == 0);

  if(res && filetype == TYPE_REL && !recordlen) {
    set_error(ERROR_SYNTAX_UNABLE);
    return;
  }

  /* If match found is a REL... */
  if(!res && (dent.typeflags & TYPE_MASK) == TYPE_REL) {
    /* requested type must be REL or DEL */
    if(filetype != TYPE_REL && filetype != TYPE_DEL) {
      set_error(ERROR_FILE_TYPE_MISMATCH);
      return;
    }
    filetype = TYPE_REL;
    mode = OPEN_MODIFY;
  }

  /* Force mode+type for secondaries 0/1 */
  switch (secondary) {
  case 0:
    mode = OPEN_READ;
    if (filetype == TYPE_DEL)
      filetype = TYPE_PRG;
    break;

  case 1:
    mode = OPEN_WRITE;
    if (filetype == TYPE_DEL)
      filetype = TYPE_PRG;
    break;

  default:
    if (filetype == TYPE_DEL)
      filetype = TYPE_SEQ;
  }

  if (mode == OPEN_WRITE) {
    if (res == 0) {
      /* Match found */
      if (command_buffer[0] == '@') {
        /* Make sure there is a free buffer to open the new file later */
        if (!check_free_buffers()) {
          set_error(ERROR_NO_CHANNEL);
          return;
        }

        /* Copy dent because file_delete may change it */
        cbmdirent_t dentcopy = dent;

        /* Rewrite existing file: Delete the old one */
        if (file_delete(&path, &dentcopy) == 255)
          return;

        /* Force fatops to create a new name based on the (long) CBM- */
        /* name instead of creating one with the old SFN and no LFN.  */
        if (dent.opstype == OPSTYPE_FAT || dent.opstype == OPSTYPE_FAT_X00)
          dent.pvt.fat.realname[0] = 0;
      } else {
        /* Write existing file without replacement: Raise error */
        set_error(ERROR_FILE_EXISTS);
        return;
      }
    } else {
      /* Normal write or non-existing rewrite */
      /* Doesn't exist: Copy name to dent */
      memset(&dent, 0, sizeof(dent));
      ustrncpy(dent.name, fname, CBM_NAME_LENGTH);
      set_error(ERROR_OK); // because first_match has set FNF
    }
  } else if (res != 0) {
    /* File not found */
    set_error(ERROR_FILE_NOT_FOUND);
    return;
  }

  /* Grab a buffer */
  buf = alloc_buffer();
  if (!buf)
    return;

  buf->secondary = secondary;

  if(filetype == TYPE_REL) {
    display_filename_write(path.part,CBM_NAME_LENGTH,dent.name);
    open_rel(&path, &dent, buf, recordlen, (mode == OPEN_MODIFY));
    return;
  }

  switch (mode) {
  case OPEN_MODIFY:
  case OPEN_READ:
    /* Modify is the same as read, but allows reading *ed files.        */
    /* FAT doesn't have anything equivalent, so both are mapped to READ */
    display_filename_read(path.part,CBM_NAME_LENGTH,dent.name);
    open_read(&path, &dent, buf);
    break;

  case OPEN_WRITE:
  case OPEN_APPEND:
    display_filename_write(path.part,CBM_NAME_LENGTH,dent.name);
    open_write(&path, &dent, filetype, buf, (mode == OPEN_APPEND));
    break;
  }
}
コード例 #5
0
ファイル: menu.c プロジェクト: nils-eilers/NODISKEMU
void menu_browse_files(void) {
  buffer_t *buf;
  buffer_t *buf_tbl;
  buffer_t *buf_cur;
  buffer_t *first_buf;
  path_t path;
  cbmdirent_t dent;
  uint16_t entries;
  uint8_t entry_num;
  bool fat_filesystem;
  uint8_t i;
  uint8_t my;
  uint16_t mp;
  bool action;
  uint16_t stack_mp[MAX_LASTPOS];
  uint8_t stack_my[MAX_LASTPOS];
  uint8_t pos_stack;
  uint8_t save_active_buffers;

  pos_stack = 0;
  memset(stack_mp, 0, sizeof(stack_mp));
  memset(stack_my, 0, sizeof(stack_my));
  save_active_buffers = active_buffers;

start:
  lcd_clear();
  lcd_puts_P(PSTR("Reading..."));

  buf = buf_tbl = buf_cur = first_buf = NULL;
  entries = entry_num = mp = 0;
  fat_filesystem = false;

  // Allocate one buffer, used to read a single directory entry
  if ((buf = alloc_system_buffer()) == NULL) return;

  // Allocate buffers with continuous data segments
  // Stores pointers to directory entries for qsort
  if ((buf_tbl = alloc_linked_buffers(CONFIG_DIR_BUFFERS)) == NULL) return;

  // Buffers to store the actual diretory entries.
  // Whilst the directory grows, new buffers get allocated and linked
  if ((buf_cur = alloc_system_buffer()) == NULL) return;
  first_buf = buf_cur;

  // Allocating buffers affects the LEDs
  set_busy_led(false); set_dirty_led(true);

  path.part = current_part;
  path.dir  = partition[path.part].current_dir;
  uart_trace(&path.dir, 0, sizeof(dir_t));
  uart_putcrlf();
  uart_flush();
  if (opendir(&buf->pvt.dir.dh, &path)) return;

  for (;;) {
    if (next_match(&buf->pvt.dir.dh,
                    buf->pvt.dir.matchstr,
                    buf->pvt.dir.match_start,
                    buf->pvt.dir.match_end,
                    buf->pvt.dir.filetype,
                    &dent) == 0)
    {
      uint8_t e_flags = 0;
      if (dent.opstype == OPSTYPE_FAT) {
        fat_filesystem = true;
        if (check_imageext(dent.pvt.fat.realname) != IMG_UNKNOWN)
          e_flags |= E_IMAGE;
      }
      // Current block full?
      if (entry_num == ENTRIES_PER_BLOCK) {
        entry_num = 0;
        buffer_t *old_buf = buf_cur;
        if ((buf_cur = alloc_system_buffer()) == NULL) {
          printf("alloc buf_cur failed, %d entries", entries);
          goto cleanup;
        }
        set_busy_led(false); set_dirty_led(true);
        buf_cur->pvt.buffer.next = NULL;
        old_buf->pvt.buffer.next = buf_cur;
      }

      // Store entry
      ep[entries] = (entry_t *) (buf_cur->data + entry_num * sizeof(entry_t));
      ustrncpy(ep[entries]->filename, dent.name, 16);
      ep[entries]->filesize = dent.blocksize;
      if ((dent.typeflags & EXT_TYPE_MASK) == TYPE_DIR)
        e_flags |= E_DIR;
      ep[entries]->flags = e_flags;
      entries++;
      entry_num++;
    } else {
      // No more directory entries to read
      break;
    }
  }
  printf("%d entries\r\n", entries);

  if (fat_filesystem)
    qsort(ep, entries, sizeof(entry_t*), compare);

  for (uint16_t i = 0; i < entries; i++) {
    printf("%3u: ", i);
    if (ep[i]->flags & E_DIR)
      uart_puts_P(PSTR(" DIR "));
    else if (ep[i]->flags & E_IMAGE)
      uart_puts_P(PSTR(" IMG "));
    else
      printf("%4u ", ep[i]->filesize);
    uint8_t filename[16 + 1];
    ustrncpy(filename, ep[i]->filename, 16);
    filename[16] = '\0';
    pet2asc(filename);
    printf("%s\r\n", filename);
    uart_flush();
  }
  uart_putcrlf();

#define DIRNAV_OFFSET   2
#define NAV_ABORT       0
#define NAV_PARENT      1

  mp = stack_mp[pos_stack];
  my = stack_my[pos_stack];
  printf("mp set to %d\r\n", mp);
  if (mp < (LCD_LINES - 1))
    my = mp;
  else
    my = 0;
  action = false;

  for (i=0; i < MAX_LASTPOS; i++) {
    if (pos_stack == i) uart_putc('>');
    printf("%d ", stack_mp[i]);
  }
  uart_putcrlf();

  for (;;) {
    lcd_clear();
    for (i = 0; i < LCD_LINES; i++) {
      lcd_locate(0, i);
      int8_t y = mp - my + i;
      if (y < 0) return; // should not happen!
      if (y < DIRNAV_OFFSET) {
        rom_menu_browse(y);
      } else {
        y -= DIRNAV_OFFSET;
        if (y >= entries) {
          lcd_puts_P(PSTR("-- End of dir --"));
          break;
        } else {
          lcd_print_dir_entry(y);
        }
      }
    }

    lcd_cursor(true);
    for (;;) {
      lcd_locate(0, my);
      //printf("mp: %u   my: %u\r\n", mp, my);
      //while (!get_key_state(KEY_ANY));
      if (get_key_autorepeat(KEY_PREV)) {
        if (mp > 0) {
          --mp;
          if (my > 0) --my;
          else {
            my = LCD_LINES - 1;
            if (mp < LCD_LINES) {
              while ((mp - my) >= DIRNAV_OFFSET) {
                --my;
                // TODO: is this really necessary?
                uart_puts_P(PSTR("my fixed\r\n"));
              }
            }
            break;
          }
        } else {
          my = LCD_LINES - 2;
          mp = entries + DIRNAV_OFFSET - 1;
          break;
        }
      }
      if (get_key_autorepeat(KEY_NEXT)) {
        if (mp < (entries -1 + DIRNAV_OFFSET)) {
          ++mp;
          if (my < (LCD_LINES - 1))  ++my;
          else {
            my = 0;
            break;
          }
        } else {
          mp = 0;
          my = 0;
          break;
        }
      }
      if (get_key_press(KEY_SEL)) {
        action = true;
        break;
      }
    }
    lcd_cursor(false);
    if (!action) continue;
    if (mp == NAV_ABORT) goto cleanup;
    if (mp == NAV_PARENT) {
      uart_puts_P(PSTR("CD_\r\n"));
      ustrcpy_P(command_buffer, PSTR("CD_"));
      command_length = 3;
      parse_doscommand();
      clear_command_buffer();
      stack_mp[pos_stack] = 0;
      stack_my[pos_stack] = 0;
      if (pos_stack > 0) --pos_stack;
      printf("pos_stack set to %d\r\n", pos_stack);
      if (current_error != ERROR_OK) goto cleanup;
      goto reread;
    }
    if (ep[mp - DIRNAV_OFFSET]->flags & E_DIR ||
        ep[mp - DIRNAV_OFFSET]->flags & E_IMAGE)
    {
      clear_command_buffer();
      ustrcpy_P(command_buffer, PSTR("CD:"));
      ustrncpy(command_buffer + 3, ep[mp - DIRNAV_OFFSET]->filename, 16);
      command_length = ustrlen(command_buffer);
      parse_doscommand();
      clear_command_buffer();
      if (current_error != ERROR_OK) goto cleanup;
      if (pos_stack < MAX_LASTPOS) {
        stack_mp[pos_stack]   = mp;
        stack_my[pos_stack++] = my;
        printf("pos_stack set to %d\r\n", pos_stack);
      }
      goto reread;
    }
  }

reread:
  free_buffer(buf);

  buffer_t *p = buf_tbl;
  do {
    p->allocated = 0;
    p = p->pvt.buffer.next;
  } while (p != NULL);

  p = first_buf;
  if (p != NULL) do {
    p->allocated = 0;
    p = p->pvt.buffer.next;
  } while (p != NULL);

  set_busy_led(false); set_dirty_led(true);
  active_buffers = save_active_buffers;
  if (mp == NAV_ABORT) return;
  goto start;

cleanup:
  mp = NAV_ABORT;
  goto reread;
}