コード例 #1
0
static void
didaktik_from_snapshot( libspectrum_snap *snap )
{
  int i;

  if( !libspectrum_snap_didaktik80_active( snap ) ) return;

  if( libspectrum_snap_didaktik80_custom_rom( snap ) &&
      libspectrum_snap_didaktik80_rom( snap, 0 ) &&
      machine_load_rom_bank_from_buffer(
                             didaktik_memory_map_romcs_rom, 0,
                             libspectrum_snap_didaktik80_rom( snap, 0 ),
                             ROM_SIZE, 1 ) )
    return;

  if( libspectrum_snap_didaktik80_ram( snap, 0 ) ) {
    for( i = 0; i < MEMORY_PAGES_IN_2K; i++ )
      memcpy( didaktik_memory_map_romcs_ram[ i ].page,
              libspectrum_snap_didaktik80_ram( snap, 0 ) + i * MEMORY_PAGE_SIZE,
              MEMORY_PAGE_SIZE );
  }

  /* ignore drive count for now, there will be an issue with loading snaps where
     drives have been disabled
  libspectrum_snap_didaktik80_drive_count( snap )
   */

  didaktik_fdc->direction = libspectrum_snap_plusd_direction( snap );

  didaktik_cr_write ( 0x0081, libspectrum_snap_didaktik80_status ( snap ) );
  didaktik_tr_write ( 0x0083, libspectrum_snap_didaktik80_track  ( snap ) );
  didaktik_sec_write( 0x0085, libspectrum_snap_didaktik80_sector ( snap ) );
  didaktik_dr_write ( 0x0087, libspectrum_snap_didaktik80_data   ( snap ) );
  didaktik_aux_write( 0x0089, libspectrum_snap_didaktik80_aux    ( snap ) );

  if( libspectrum_snap_didaktik80_paged( snap ) ) {
    didaktik80_page();
  } else {
    didaktik80_unpage();
  }
}
コード例 #2
0
int
didaktik80_unittest( void )
{
  int r = 0;

  didaktik80_page();

  r += unittests_assert_8k_page( 0x0000, didaktik_rom_memory_source, 0 );
  r += unittests_assert_4k_page( 0x2000, didaktik_rom_memory_source, 0 );
  r += unittests_assert_2k_page( 0x3000, didaktik_rom_memory_source, 0 );
  r += unittests_assert_2k_page( 0x3800, didaktik_ram_memory_source, 0 );
  r += unittests_assert_16k_ram_page( 0x4000, 5 );
  r += unittests_assert_16k_ram_page( 0x8000, 2 );
  r += unittests_assert_16k_ram_page( 0xc000, 0 );

  didaktik80_unpage();

  r += unittests_paging_test_48( 2 );

  return r;
}
コード例 #3
0
ファイル: z80_ops.c プロジェクト: jacadym/fuse-emulator
/* Execute Z80 opcodes until the next event */
void
z80_do_opcodes( void )
{
#ifdef HAVE_ENOUGH_MEMORY
  libspectrum_byte opcode = 0x00;
#endif

  int even_m1 =
    machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_EVEN_M1; 

#ifdef __GNUC__

#undef SETUP_CHECK
#define SETUP_CHECK( label, condition ) \
  if( condition ) { cgoto[ next ] = &&label; next = pos_##label + 1; } \
  check++;

#undef SETUP_NEXT
#define SETUP_NEXT( label ) \
  if( next != check ) { cgoto[ next ] = &&label; } \
  next = check;

  void *cgoto[ numchecks ]; size_t next = 0; size_t check = 0;

#include "z80_checks.h"

#endif				/* #ifdef __GNUC__ */

  while( tstates < event_next_event ) {

    /* Profiler */
    CHECK( profile, profile_active )

    profile_map( PC );

    END_CHECK

    /* If we're due an end of frame from RZX playback, generate one */
    CHECK( rzx, rzx_playback )

    if( R + rzx_instructions_offset >= rzx_instruction_count ) {
      event_add( tstates, spectrum_frame_event );
      break;		/* And break out of the execution loop to let
			   the interrupt happen */
    }

    END_CHECK

    /* Check if the debugger should become active at this point */
    CHECK( debugger, debugger_mode != DEBUGGER_MODE_INACTIVE )

    if( !z80.halted && debugger_check( DEBUGGER_BREAKPOINT_TYPE_EXECUTE, PC ) )
      debugger_trap();

    END_CHECK

    CHECK( beta, beta_available )

#define NOT_128_TYPE_OR_IS_48_TYPE ( !( machine_current->capabilities & \
            LIBSPECTRUM_MACHINE_CAPABILITY_128_MEMORY ) || \
            machine_current->ram.current_rom )

    if( beta_active ) {
      if( NOT_128_TYPE_OR_IS_48_TYPE && PC >= 16384 ) {
	beta_unpage();
      }
    } else if( ( PC & beta_pc_mask ) == beta_pc_value &&
               NOT_128_TYPE_OR_IS_48_TYPE ) {
      beta_page();
    }

    END_CHECK

    CHECK( plusd, plusd_available )

    if( PC == 0x0008 || PC == 0x003a || PC == 0x0066 || PC == 0x028e ) {
      plusd_page();
    }

    END_CHECK

    CHECK( didaktik80, didaktik80_available )

    if( PC == 0x0000 || PC == 0x0008 ) {
      didaktik80_page();
    } else if( PC == 0x1700 ) {
      didaktik80_unpage();
    }

    END_CHECK

    CHECK( disciple, disciple_available )

    if( PC == 0x0001 || PC == 0x0008 || PC == 0x0066 || PC == 0x028e ) {
      disciple_page();
    }

    END_CHECK

    CHECK( usource, usource_available )

    if( PC == 0x2bae ) {
      usource_toggle();
    }

    END_CHECK

    CHECK( if1p, if1_available )

    if( PC == 0x0008 || PC == 0x1708 ) {
      if1_page();
    }

    END_CHECK

    CHECK( divide_early, settings_current.divide_enabled )
    
    if( ( PC & 0xff00 ) == 0x3d00 ) {
      divide_set_automap( 1 );
    }
    
    END_CHECK

    CHECK( spectranet_page, spectranet_available && !settings_current.spectranet_disable )

    if( PC == 0x0008 || ((PC & 0xfff8) == 0x3ff8) )
      spectranet_page( 0 );

    if( PC == spectranet_programmable_trap &&
      spectranet_programmable_trap_active )
      event_add( 0, z80_nmi_event );

    END_CHECK

  opcode_delay:

    contend_read( PC, 4 );

    /* Check to see if M1 cycles happen on even tstates */
    CHECK( evenm1, even_m1 )

    if( tstates & 1 ) {
      if( ++tstates == event_next_event ) {
	break;
      }
    }

    END_CHECK

  run_opcode:
    /* Do the instruction fetch; readbyte_internal used here to avoid
       triggering read breakpoints */
    opcode = readbyte_internal( PC );

    CHECK( if1u, if1_available )

    if( PC == 0x0700 ) {
      if1_unpage();
    }

    END_CHECK

    CHECK( divide_late, settings_current.divide_enabled )

    if( ( PC & 0xfff8 ) == 0x1ff8 ) {
      divide_set_automap( 0 );
    } else if( (PC == 0x0000) || (PC == 0x0008) || (PC == 0x0038)
      || (PC == 0x0066) || (PC == 0x04c6) || (PC == 0x0562) ) {
      divide_set_automap( 1 );
    }
    
    END_CHECK

    CHECK( opus, opus_available )

    if( opus_active ) {
      if( PC == 0x1748 ) {
        opus_unpage();
      }
    } else if( PC == 0x0008 || PC == 0x0048 || PC == 0x1708 ) {
      opus_page();
    }

    END_CHECK

    CHECK( spectranet_unpage, spectranet_available )

    if( PC == 0x007c )
      spectranet_unpage();

    END_CHECK

    CHECK( z80_halted, z80.halted )

    /* Opcode read from memory is ignored and PC is left unchanged */
    R++;
    continue;

    END_CHECK

    CHECK( z80_iff2_read, z80.iff2_read )

    z80.iff2_read = 0;
    /* Execute *one* instruction before reevaluating the checks */
    event_add( tstates, z80_nmos_iff2_event );

    END_CHECK

    CHECK( didaktik80snap, didaktik80_snap )

    if( PC == 0x0066 && !didaktik80_active ) {
      opcode = 0xc7;	/* RST 00 */
      didaktik80_snap = 0; /* FIXME: this should be a time-based reset */
    }

    END_CHECK

    CHECK( svg_capture, svg_capture_active )

    svg_capture();

    END_CHECK

  end_opcode:
    PC++; R++;
    switch(opcode) {
#include "z80/opcodes_base.c"
    }

  }

}