Improved scrolling and added better memcpy/memmove functions written in assembly.
This commit is contained in:
parent
6ec9e0d320
commit
c745c2d2d3
@ -11,8 +11,8 @@
|
|||||||
BA_EXTERN_C_BEGIN
|
BA_EXTERN_C_BEGIN
|
||||||
|
|
||||||
BA_CXX_NODISCARD int memcmp(const void* lhs, const void* rhs, size_t count) BA_CXX_NOEXCEPT;
|
BA_CXX_NODISCARD int memcmp(const void* lhs, const void* rhs, size_t count) BA_CXX_NOEXCEPT;
|
||||||
void memcpy(void* dest, const void* src, size_t count) BA_CXX_NOEXCEPT;
|
void* memcpy(void* dest, const void* src, size_t count) BA_CXX_NOEXCEPT;
|
||||||
void memmove(void* dest, const void* src, size_t count) BA_CXX_NOEXCEPT;
|
void* memmove(void* dest, const void* src, size_t count) BA_CXX_NOEXCEPT;
|
||||||
void* memset(void* dest, int value, size_t count) BA_CXX_NOEXCEPT;
|
void* memset(void* dest, int value, size_t count) BA_CXX_NOEXCEPT;
|
||||||
BA_CXX_NODISCARD size_t strlen(const char* str) BA_CXX_NOEXCEPT;
|
BA_CXX_NODISCARD size_t strlen(const char* str) BA_CXX_NOEXCEPT;
|
||||||
|
|
||||||
|
@ -20,16 +20,16 @@ int memcmp(const void* lhs, const void* rhs, size_t count) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(__x86_64__)
|
#if !defined(__x86_64__)
|
||||||
void memcpy(void* dest, const void* src, size_t count) noexcept
|
void* memcpy(void* dest, const void* src, size_t count) noexcept
|
||||||
{
|
{
|
||||||
for (size_t pos = 0; pos < count; ++pos)
|
for (size_t pos = 0; pos < count; ++pos)
|
||||||
{
|
{
|
||||||
*(static_cast<uint8_t*>(dest) + pos) = *(static_cast<const uint8_t*>(src) + pos);
|
*(static_cast<uint8_t*>(dest) + pos) = *(static_cast<const uint8_t*>(src) + pos);
|
||||||
}
|
}
|
||||||
|
return dest;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void memmove(void* dest, const void* src, size_t count) noexcept
|
void* memmove(void* dest, const void* src, size_t count) noexcept
|
||||||
{
|
{
|
||||||
if (dest < src)
|
if (dest < src)
|
||||||
{
|
{
|
||||||
@ -45,7 +45,9 @@ void memmove(void* dest, const void* src, size_t count) noexcept
|
|||||||
*(static_cast<uint8_t*>(dest) + count - pos - 1) = *(static_cast<const uint8_t*>(src) + count - pos - 1);
|
*(static_cast<uint8_t*>(dest) + count - pos - 1) = *(static_cast<const uint8_t*>(src) + count - pos - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return dest;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void* memset(void* dest, int value, size_t count) noexcept
|
void* memset(void* dest, int value, size_t count) noexcept
|
||||||
{
|
{
|
||||||
|
@ -16,11 +16,16 @@ void scrollVertical(int scrollY, const Pixel& fillColor) noexcept
|
|||||||
if (scrollY == 0) {
|
if (scrollY == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const std::ptrdiff_t pixelOffset = scrollY * gFramebuffer.getPitch();
|
|
||||||
if (scrollY > 0)
|
if (scrollY > 0)
|
||||||
{
|
{
|
||||||
// std::memmove(gFramebuffer.getBase(), gFramebuffer.getBase() + pixelOffset, gFramebuffer.getBufferSize() - (4 * pixelOffset));
|
const size_t bytesPerRow = gDoubleBuffer.getPitch() * sizeof(Pixel);
|
||||||
// std::memset(gFramebuffer.getBase() + pixelOffset, 0, )
|
const size_t bytesToMove = (gDoubleBuffer.getHeight() - scrollY) * bytesPerRow;
|
||||||
|
const size_t byteDist = scrollY * bytesPerRow;
|
||||||
|
uint8_t* basePtr = reinterpret_cast<uint8_t*>(gDoubleBuffer.getBase());
|
||||||
|
std::memmove(basePtr, basePtr + byteDist, bytesToMove);
|
||||||
|
std::memset(basePtr + byteDist, 0, byteDist);
|
||||||
|
std::memcpy(gFramebuffer.getBase(), gDoubleBuffer.getBase(), gDoubleBuffer.getHeight() * bytesPerRow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,11 +113,11 @@ void character(unsigned posX, unsigned posY, const psf::Font& font, char chr, co
|
|||||||
|
|
||||||
void scrollBy(int scrollX, int scrollY, const Pixel& fillColor) noexcept
|
void scrollBy(int scrollX, int scrollY, const Pixel& fillColor) noexcept
|
||||||
{
|
{
|
||||||
// if (scrollX == 0)
|
if (scrollX == 0)
|
||||||
// {
|
{
|
||||||
// scrollVertical(scrollY, fillColor);
|
scrollVertical(scrollY, fillColor);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
const int width = static_cast<int>(gFramebuffer.getHeight());
|
const int width = static_cast<int>(gFramebuffer.getHeight());
|
||||||
const int height = static_cast<int>(gFramebuffer.getHeight());
|
const int height = static_cast<int>(gFramebuffer.getHeight());
|
||||||
const bool reverseX = scrollX < 0;
|
const bool reverseX = scrollX < 0;
|
||||||
|
@ -3,25 +3,64 @@
|
|||||||
.global memcpy
|
.global memcpy
|
||||||
.type memcpy @function
|
.type memcpy @function
|
||||||
|
|
||||||
// int memcpy(void* dest [%rdi], void* src [%rsi], size_t count [%rdx])
|
// void* memcpy(void* dest [%rdi], void* src [%rsi], size_t count [%rdx])
|
||||||
//
|
//
|
||||||
memcpy:
|
memcpy:
|
||||||
cmpq %rdx, 4
|
movq %rdi, %rax // return value
|
||||||
jl memcpy_bytes
|
memcpy_qwords:
|
||||||
movq (%rsi), %rax
|
cmpq $8, %rdx // check if the remaining bytes are at least 8
|
||||||
movq %rax, (%rdi)
|
jl memcpy_bytes // if not copy the remaining bytes per byte
|
||||||
addq $4, %rsi
|
movq (%rsi), %rcx // if yes, copy using movq
|
||||||
addq $4, %rdi
|
movq %rcx, (%rdi)
|
||||||
subq $4, %rdx
|
addq $8, %rsi
|
||||||
jmp memcpy
|
addq $8, %rdi
|
||||||
|
subq $8, %rdx
|
||||||
|
jmp memcpy_qwords
|
||||||
memcpy_bytes:
|
memcpy_bytes:
|
||||||
cmpq %rdx, 0
|
cmpq $0, %rdx
|
||||||
je memcpy_end
|
je memcpy_end
|
||||||
movb (%rsi), %ah
|
movb (%rsi), %ch
|
||||||
movb %ah, (%rdi)
|
movb %ch, (%rdi)
|
||||||
addq $1, %rsi
|
addq $1, %rsi
|
||||||
addq $1, %rdi
|
addq $1, %rdi
|
||||||
subq $1, %rdx
|
subq $1, %rdx
|
||||||
jmp memcpy_bytes
|
jmp memcpy_bytes
|
||||||
memcpy_end:
|
memcpy_end:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.global memmove
|
||||||
|
.type memmove @function
|
||||||
|
// void* memmove(void* dest [%rdi], void* src [%rsi], size_t count [%rdx])
|
||||||
|
//
|
||||||
|
memmove:
|
||||||
|
movq %rdi, %rax // preserve dest as return value
|
||||||
|
cmpq %rsi, %rdi // check if dest > src
|
||||||
|
jg memmove_backward // if yes, do everything backwards
|
||||||
|
movq %rsi, %rcx // check if (src - dest) < 8
|
||||||
|
subq %rdi, %rcx
|
||||||
|
cmpq $8, %rdi
|
||||||
|
jl memcpy_bytes // if yes, we have to do a bytewise copy
|
||||||
|
jmp memcpy_qwords // otherwise copy whole qwords
|
||||||
|
memmove_backward: // dest > src, copy backwards
|
||||||
|
addq %rdx, %rdi // dest = dest + count
|
||||||
|
addq %rdx, %rsi // src = src + count
|
||||||
|
memmove_qwords:
|
||||||
|
cmpq $8, %rdx // check if the remaining bytes are at least 8
|
||||||
|
jl memmove_bytes // if not copy the remaining bytes per byte
|
||||||
|
movq -8(%rsi), %rcx // if yes, copy using movq
|
||||||
|
movq %rcx, -8(%rdi)
|
||||||
|
subq $8, %rsi
|
||||||
|
subq $8, %rdi
|
||||||
|
subq $8, %rdx
|
||||||
|
jmp memmove_qwords
|
||||||
|
memmove_bytes:
|
||||||
|
cmpq $0, %rdx
|
||||||
|
je memmove_end
|
||||||
|
movb (%rsi), %ch
|
||||||
|
movb %ch, (%rdi)
|
||||||
|
subq $1, %rsi
|
||||||
|
subq $1, %rdi
|
||||||
|
subq $1, %rdx
|
||||||
|
jmp memmove_bytes
|
||||||
|
memmove_end:
|
||||||
|
ret
|
||||||
|
Loading…
x
Reference in New Issue
Block a user