diff --git a/zsnes/src/cpu/execute.asm b/zsnes/src/cpu/execute.asm index 713cd466..58955d25 100644 --- a/zsnes/src/cpu/execute.asm +++ b/zsnes/src/cpu/execute.asm @@ -55,21 +55,17 @@ EXTSYM fxbit67pcal,SfxSFR,nosprincr,cpucycle,switchtovirqdeb,switchtonmideb EXTSYM MovieSeekBehind,SaveSramData,BackupCVFrame,RestoreCVFrame,loadstate EXTSYM KeyInsrtChap,KeyNextChap,KeyPrevChap,MovieInsertChapter,MovieSeekAhead EXTSYM ResetDuringMovie,EMUPauseKey,INCRFrameKey,MovieWaiting,NoInputRead - +EXTSYM AllocatedRewindStates %ifdef __MSDOS__ EXTSYM dssel %endif SECTION .data -NEWSYM CBackupPos, dd 0 -NEWSYM PBackupPos, dd 0 NEWSYM tempedx, dd 0 NEWSYM tempesi, dd 0 NEWSYM tempedi, dd 0 NEWSYM tempebp, dd 0 -NEWSYM RewindOldPos, dd 0 -NEWSYM RewindPos, dd 0 NEWSYM RewindTimer, dd 0 NEWSYM BackState, db 1 NEWSYM BackStateSize, dd 6 @@ -96,76 +92,39 @@ NEWSYM ProcessRewind cmp byte[pressed+eax],1 jne near .notokay mov byte[pressed+eax],2 - mov eax,[RewindOldPos] - cmp [RewindPos],eax - je near .notokay - dec dword[RewindPos] - and dword[RewindPos],0Fh - mov eax,[RewindOldPos] - cmp [RewindPos],eax - je .notokay2 - dec dword[RewindPos] - and dword[RewindPos],0Fh - mov eax,[RewindPos] - mov [PBackupPos],eax - push ecx - push ebx + pushad call RestoreCVFrame popad + mov esi,[tempesi] mov edi,[tempedi] mov ebp,[tempebp] - ; Clear Cache Check - mov ebx,vidmemch2 - mov ecx,4096+4096+4096 -.next - mov byte[ebx],1 - inc ebx - dec ecx - jnz .next - pop ebx - pop ecx - inc dword[RewindPos] - and dword[RewindPos],0Fh mov edx,[tempedx] .notokay ret -.notokay2 - inc dword[RewindPos] - and dword[RewindPos],0Fh - ret NEWSYM UpdateRewind - push eax + cmp byte[AllocatedRewindStates],0 + je .norewinds cmp dword[KeyRewind],0 - je .notftimer - call ProcessRewind + je .norewinds + dec dword[RewindTimer] - jnz .notftimer - jmp .okay -.notftimer - pop eax - ret -.okay - mov eax,[RewindPos] - mov [CBackupPos],eax + jnz .checkrewind + mov [tempedx],edx mov [tempesi],esi mov [tempedi],edi mov [tempebp],ebp + pushad call BackupCVFrame popad - inc dword[RewindPos] - and dword[RewindPos],0Fh - mov eax,[RewindOldPos] - cmp [RewindPos],eax - jne .noteq - inc dword[RewindOldPos] - and dword[RewindOldPos],0Fh -.noteq - pop eax + +.checkrewind + call ProcessRewind +.norewinds ret SECTION .data diff --git a/zsnes/src/zstate.c b/zsnes/src/zstate.c index d78e6c58..78750291 100755 --- a/zsnes/src/zstate.c +++ b/zsnes/src/zstate.c @@ -192,75 +192,59 @@ static void memcpyrinc(unsigned char **src, void *dest, size_t len) extern unsigned int RewindTimer; extern unsigned char RewindStates; + unsigned char *StateBackup = 0; +unsigned char AllocatedRewindStates, LatestRewindPos, EarliestRewindPos; + size_t rewind_state_size, cur_zst_size, old_zst_size; -/* A nice idea, but needs more ported from the assembly first. -size_t RewindPos, RewindEarliestPos; +extern unsigned char RewindFrames, romispal; +extern unsigned char MovieProcessing; +void zmv_rewind_save(size_t, bool); +void zmv_rewind_load(size_t, bool); + +#define ActualRewindFrames (RewindFrames * (romispal ? 25 : 30)) void BackupCVFrame() { - unsigned char *RewindBufferPos = StateBackup + RewindPos*rewind_state_size; - printf("Backing up rewind in slot #%u\n", RewindPos); + unsigned char *RewindBufferPos = StateBackup + LatestRewindPos*rewind_state_size; + printf("Backing up rewind in slot #%u\n", LatestRewindPos); + + if (MovieProcessing == 1) { zmv_rewind_save(LatestRewindPos, true); } + else if (MovieProcessing == 2) { zmv_rewind_save(LatestRewindPos, false); } copy_state_data(RewindBufferPos, memcpyinc, false); - RewindPos++; - if (RewindPos == RewindStates) + + LatestRewindPos = (LatestRewindPos != AllocatedRewindStates-1) ? LatestRewindPos+1 : 0; + if (LatestRewindPos == EarliestRewindPos) { - RewindPos = 0; + EarliestRewindPos = (EarliestRewindPos != AllocatedRewindStates-1) ? EarliestRewindPos+1 : 0; } - if (RewindPos == RewindEarliestPos) - { - RewindEarliestPos++; - if (RewindEarliestPos == RewindStates) - { - RewindEarliestPos = 0; - } - } - RewindTimer = 60*3; + + RewindTimer = ActualRewindFrames; } void RestoreCVFrame() { - if (RewindPos != RewindEarliestPos) + unsigned char *RewindBufferPos; + + if (LatestRewindPos != EarliestRewindPos) { - unsigned char *RewindBufferPos; - - if (!RewindPos) - { - RewindPos = RewindStates; - } - RewindPos--; - - RewindBufferPos = StateBackup + RewindPos*rewind_state_size; - printf("Restoring rewind in slot #%u\n", RewindPos); - copy_state_data(RewindBufferPos, memcpyrinc, true); - - //Clear Cache Check - memset(vidmemch2, 1, sizeof(vidmemch2)); - memset(vidmemch4, 1, sizeof(vidmemch4)); - memset(vidmemch8, 1, sizeof(vidmemch8)); - - RewindTimer = 60*3; + LatestRewindPos = (LatestRewindPos) ? LatestRewindPos-1 : AllocatedRewindStates-1; } -} -void MultipleFrameBack(unsigned int i) -{ - while (i--) - { - if (RewindPos != RewindEarliestPos) - { - if (!RewindPos) - { - RewindPos = RewindStates; - } - RewindPos--; - } - else - { - break; - } - } + RewindBufferPos = StateBackup + LatestRewindPos*rewind_state_size; + printf("Restoring rewind in slot #%u\n", LatestRewindPos); + + if (MovieProcessing == 1) { zmv_rewind_load(LatestRewindPos, true); } + else if (MovieProcessing == 2) { zmv_rewind_load(LatestRewindPos, false); } + copy_state_data(RewindBufferPos, memcpyrinc, true); + + //Clear Cache Check + memset(vidmemch2, 1, sizeof(vidmemch2)); + memset(vidmemch4, 1, sizeof(vidmemch4)); + memset(vidmemch8, 1, sizeof(vidmemch8)); + + RewindTimer = ActualRewindFrames; } void SetupRewindBuffer() @@ -272,47 +256,7 @@ void SetupRewindBuffer() StateBackup = (unsigned char *)malloc(rewind_state_size*RewindStates); if (StateBackup) { break; } } -} -*/ - -extern unsigned int CBackupPos, PBackupPos, RewindPos, RewindOldPos; -extern unsigned char RewindFrames, romispal; -extern unsigned char MovieProcessing; -void zmv_rewind_save(size_t, bool); -void zmv_rewind_load(size_t, bool); - -#define ActualRewindFrames (RewindFrames * (romispal ? 25 : 30)) - -void BackupCVFrame() -{ - unsigned char *RewindBufferPos = StateBackup + CBackupPos*rewind_state_size; - //printf("Backing up rewind in slot #%u\n", CBackupPos); - copy_state_data(RewindBufferPos, memcpyinc, false); - if (MovieProcessing == 1) { zmv_rewind_save(CBackupPos, true); } - else if (MovieProcessing == 2) { zmv_rewind_save(CBackupPos, false); } - RewindTimer = ActualRewindFrames; -} - -void RestoreCVFrame() -{ - unsigned char *RewindBufferPos = StateBackup + PBackupPos*rewind_state_size; - //printf("Restoring rewind in slot #%u\n", PBackupPos); - copy_state_data(RewindBufferPos, memcpyrinc, true); - if (MovieProcessing == 1) { zmv_rewind_load(PBackupPos, true); } - else if (MovieProcessing == 2) { zmv_rewind_load(PBackupPos, false); } - RewindTimer = ActualRewindFrames; -} - -void SetupRewindBuffer() -{ - if (StateBackup){ free(StateBackup); } - RewindStates = 16; - StateBackup = 0; - StateBackup = (unsigned char *)malloc(rewind_state_size*RewindStates); - if (!StateBackup) - { - asm_call(outofmemory); - } + AllocatedRewindStates = RewindStates; } static size_t state_size; @@ -324,18 +268,15 @@ static void state_size_tally(unsigned char **dest, void *src, size_t len) void InitRewindVars() { -#ifndef __MSDOS__ //When all the code is ported to C, we can make this work with DOS too unsigned char almost_useless_array[1]; //An array is needed for copy_state_data to give the correct size state_size = 0; copy_state_data(almost_useless_array, state_size_tally, false); rewind_state_size = state_size; SetupRewindBuffer(); - RewindPos = 0; - RewindOldPos = 0; - //RewindEarliestPos = 0; - RewindTimer = ActualRewindFrames; -#endif + LatestRewindPos = 0; + EarliestRewindPos = 0; + RewindTimer = 1; } //This is used to preserve system load state between loads