@@ -16,7 +16,7 @@ function _set(byte, mask, set) {
16
16
return ( byte & ~ mask ) | ( set ? mask : 0 ) ;
17
17
}
18
18
19
- class Flags {
19
+ export class Flags {
20
20
constructor ( ) {
21
21
this . _byte = 0x30 ;
22
22
}
@@ -98,6 +98,22 @@ class Flags {
98
98
setFromByte ( byte ) {
99
99
this . _byte = byte | 0x30 ;
100
100
}
101
+
102
+ /**
103
+ * Save the flags state
104
+ * @returns {number } The flags byte value
105
+ */
106
+ saveState ( ) {
107
+ return this . _byte ;
108
+ }
109
+
110
+ /**
111
+ * Load flags state
112
+ * @param {number } byte The flags byte value
113
+ */
114
+ loadState ( byte ) {
115
+ this . _byte = byte ;
116
+ }
101
117
}
102
118
103
119
class Base6502 {
@@ -149,6 +165,59 @@ class Base6502 {
149
165
}
150
166
}
151
167
168
+ /**
169
+ * Save CPU state
170
+ * @param {SaveState } saveState The SaveState to save to
171
+ */
172
+ saveState ( saveState ) {
173
+ const state = {
174
+ // Register state
175
+ a : this . a ,
176
+ x : this . x ,
177
+ y : this . y ,
178
+ s : this . s ,
179
+ pc : this . pc ,
180
+ p : this . p . saveState ( ) ,
181
+
182
+ // Interrupt state
183
+ interrupt : this . interrupt ,
184
+ nmiLevel : this . _nmiLevel ,
185
+ nmiEdge : this . _nmiEdge ,
186
+
187
+ // Other CPU state
188
+ takeInt : this . takeInt ,
189
+ halted : this . halted ,
190
+ } ;
191
+
192
+ saveState . addComponent ( "cpu" , state ) ;
193
+ }
194
+
195
+ /**
196
+ * Load CPU state
197
+ * @param {SaveState } saveState The SaveState to load from
198
+ */
199
+ loadState ( saveState ) {
200
+ const state = saveState . getComponent ( "cpu" ) ;
201
+ if ( ! state ) return ;
202
+
203
+ // Register state
204
+ this . a = state . a ;
205
+ this . x = state . x ;
206
+ this . y = state . y ;
207
+ this . s = state . s ;
208
+ this . pc = state . pc ;
209
+ this . p . loadState ( state . p ) ;
210
+
211
+ // Interrupt state
212
+ this . interrupt = state . interrupt ;
213
+ this . _nmiLevel = state . nmiLevel ;
214
+ this . _nmiEdge = state . nmiEdge ;
215
+
216
+ // Other CPU state
217
+ this . takeInt = state . takeInt ;
218
+ this . halted = state . halted ;
219
+ }
220
+
152
221
incpc ( ) {
153
222
this . pc = ( this . pc + 1 ) & 0xffff ;
154
223
}
@@ -637,6 +706,135 @@ export class Cpu6502 extends Base6502 {
637
706
this . fdc = new this . model . Fdc ( this , this . ddNoise , this . scheduler , this . debugFlags ) ;
638
707
}
639
708
709
+ /**
710
+ * Save CPU state
711
+ * @param {SaveState } saveState The SaveState to save to
712
+ */
713
+ saveState ( saveState ) {
714
+ // Call the base class method to save CPU core state
715
+ super . saveState ( saveState ) ;
716
+
717
+ // Save CPU specific state
718
+ const state = {
719
+ // Memory state
720
+ memStatOffsetByIFetchBank : this . memStatOffsetByIFetchBank ,
721
+ memStatOffset : this . memStatOffset ,
722
+ memStat : this . memStat ,
723
+ memLook : this . memLook ,
724
+
725
+ // RAM state - only save relevant portions
726
+ ram : this . ramRomOs . slice ( 0 , 128 * 1024 ) , // Main RAM (128K)
727
+
728
+ // Hardware registers
729
+ romsel : this . romsel ,
730
+ acccon : this . acccon ,
731
+ resetLine : this . resetLine ,
732
+ music5000PageSel : this . music5000PageSel ,
733
+
734
+ // Timing state
735
+ peripheralCycles : this . peripheralCycles ,
736
+ videoCycles : this . videoCycles ,
737
+ cycleSeconds : this . cycleSeconds ,
738
+ currentCycles : this . currentCycles ,
739
+ targetCycles : this . targetCycles ,
740
+
741
+ // Video display state
742
+ videoDisplayPage : this . videoDisplayPage ,
743
+
744
+ // Debug state not needed for regular save states
745
+ // oldPcArray, oldAArray, oldXArray, oldYArray, oldPcIndex
746
+ } ;
747
+
748
+ // Add to the saveState
749
+ saveState . addComponent ( "cpu_extended" , state ) ;
750
+
751
+ // Save scheduler state
752
+ this . scheduler . saveState ( saveState ) ;
753
+
754
+ // Save peripheral states
755
+ // TODO: Implement saveState in these components
756
+ // this.tube.saveState(saveState);
757
+ // this.sysvia.saveState(saveState);
758
+ // this.uservia.saveState(saveState);
759
+ // this.acia.saveState(saveState);
760
+ // this.serial.saveState(saveState);
761
+ // this.adconverter.saveState(saveState);
762
+ // this.soundChip.saveState(saveState);
763
+
764
+ // Video component is already implemented
765
+ this . video . saveState ( saveState ) ;
766
+
767
+ // TODO: Implement saveState in these components
768
+ // this.fdc.saveState(saveState);
769
+ // if (this.music5000) this.music5000.saveState(saveState);
770
+ // if (this.econet) this.econet.saveState(saveState);
771
+ // if (this.cmos) this.cmos.saveState(saveState);
772
+ }
773
+
774
+ /**
775
+ * Load CPU state
776
+ * @param {SaveState } saveState The SaveState to load from
777
+ */
778
+ loadState ( saveState ) {
779
+ // Call the base class method to load CPU core state
780
+ super . loadState ( saveState ) ;
781
+
782
+ // Load CPU specific state
783
+ const state = saveState . getComponent ( "cpu_extended" ) ;
784
+ if ( ! state ) return ;
785
+
786
+ // Memory configuration
787
+ this . memStatOffsetByIFetchBank = state . memStatOffsetByIFetchBank ;
788
+ this . memStatOffset = state . memStatOffset ;
789
+ this . memStat . set ( state . memStat ) ;
790
+
791
+ // memLook is a Int32Array
792
+ for ( let i = 0 ; i < state . memLook . length ; i ++ ) {
793
+ this . memLook [ i ] = state . memLook [ i ] ;
794
+ }
795
+
796
+ // RAM state
797
+ this . ramRomOs . set ( state . ram , 0 ) ; // Copy RAM
798
+
799
+ // Hardware registers
800
+ this . romsel = state . romsel ;
801
+ this . acccon = state . acccon ;
802
+ this . resetLine = state . resetLine ;
803
+ this . music5000PageSel = state . music5000PageSel ;
804
+
805
+ // Timing state
806
+ this . peripheralCycles = state . peripheralCycles ;
807
+ this . videoCycles = state . videoCycles ;
808
+ this . cycleSeconds = state . cycleSeconds ;
809
+ this . currentCycles = state . currentCycles ;
810
+ this . targetCycles = state . targetCycles ;
811
+
812
+ // Video display state
813
+ this . videoDisplayPage = state . videoDisplayPage ;
814
+
815
+ // Load scheduler state
816
+ this . scheduler . loadState ( saveState ) ;
817
+
818
+ // Load peripheral states
819
+ // TODO: Implement loadState in these components
820
+ // this.tube.loadState(saveState);
821
+ // this.sysvia.loadState(saveState);
822
+ // this.uservia.loadState(saveState);
823
+ // this.acia.loadState(saveState);
824
+ // this.serial.loadState(saveState);
825
+ // this.adconverter.loadState(saveState);
826
+ // this.soundChip.loadState(saveState);
827
+
828
+ // Video component is already implemented
829
+ this . video . loadState ( saveState ) ;
830
+
831
+ // TODO: Implement loadState in these components
832
+ // this.fdc.loadState(saveState);
833
+ // if (this.music5000) this.music5000.loadState(saveState);
834
+ // if (this.econet) this.econet.loadState(saveState);
835
+ // if (this.cmos) this.cmos.loadState(saveState);
836
+ }
837
+
640
838
getPrevPc ( index ) {
641
839
return this . oldPcArray [ ( this . oldPcIndex - index ) & 0xff ] ;
642
840
}
0 commit comments