예제 #1
0
static void
write_header( libspectrum_byte **buffer, libspectrum_byte **ptr,
	      size_t *length, libspectrum_snap *snap )
{
  libspectrum_make_room( buffer, LIBSPECTRUM_SNA_HEADER_LENGTH, ptr, length );

  *(*ptr)++ = libspectrum_snap_i ( snap );
  libspectrum_write_word( ptr, libspectrum_snap_hl_( snap ) );
  libspectrum_write_word( ptr, libspectrum_snap_de_( snap ) );
  libspectrum_write_word( ptr, libspectrum_snap_bc_( snap ) );
  *(*ptr)++ = libspectrum_snap_f_( snap );
  *(*ptr)++ = libspectrum_snap_a_( snap );
  libspectrum_write_word( ptr, libspectrum_snap_hl ( snap ) );
  libspectrum_write_word( ptr, libspectrum_snap_de ( snap ) );
  libspectrum_write_word( ptr, libspectrum_snap_bc ( snap ) );
  libspectrum_write_word( ptr, libspectrum_snap_iy ( snap ) );
  libspectrum_write_word( ptr, libspectrum_snap_ix ( snap ) );

  *(*ptr)++ = libspectrum_snap_iff2( snap ) ? 0x04 : 0x00;

  *(*ptr)++ = libspectrum_snap_r ( snap );
  *(*ptr)++ = libspectrum_snap_f ( snap );
  *(*ptr)++ = libspectrum_snap_a ( snap );

  libspectrum_write_word( ptr, libspectrum_snap_sp ( snap ) );

  *(*ptr)++ = libspectrum_snap_im( snap );
  *(*ptr)++ = libspectrum_snap_out_ula( snap ) & 0x07;
}
예제 #2
0
static libspectrum_error
write_48k_sna( libspectrum_byte **buffer, libspectrum_byte **ptr,
	       size_t *length, libspectrum_snap *snap )
{
  libspectrum_error error;
  libspectrum_byte *stack, *sp;

  /* Must have somewhere in RAM to store PC */
  if( libspectrum_snap_sp( snap ) < 0x4002 ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_INVALID,
			     "SP is too low (0x%04x) to stack PC",
			     libspectrum_snap_sp( snap ) );
    return LIBSPECTRUM_ERROR_INVALID;
  }

  libspectrum_make_room( buffer, 0xc000, ptr, length );

  error = write_page( &( (*ptr)[ 0x0000 ] ), snap, 5 );
  if( error ) return error;
  error = write_page( &( (*ptr)[ 0x4000 ] ), snap, 2 );
  if( error ) return error;
  error = write_page( &( (*ptr)[ 0x8000 ] ), snap, 0 );
  if( error ) return error;

  /* Place PC on the stack */
  stack = &( (*ptr)[ libspectrum_snap_sp( snap ) - 0x4000 - 2 ] );
  libspectrum_write_word( &stack, libspectrum_snap_pc( snap ) );

  *ptr += 0xc000;

  /* Store the new value of SP */
  sp = *buffer + SNA_OFFSET_SP;
  libspectrum_write_word( &sp, libspectrum_snap_sp( snap ) - 2 );

  return LIBSPECTRUM_ERROR_NONE;
}
예제 #3
0
파일: z80.cpp 프로젝트: Oggom/mednafen-git
/* Routines for transferring the Z80 contents to and from snapshots */
static void
z80_from_snapshot( libspectrum_snap *snap )
{
  A  = libspectrum_snap_a ( snap ); F  = libspectrum_snap_f ( snap );
  A_ = libspectrum_snap_a_( snap ); F_ = libspectrum_snap_f_( snap );

  BC  = libspectrum_snap_bc ( snap ); DE  = libspectrum_snap_de ( snap );
  HL  = libspectrum_snap_hl ( snap ); BC_ = libspectrum_snap_bc_( snap );
  DE_ = libspectrum_snap_de_( snap ); HL_ = libspectrum_snap_hl_( snap );

  IX = libspectrum_snap_ix( snap ); IY = libspectrum_snap_iy( snap );
  I  = libspectrum_snap_i ( snap ); R = R7 = libspectrum_snap_r( snap );
  SP = libspectrum_snap_sp( snap ); PC = libspectrum_snap_pc( snap );

  IFF1 = libspectrum_snap_iff1( snap ); IFF2 = libspectrum_snap_iff2( snap );
  IM = libspectrum_snap_im( snap );

  z80.halted = libspectrum_snap_halted( snap );

  z80.interrupts_enabled_at =
    libspectrum_snap_last_instruction_ei( snap ) ? z80_tstates : -1;
}
예제 #4
0
static int
libspectrum_sna_read_data( const libspectrum_byte *buffer,
			   size_t buffer_length, libspectrum_snap *snap )
{
  int error, page, i;
  libspectrum_word sp, offset;

  if( buffer_length < 0xc000 ) {
    libspectrum_print_error(
      LIBSPECTRUM_ERROR_CORRUPT,
      "libspectrum_sna_read_data: not enough data in buffer"
    );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  switch( libspectrum_snap_machine( snap ) ) {

  case LIBSPECTRUM_MACHINE_48:

    sp = libspectrum_snap_sp( snap );
    if( sp < 0x4000 || sp == 0xffff ) {
      libspectrum_print_error(
        LIBSPECTRUM_ERROR_CORRUPT,
        "libspectrum_sna_read_data: SP invalid (0x%04x)", sp
      );
      return LIBSPECTRUM_ERROR_CORRUPT;
    }

    /* Rescue PC from the stack */
    offset = sp - 0x4000;
    libspectrum_snap_set_pc( snap, buffer[offset] + 0x100 * buffer[offset+1] );

    /* Increase SP as PC has been unstacked */
    libspectrum_snap_set_sp( snap, libspectrum_snap_sp( snap ) + 2 );

    /* And split the pages up */
    error = libspectrum_split_to_48k_pages( snap, buffer );
    if( error != LIBSPECTRUM_ERROR_NONE ) return error;

    break;

  case LIBSPECTRUM_MACHINE_PENT:
    
    for( i=0; i<8; i++ ) {
      libspectrum_byte *ram = libspectrum_new( libspectrum_byte, 0x4000 );
      libspectrum_snap_set_pages( snap, i, ram );
    }

    memcpy( libspectrum_snap_pages( snap, 5 ), &buffer[0x0000], 0x4000 );
    memcpy( libspectrum_snap_pages( snap, 2 ), &buffer[0x4000], 0x4000 );

    error = libspectrum_sna_read_128_header( buffer + 0xc000,
					     buffer_length - 0xc000, snap );
    if( error != LIBSPECTRUM_ERROR_NONE ) return error;

    page = libspectrum_snap_out_128_memoryport( snap ) & 0x07;
    if( page == 5 || page == 2 ) {
      if( memcmp( libspectrum_snap_pages( snap, page ),
		  &buffer[0x8000], 0x4000 ) ) {
	libspectrum_print_error(
          LIBSPECTRUM_ERROR_CORRUPT,
	  "libspectrum_sna_read_data: duplicated page not identical"
	);
	return LIBSPECTRUM_ERROR_CORRUPT;
      }
    } else {
      memcpy( libspectrum_snap_pages( snap, page ), &buffer[0x8000], 0x4000 );
    }

    buffer += 0xc000 + LIBSPECTRUM_SNA_128_HEADER_LENGTH;
    buffer_length -= 0xc000 + LIBSPECTRUM_SNA_128_HEADER_LENGTH;
    error = libspectrum_sna_read_128_data( buffer, buffer_length, snap );
    if( error != LIBSPECTRUM_ERROR_NONE ) return error;

    break;

  default:
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "libspectrum_sna_read_data: unknown machine" );
    return LIBSPECTRUM_ERROR_LOGIC;
  }
  
  return LIBSPECTRUM_ERROR_NONE;
}