NOTE: called from outside MTGS
| 2989 | |
| 2990 | // NOTE: called from outside MTGS |
| 2991 | void GSState::Read(u8* mem, int len) |
| 2992 | { |
| 2993 | if (len <= 0 || m_tr.total == 0) |
| 2994 | return; |
| 2995 | |
| 2996 | if (m_env.TRXDIR.XDIR == 3) |
| 2997 | return; |
| 2998 | |
| 2999 | const int w = m_env.TRXREG.RRW; |
| 3000 | const int h = m_env.TRXREG.RRH; |
| 3001 | const u16 bpp = GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM].trbpp; |
| 3002 | |
| 3003 | CheckWriteOverlap(false, true); |
| 3004 | |
| 3005 | if (!m_tr.Update(w, h, bpp, len)) |
| 3006 | return; |
| 3007 | |
| 3008 | const u64 draw = s_n; |
| 3009 | |
| 3010 | if (draw != s_n) |
| 3011 | DevCon.Warning("Warning! Possible incorrect data download"); |
| 3012 | |
| 3013 | // If it wraps memory, we need to break it up so we don't read out of bounds. |
| 3014 | if ((m_tr.end + len) > m_mem.m_vmsize) |
| 3015 | { |
| 3016 | const int first_transfer = m_mem.m_vmsize - m_tr.end; |
| 3017 | const int second_transfer = len - first_transfer; |
| 3018 | memcpy(mem, &m_tr.buff[m_tr.end], first_transfer); |
| 3019 | m_tr.end = 0; |
| 3020 | memcpy(&mem[first_transfer], &m_tr.buff, second_transfer); |
| 3021 | m_tr.end = second_transfer; |
| 3022 | } |
| 3023 | else |
| 3024 | { |
| 3025 | memcpy(mem, &m_tr.buff[m_tr.end], len); |
| 3026 | m_tr.end += len; |
| 3027 | } |
| 3028 | |
| 3029 | if(m_tr.end >= m_tr.total) |
| 3030 | m_env.TRXDIR.XDIR = 3; |
| 3031 | } |
| 3032 | |
| 3033 | void GSState::Move() |
| 3034 | { |