Mercurial > spc_convert
diff snes_spc/SNES_SPC_state.cpp @ 0:e38dacceb958
initial import
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 21 Oct 2011 05:53:11 -0700 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/snes_spc/SNES_SPC_state.cpp Fri Oct 21 05:53:11 2011 -0700 1.3 @@ -0,0 +1,129 @@ 1.4 +// SPC emulation state save/load: copy_state(), save_spc() 1.5 +// Separate file to avoid linking in unless needed 1.6 + 1.7 +// snes_spc 0.9.0. http://www.slack.net/~ant/ 1.8 + 1.9 +#include "SNES_SPC.h" 1.10 + 1.11 +#if !SPC_NO_COPY_STATE_FUNCS 1.12 + 1.13 +#include <string.h> 1.14 + 1.15 +/* Copyright (C) 2004-2007 Shay Green. This module is free software; you 1.16 +can redistribute it and/or modify it under the terms of the GNU Lesser 1.17 +General Public License as published by the Free Software Foundation; either 1.18 +version 2.1 of the License, or (at your option) any later version. This 1.19 +module is distributed in the hope that it will be useful, but WITHOUT ANY 1.20 +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 1.21 +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 1.22 +details. You should have received a copy of the GNU Lesser General Public 1.23 +License along with this module; if not, write to the Free Software Foundation, 1.24 +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 1.25 + 1.26 +#include "blargg_source.h" 1.27 + 1.28 +#define RAM (m.ram.ram) 1.29 +#define REGS (m.smp_regs [0]) 1.30 +#define REGS_IN (m.smp_regs [1]) 1.31 + 1.32 +void SNES_SPC::save_regs( uint8_t out [reg_count] ) 1.33 +{ 1.34 + // Use current timer counter values 1.35 + for ( int i = 0; i < timer_count; i++ ) 1.36 + out [r_t0out + i] = m.timers [i].counter; 1.37 + 1.38 + // Last written values 1.39 + memcpy( out, REGS, r_t0out ); 1.40 +} 1.41 + 1.42 +void SNES_SPC::init_header( void* spc_out ) 1.43 +{ 1.44 + spc_file_t* const spc = (spc_file_t*) spc_out; 1.45 + 1.46 + spc->has_id666 = 26; // has none 1.47 + spc->version = 30; 1.48 + memcpy( spc, signature, sizeof spc->signature ); 1.49 + memset( spc->text, 0, sizeof spc->text ); 1.50 +} 1.51 + 1.52 +void SNES_SPC::save_spc( void* spc_out ) 1.53 +{ 1.54 + spc_file_t* const spc = (spc_file_t*) spc_out; 1.55 + 1.56 + // CPU 1.57 + spc->pcl = (uint8_t) (m.cpu_regs.pc >> 0); 1.58 + spc->pch = (uint8_t) (m.cpu_regs.pc >> 8); 1.59 + spc->a = m.cpu_regs.a; 1.60 + spc->x = m.cpu_regs.x; 1.61 + spc->y = m.cpu_regs.y; 1.62 + spc->psw = m.cpu_regs.psw; 1.63 + spc->sp = m.cpu_regs.sp; 1.64 + 1.65 + // RAM, ROM 1.66 + memcpy( spc->ram, RAM, sizeof spc->ram ); 1.67 + if ( m.rom_enabled ) 1.68 + memcpy( spc->ram + rom_addr, m.hi_ram, sizeof m.hi_ram ); 1.69 + memset( spc->unused, 0, sizeof spc->unused ); 1.70 + memcpy( spc->ipl_rom, m.rom, sizeof spc->ipl_rom ); 1.71 + 1.72 + // SMP registers 1.73 + save_regs( &spc->ram [0xF0] ); 1.74 + int i; 1.75 + for ( i = 0; i < port_count; i++ ) 1.76 + spc->ram [0xF0 + r_cpuio0 + i] = REGS_IN [r_cpuio0 + i]; 1.77 + 1.78 + // DSP registers 1.79 + for ( i = 0; i < SPC_DSP::register_count; i++ ) 1.80 + spc->dsp [i] = dsp.read( i ); 1.81 +} 1.82 + 1.83 +void SNES_SPC::copy_state( unsigned char** io, copy_func_t copy ) 1.84 +{ 1.85 + SPC_State_Copier copier( io, copy ); 1.86 + 1.87 + // Make state data more readable by putting 64K RAM, 16 SMP registers, 1.88 + // then DSP (with its 128 registers) first 1.89 + 1.90 + // RAM 1.91 + enable_rom( 0 ); // will get re-enabled if necessary in regs_loaded() below 1.92 + copier.copy( RAM, 0x10000 ); 1.93 + 1.94 + { 1.95 + // SMP registers 1.96 + uint8_t out_ports [port_count]; 1.97 + uint8_t regs [reg_count]; 1.98 + memcpy( out_ports, ®S [r_cpuio0], sizeof out_ports ); 1.99 + save_regs( regs ); 1.100 + copier.copy( regs, sizeof regs ); 1.101 + copier.copy( out_ports, sizeof out_ports ); 1.102 + load_regs( regs ); 1.103 + regs_loaded(); 1.104 + memcpy( ®S [r_cpuio0], out_ports, sizeof out_ports ); 1.105 + } 1.106 + 1.107 + // CPU registers 1.108 + SPC_COPY( uint16_t, m.cpu_regs.pc ); 1.109 + SPC_COPY( uint8_t, m.cpu_regs.a ); 1.110 + SPC_COPY( uint8_t, m.cpu_regs.x ); 1.111 + SPC_COPY( uint8_t, m.cpu_regs.y ); 1.112 + SPC_COPY( uint8_t, m.cpu_regs.psw ); 1.113 + SPC_COPY( uint8_t, m.cpu_regs.sp ); 1.114 + copier.extra(); 1.115 + 1.116 + SPC_COPY( int16_t, m.spc_time ); 1.117 + SPC_COPY( int16_t, m.dsp_time ); 1.118 + 1.119 + // DSP 1.120 + dsp.copy_state( io, copy ); 1.121 + 1.122 + // Timers 1.123 + for ( int i = 0; i < timer_count; i++ ) 1.124 + { 1.125 + Timer* t = &m.timers [i]; 1.126 + SPC_COPY( int16_t, t->next_time ); 1.127 + SPC_COPY( uint8_t, t->divider ); 1.128 + copier.extra(); 1.129 + } 1.130 + copier.extra(); 1.131 +} 1.132 +#endif