annotate snes_spc/SNES_SPC_state.cpp @ 6:a012d31df380

Made convert.pl work in parallel. Restored files in less than 2 minutes!
author Robert McIntyre <rlm@mit.edu>
date Fri, 21 Oct 2011 07:23:22 -0700
parents e38dacceb958
children
rev   line source
rlm@0 1 // SPC emulation state save/load: copy_state(), save_spc()
rlm@0 2 // Separate file to avoid linking in unless needed
rlm@0 3
rlm@0 4 // snes_spc 0.9.0. http://www.slack.net/~ant/
rlm@0 5
rlm@0 6 #include "SNES_SPC.h"
rlm@0 7
rlm@0 8 #if !SPC_NO_COPY_STATE_FUNCS
rlm@0 9
rlm@0 10 #include <string.h>
rlm@0 11
rlm@0 12 /* Copyright (C) 2004-2007 Shay Green. This module is free software; you
rlm@0 13 can redistribute it and/or modify it under the terms of the GNU Lesser
rlm@0 14 General Public License as published by the Free Software Foundation; either
rlm@0 15 version 2.1 of the License, or (at your option) any later version. This
rlm@0 16 module is distributed in the hope that it will be useful, but WITHOUT ANY
rlm@0 17 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
rlm@0 18 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
rlm@0 19 details. You should have received a copy of the GNU Lesser General Public
rlm@0 20 License along with this module; if not, write to the Free Software Foundation,
rlm@0 21 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
rlm@0 22
rlm@0 23 #include "blargg_source.h"
rlm@0 24
rlm@0 25 #define RAM (m.ram.ram)
rlm@0 26 #define REGS (m.smp_regs [0])
rlm@0 27 #define REGS_IN (m.smp_regs [1])
rlm@0 28
rlm@0 29 void SNES_SPC::save_regs( uint8_t out [reg_count] )
rlm@0 30 {
rlm@0 31 // Use current timer counter values
rlm@0 32 for ( int i = 0; i < timer_count; i++ )
rlm@0 33 out [r_t0out + i] = m.timers [i].counter;
rlm@0 34
rlm@0 35 // Last written values
rlm@0 36 memcpy( out, REGS, r_t0out );
rlm@0 37 }
rlm@0 38
rlm@0 39 void SNES_SPC::init_header( void* spc_out )
rlm@0 40 {
rlm@0 41 spc_file_t* const spc = (spc_file_t*) spc_out;
rlm@0 42
rlm@0 43 spc->has_id666 = 26; // has none
rlm@0 44 spc->version = 30;
rlm@0 45 memcpy( spc, signature, sizeof spc->signature );
rlm@0 46 memset( spc->text, 0, sizeof spc->text );
rlm@0 47 }
rlm@0 48
rlm@0 49 void SNES_SPC::save_spc( void* spc_out )
rlm@0 50 {
rlm@0 51 spc_file_t* const spc = (spc_file_t*) spc_out;
rlm@0 52
rlm@0 53 // CPU
rlm@0 54 spc->pcl = (uint8_t) (m.cpu_regs.pc >> 0);
rlm@0 55 spc->pch = (uint8_t) (m.cpu_regs.pc >> 8);
rlm@0 56 spc->a = m.cpu_regs.a;
rlm@0 57 spc->x = m.cpu_regs.x;
rlm@0 58 spc->y = m.cpu_regs.y;
rlm@0 59 spc->psw = m.cpu_regs.psw;
rlm@0 60 spc->sp = m.cpu_regs.sp;
rlm@0 61
rlm@0 62 // RAM, ROM
rlm@0 63 memcpy( spc->ram, RAM, sizeof spc->ram );
rlm@0 64 if ( m.rom_enabled )
rlm@0 65 memcpy( spc->ram + rom_addr, m.hi_ram, sizeof m.hi_ram );
rlm@0 66 memset( spc->unused, 0, sizeof spc->unused );
rlm@0 67 memcpy( spc->ipl_rom, m.rom, sizeof spc->ipl_rom );
rlm@0 68
rlm@0 69 // SMP registers
rlm@0 70 save_regs( &spc->ram [0xF0] );
rlm@0 71 int i;
rlm@0 72 for ( i = 0; i < port_count; i++ )
rlm@0 73 spc->ram [0xF0 + r_cpuio0 + i] = REGS_IN [r_cpuio0 + i];
rlm@0 74
rlm@0 75 // DSP registers
rlm@0 76 for ( i = 0; i < SPC_DSP::register_count; i++ )
rlm@0 77 spc->dsp [i] = dsp.read( i );
rlm@0 78 }
rlm@0 79
rlm@0 80 void SNES_SPC::copy_state( unsigned char** io, copy_func_t copy )
rlm@0 81 {
rlm@0 82 SPC_State_Copier copier( io, copy );
rlm@0 83
rlm@0 84 // Make state data more readable by putting 64K RAM, 16 SMP registers,
rlm@0 85 // then DSP (with its 128 registers) first
rlm@0 86
rlm@0 87 // RAM
rlm@0 88 enable_rom( 0 ); // will get re-enabled if necessary in regs_loaded() below
rlm@0 89 copier.copy( RAM, 0x10000 );
rlm@0 90
rlm@0 91 {
rlm@0 92 // SMP registers
rlm@0 93 uint8_t out_ports [port_count];
rlm@0 94 uint8_t regs [reg_count];
rlm@0 95 memcpy( out_ports, &REGS [r_cpuio0], sizeof out_ports );
rlm@0 96 save_regs( regs );
rlm@0 97 copier.copy( regs, sizeof regs );
rlm@0 98 copier.copy( out_ports, sizeof out_ports );
rlm@0 99 load_regs( regs );
rlm@0 100 regs_loaded();
rlm@0 101 memcpy( &REGS [r_cpuio0], out_ports, sizeof out_ports );
rlm@0 102 }
rlm@0 103
rlm@0 104 // CPU registers
rlm@0 105 SPC_COPY( uint16_t, m.cpu_regs.pc );
rlm@0 106 SPC_COPY( uint8_t, m.cpu_regs.a );
rlm@0 107 SPC_COPY( uint8_t, m.cpu_regs.x );
rlm@0 108 SPC_COPY( uint8_t, m.cpu_regs.y );
rlm@0 109 SPC_COPY( uint8_t, m.cpu_regs.psw );
rlm@0 110 SPC_COPY( uint8_t, m.cpu_regs.sp );
rlm@0 111 copier.extra();
rlm@0 112
rlm@0 113 SPC_COPY( int16_t, m.spc_time );
rlm@0 114 SPC_COPY( int16_t, m.dsp_time );
rlm@0 115
rlm@0 116 // DSP
rlm@0 117 dsp.copy_state( io, copy );
rlm@0 118
rlm@0 119 // Timers
rlm@0 120 for ( int i = 0; i < timer_count; i++ )
rlm@0 121 {
rlm@0 122 Timer* t = &m.timers [i];
rlm@0 123 SPC_COPY( int16_t, t->next_time );
rlm@0 124 SPC_COPY( uint8_t, t->divider );
rlm@0 125 copier.extra();
rlm@0 126 }
rlm@0 127 copier.extra();
rlm@0 128 }
rlm@0 129 #endif