Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Big Endian Linux platform (z/Linux) #136

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,17 @@ endif()

option(TV_BUILD_TESTS "Build and run tests" OFF)

# Endianness detection

include(TestBigEndian)
TEST_BIG_ENDIAN(BIGENDIAN)
if(${BIGENDIAN})
add_definitions(-DTV_BIG_ENDIAN)
tv_message_mp(STATUS "BIG ENDIAN platform detected")
else()
tv_message_mp(STATUS "LITTLE ENDIAN platform detected")
endif(${BIGENDIAN})

# Library

add_subdirectory(source)
Expand Down
4 changes: 2 additions & 2 deletions include/tvision/internal/ansidisp.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ struct TermColor

TermColor& operator=(uint32_t val) noexcept
{
memcpy(this, &val, sizeof(*this));
tvintmemcpy(this, &val, sizeof(*this));
return *this;
static_assert(sizeof(*this) == 4, "");
}
operator uint32_t() const noexcept
{
uint32_t val;
memcpy(&val, this, sizeof(*this));
tvintmemcpy(&val, this, sizeof(*this));
return val;
}
TermColor(uint8_t aIdx, TermColorTypes aType) noexcept
Expand Down
2 changes: 1 addition & 1 deletion include/tvision/internal/codepage.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class CpTranslator
static uint32_t toPackedUtf8(unsigned char c) noexcept
{
uint32_t asInt;
memcpy(&asInt, (*currentToUtf8)[c], sizeof(asInt));
tvintmemcpy(&asInt, (*currentToUtf8)[c], sizeof(asInt));
return asInt;
}

Expand Down
10 changes: 10 additions & 0 deletions include/tvision/internal/strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ inline constexpr Int string_as_int(TStringView s) noexcept
{
Int res = 0;
for (size_t i = 0; i < min(s.size(), sizeof(res)); ++i)
#ifndef TV_BIG_ENDIAN
// CAUTION: Assumes Little Endian.
res |= uint64_t(uint8_t(s[i])) << 8*i;
#else
res |= uint64_t(uint8_t(s[i])) << 8*(sizeof(res)-1-i);
#endif
return res;
}

Expand All @@ -35,13 +39,19 @@ inline char *fast_btoa(uint8_t value, char *buffer) noexcept
{
extern const btoa_lut_t btoa_lut;
const auto &lut = (btoa_lut_elem_t (&) [256]) btoa_lut;
#ifndef TV_BIG_ENDIAN
// CAUTION: Assumes Little Endian.
// We can afford to write more bytes into 'buffer' than digits.
uint32_t asInt;
memcpy(&asInt, &lut[value], 4);
memcpy(buffer, &asInt, 4);
return buffer + (asInt >> 24);
static_assert(sizeof(btoa_lut_elem_t) == 4, "");
#else
memcpy(buffer, &lut[value].chars, lut[value].digits);
buffer[lut[value].digits] = 0; // null-terminate for safety - may not be needed?
return buffer + lut[value].digits;
#endif
}

} // namespace tvision
Expand Down
2 changes: 1 addition & 1 deletion include/tvision/internal/utf8.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ inline size_t utf32To8(uint32_t u32, char u8[4]) noexcept
(( u32 & 0b00111111) | 0b10000000) << 24;
length = 4;
}
memcpy(u8, &asInt, 4);
tvintmemcpy(u8, &asInt, 4);
return length;
}

Expand Down
2 changes: 1 addition & 1 deletion include/tvision/scrncell.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ inline void TCellChar::moveInt(uint32_t mbc, bool wide)
{
memset(this, 0, sizeof(*this));
// CAUTION: Assumes Little Endian.
memcpy(_text, &mbc, sizeof(mbc));
tvintmemcpy(_text, &mbc, sizeof(mbc));
_flags = -int(wide) & fWide;
}

Expand Down
6 changes: 6 additions & 0 deletions include/tvision/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,14 @@ inline void TMouse::registerHandler( unsigned mask, void (_FAR *func)() )

struct CharScanType
{
#ifndef TV_BIG_ENDIAN
uchar charCode;
uchar scanCode;
#else
// big endian version reverses the order
uchar scanCode;
uchar charCode;
#endif
};

struct KeyDownEvent
Expand Down
17 changes: 17 additions & 0 deletions include/tvision/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,21 @@ char *ultoa( ulong value, char *buffer, int radix ) noexcept;

#endif // __BORLANDC__

#ifdef TV_BIG_ENDIAN
inline void *be_tvintmemcpy(void *dest, const void *src, size_t n) // implementation of tvintmemcpy for Big Endian platforms, reverses bytes while copying
{
// TVision assumes Little Endian byte order for some operations where uints are assigned to stucts etc.
// This memcpy-like function reverses the order of the bytes when copying them, so can be used on big-endian
// platforms in place of a standard memcpy.
for (size_t i=0; i<n; i++) {
((uchar*)dest)[i] = ((const uchar*)src)[n-i-1];
}
return dest;
}
#define tvintmemcpy be_tvintmemcpy
#else
// On little-endian platforms, just use memcpy as before
#define tvintmemcpy memcpy
#endif

#endif // __UTIL_H
2 changes: 1 addition & 1 deletion source/platform/ansidisp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ struct alignas(8) colorconv_r
colorconv_r(TermColor aColor, TColorAttr::Style aExtraFlags=0) noexcept
{
uint64_t val = aColor | (uint64_t(aExtraFlags) << 32);
memcpy(this, &val, 8);
tvintmemcpy(this, &val, 8);
static_assert(sizeof(*this) == 8, "");
}
};
Expand Down