Exemplo n.º 1
0
static libspectrum_error
generalised_data_init( libspectrum_tape_generalised_data_block *block,
                       libspectrum_tape_generalised_data_block_state *state )
{
  state->run = 0;
  state->symbols_through_run = 0;
  state->edges_through_symbol = 0;

  state->current_symbol = 0;
  state->symbols_through_stream = 0;

  state->current_byte = 0;
  state->bits_through_byte = 0;
  state->bytes_through_stream = 0;

  if( block->pilot_table.symbols_in_block ) {
    state->state = LIBSPECTRUM_TAPE_STATE_PILOT;
  } else if( block->data_table.symbols_in_block ) {
    state->state = LIBSPECTRUM_TAPE_STATE_DATA1;
    state->current_byte = block->data[ 0 ];
    state->current_symbol = get_generalised_data_symbol( block, state );
  } else {
    state->state = LIBSPECTRUM_TAPE_STATE_PAUSE;
  }

  return LIBSPECTRUM_ERROR_NONE;
}
Exemplo n.º 2
0
static libspectrum_error
generalised_data_edge( libspectrum_tape_generalised_data_block *block,
                       libspectrum_tape_generalised_data_block_state *state,
		       libspectrum_dword *tstates, int *end_of_block,
		       int *flags )
{
  libspectrum_tape_generalised_data_symbol_table *table;
  libspectrum_tape_generalised_data_symbol *symbol;
  size_t current_symbol;

  switch( state->state ) {
  case LIBSPECTRUM_TAPE_STATE_PILOT:
    table = &( block->pilot_table );
    current_symbol = block->pilot_symbols[ state->run ];
    symbol = &( table->symbols[ current_symbol ] );

    set_tstates_and_flags( symbol, state->edges_through_symbol, tstates,
			   flags );

    state->edges_through_symbol++;
    if( state->edges_through_symbol == table->max_pulses    ||
	symbol->lengths[ state->edges_through_symbol ] == 0    ) {
      state->edges_through_symbol = 0;
      if( ++state->symbols_through_run == block->pilot_repeats[ state->run ] ) {
	state->symbols_through_run = 0;
	if( ++state->run == table->symbols_in_block ) {
	  state->state = LIBSPECTRUM_TAPE_STATE_DATA1;
	  state->bits_through_byte = 0;
	  state->bytes_through_stream = 0;
	  state->symbols_through_stream = 0;
	  state->current_byte = block->data[ 0 ];
	  state->current_symbol = get_generalised_data_symbol( block, state );
	}
      }
    }
    break;

  case LIBSPECTRUM_TAPE_STATE_DATA1:
    table = &( block->data_table );
    symbol = &( table->symbols[ state->current_symbol ] );

    set_tstates_and_flags( symbol, state->edges_through_symbol, tstates,
			   flags );

    state->edges_through_symbol++;
    if( state->edges_through_symbol == table->max_pulses    ||
	symbol->lengths[ state->edges_through_symbol ] == 0    ) {
      if( ++state->symbols_through_stream == table->symbols_in_block ) {
	state->state = LIBSPECTRUM_TAPE_STATE_PAUSE;
      } else {
	state->edges_through_symbol = 0;
	state->current_symbol = get_generalised_data_symbol( block, state );
      }
    }
    break;

  case LIBSPECTRUM_TAPE_STATE_PAUSE:
    /* The pause at the end of the block */
    *tstates = ( block->pause * 69888 )/20; /* FIXME: should vary with tstates
					       per frame */
    *end_of_block = 1;
    break;

  default:
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "%s: unknown state %d",
			     __func__, state->state );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  return LIBSPECTRUM_ERROR_NONE;
}