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