Skip to content

Commit

Permalink
Add big endian support
Browse files Browse the repository at this point in the history
Co-authored-by: MookThompson <[email protected]>
  • Loading branch information
magiblot and MookThompson committed Jan 18, 2024
1 parent bbea05c commit 2290f29
Show file tree
Hide file tree
Showing 22 changed files with 231 additions and 39 deletions.
38 changes: 29 additions & 9 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ name: Build

on: [push, pull_request]

env:
BUILD_TYPE: Release

jobs:
build-linux-gcc:
name: Linux (GCC) (Unity)
Expand All @@ -13,11 +10,11 @@ jobs:
- uses: actions/checkout@v3

- name: Install Dependencies
run: sudo apt -y install libncursesw5-dev libgpm-dev
run: sudo apt -y install libncursesw5-dev libgpm-dev libgtest-dev

- name: Configure CMake
shell: bash
run: cmake . -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DTV_REDUCE_APP_SIZE=ON -DTV_LIBRARY_UNITY_BUILD=ON
run: cmake . -DCMAKE_BUILD_TYPE=Release -DTV_BUILD_TESTS=ON -DTV_REDUCE_APP_SIZE=ON -DTV_LIBRARY_UNITY_BUILD=ON

- name: Build
shell: bash
Expand All @@ -42,7 +39,7 @@ jobs:
env:
CC: gcc-5
CXX: g++-5
run: cmake . -DCMAKE_BUILD_TYPE=$BUILD_TYPE
run: cmake . -DCMAKE_BUILD_TYPE=Release

- name: Build
shell: bash
Expand All @@ -62,12 +59,35 @@ jobs:
env:
CC: clang
CXX: clang++
run: cmake . -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DTV_OPTIMIZE_BUILD=OFF
run: cmake . -DCMAKE_BUILD_TYPE=Release -DTV_OPTIMIZE_BUILD=OFF

- name: Build
shell: bash
run: cmake --build . -j$(nproc)

build-linux-big-endian:
name: Linux (GCC) (Big Endian)
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3

- name: Build in container
uses: uraimo/run-on-arch-action@v2
with:
arch: s390x
distro: alpine_latest
githubToken: ${{ github.token }}
dockerRunArgs: |
--volume "${PWD}:/app"
env: |
LC_CTYPE: C.UTF-8
shell: /bin/sh
install: apk update && apk add make cmake g++ ncurses-dev gtest-dev linux-headers
run: |
cd /app
cmake . -DCMAKE_BUILD_TYPE= -DTV_BUILD_USING_GPM=OFF -DTV_BUILD_EXAMPLES=OFF -DTV_BUILD_TESTS=ON -DTV_LIBRARY_UNITY_BUILD=ON
cmake --build . -j$(nproc)
build-windows-msvc32:
name: Windows (MSVC) (Win32)
runs-on: windows-latest
Expand Down Expand Up @@ -160,7 +180,7 @@ jobs:

- name: Configure CMake
shell: bash
run: cmake . -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_FLAGS="-static" -DTV_OPTIMIZE_BUILD=OFF
run: cmake . -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-static"

- name: Build
shell: bash
Expand Down Expand Up @@ -211,7 +231,7 @@ jobs:

- name: Configure CMake
shell: bash
run: cmake . -DCMAKE_BUILD_TYPE=$BUILD_TYPE
run: cmake . -DCMAKE_BUILD_TYPE=Release

- name: Build
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion examples/tvdemo/ascii.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ void TReport::handleEvent(TEvent& event)
{
if (event.message.command == cmAsciiTableCmdBase + cmCharFocused)
{
asciiChar = event.message.infoByte;
asciiChar = (uchar)(size_t)event.message.infoPtr;
drawView();
}
}
Expand Down
6 changes: 4 additions & 2 deletions examples/tvdemo/tvdemo3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ void TVDemo::mouse()

if (mouseCage != 0)
{
int32_t mouseReverse = TEventQueue::mouseReverse;
mouseCage->helpCtx = hcOMMouseDBox;
mouseCage->setData(&(TEventQueue::mouseReverse));
mouseCage->setData(&mouseReverse);
if (deskTop->execView(mouseCage) != cmCancel)
mouseCage->getData(&(TEventQueue::mouseReverse));
mouseCage->getData(&mouseReverse);
TEventQueue::mouseReverse = mouseReverse;
}
destroy( mouseCage );

Expand Down
22 changes: 22 additions & 0 deletions include/tvision/colors.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,34 @@ inline TColorAttr reverseAttribute(TColorAttr attr)
struct TColorRGB
{
uint32_t
#ifndef TV_BIG_ENDIAN
b : 8,
g : 8,
r : 8,
_unused : 8;
#else
_unused : 8,
r : 8,
g : 8,
b : 8;
#endif

TV_TRIVIALLY_CONVERTIBLE(TColorRGB, uint32_t, 0xFFFFFF)
constexpr inline TColorRGB(uint8_t r, uint8_t g, uint8_t b);
};

constexpr inline TColorRGB::TColorRGB(uint8_t r, uint8_t g, uint8_t b) :
#ifndef TV_BIG_ENDIAN
b(b),
g(g),
r(r),
_unused(0)
#else
_unused(0),
r(r),
g(g),
b(b)
#endif
{
}

Expand All @@ -90,11 +104,19 @@ constexpr inline TColorRGB::TColorRGB(uint8_t r, uint8_t g, uint8_t b) :
struct TColorBIOS
{
uint8_t
#ifndef TV_BIG_ENDIAN
b : 1,
g : 1,
r : 1,
bright : 1,
_unused : 4;
#else
_unused : 4,
bright : 1,
r : 1,
g : 1,
b : 1;
#endif

TV_TRIVIALLY_CONVERTIBLE(TColorBIOS, uint8_t, 0xF)
};
Expand Down
7 changes: 7 additions & 0 deletions include/tvision/internal/ansidisp.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <tvision/tv.h>

#include <internal/termdisp.h>
#include <internal/endian.h>

namespace tvision
{
Expand All @@ -30,6 +31,9 @@ struct TermColor

TermColor& operator=(uint32_t val) noexcept
{
#ifdef TV_BIG_ENDIAN
reverseBytes(val);
#endif
memcpy(this, &val, sizeof(*this));
return *this;
static_assert(sizeof(*this) == 4, "");
Expand All @@ -38,6 +42,9 @@ struct TermColor
{
uint32_t val;
memcpy(&val, this, sizeof(*this));
#ifdef TV_BIG_ENDIAN
reverseBytes(val);
#endif
return val;
}
TermColor(uint8_t aIdx, TermColorTypes aType) noexcept
Expand Down
29 changes: 29 additions & 0 deletions include/tvision/internal/endian.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef TVISION_ENDIAN_H
#define TVISION_ENDIAN_H

#include <stdint.h>

namespace tvision
{

inline void reverseBytes(uint16_t &val)
{
val = (val << 8) | (val >> 8);
}

inline void reverseBytes(uint32_t &val)
{
val = ((val << 8) & 0xFF00FF00U) | ((val >> 8) & 0x00FF00FF);
val = (val << 16) | (val >> 16);
}

inline void reverseBytes(uint64_t &val)
{
val = ((val << 8) & 0xFF00FF00FF00FF00ULL) | ((val >> 8) & 0x00FF00FF00FF00FFULL);
val = ((val << 16) & 0xFFFF0000FFFF0000ULL) | ((val >> 16) & 0x0000FFFF0000FFFFULL);
val = (val << 32) | (val >> 32);
}

} // namespace tvision

#endif // TVISION_ENDIAN_H
16 changes: 7 additions & 9 deletions include/tvision/internal/strings.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
#ifndef TVISION_STRINGS_H
#define TVISION_STRINGS_H

#ifndef _TV_VERSION
#include <tvision/tv.h>
#endif

namespace tvision
{

template<class Int>
inline constexpr Int string_as_int(TStringView s) noexcept
// CAUTION: It is not endian-safe to reinterpret the result as an array of bytes.
{
Int res = 0;
for (size_t i = 0; i < min(s.size(), sizeof(res)); ++i)
// CAUTION: Assumes Little Endian.
res |= uint64_t(uint8_t(s[i])) << 8*i;
return res;
}
Expand All @@ -32,15 +30,15 @@ struct alignas(4) btoa_lut_elem_t
using btoa_lut_t = constarray<btoa_lut_elem_t, 256>;

inline char *fast_btoa(uint8_t value, char *buffer) noexcept
// Pre: the capacity of 'buffer' is at least 4 bytes.
{
extern const btoa_lut_t btoa_lut;
const auto &lut = (btoa_lut_elem_t (&) [256]) btoa_lut;
// 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);
// Optimization: read and write the whole LUT entry at once in order to
// minimize memory accesses. We can afford to write more bytes into 'buffer'
// than digits.
memcpy(buffer, &lut[value], 4);
return buffer + (uint8_t) buffer[3];
static_assert(sizeof(btoa_lut_elem_t) == 4, "");
}

Expand Down
7 changes: 6 additions & 1 deletion include/tvision/internal/utf8.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#ifndef TVISION_UTF8_H
#define TVISION_UTF8_H

#include <internal/strings.h>
#include <tvision/tv.h>

#include <internal/endian.h>

#include <stdint.h>
#include <string.h>
Expand Down Expand Up @@ -66,6 +68,9 @@ inline size_t utf32To8(uint32_t u32, char u8[4]) noexcept
(( u32 & 0b00111111) | 0b10000000) << 24;
length = 4;
}
#ifdef TV_BIG_ENDIAN
reverseBytes(asInt);
#endif
memcpy(u8, &asInt, 4);
return length;
}
Expand Down
5 changes: 3 additions & 2 deletions include/tvision/scrncell.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,14 @@ struct TCellChar

inline void TCellChar::moveChar(char ch)
{
moveInt((uchar) ch);
memset(this, 0, sizeof(*this));
_text[0] = ch;
}

inline void TCellChar::moveInt(uint32_t mbc, bool wide)
// Pre: 'mbc' is a bit-casted multibyte-encoded character.
{
memset(this, 0, sizeof(*this));
// CAUTION: Assumes Little Endian.
memcpy(_text, &mbc, sizeof(mbc));
_flags = -int(wide) & fWide;
}
Expand Down
5 changes: 5 additions & 0 deletions include/tvision/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,13 @@ inline void TMouse::registerHandler( unsigned mask, void (_FAR *func)() )

struct CharScanType
{
#if !defined( TV_BIG_ENDIAN )
uchar charCode;
uchar scanCode;
#else
uchar scanCode;
uchar charCode;
#endif
};

struct KeyDownEvent
Expand Down
12 changes: 12 additions & 0 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE
TVISION_NO_STL
)

include(TestBigEndian)

TEST_BIG_ENDIAN(IS_BIG_ENDIAN)

if (IS_BIG_ENDIAN)
tv_message(STATUS "Big endian system detected")
target_compile_definitions(${PROJECT_NAME} PUBLIC
TV_BIG_ENDIAN
)
endif()

# Dependencies

if (NOT WIN32)
Expand Down Expand Up @@ -172,6 +183,7 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.16.0" AND TV_OPTIMIZE_BUILD)
file(GLOB_RECURSE TVSOURCE_NOUNITY "${CMAKE_CURRENT_LIST_DIR}/tvision/s*.cpp")
list(APPEND TVSOURCE_NOUNITY "${CMAKE_CURRENT_LIST_DIR}/tvision/new.cpp")
list(REMOVE_ITEM TVSOURCE_NOUNITY
"${CMAKE_CURRENT_LIST_DIR}/tvision/snprintf.cpp"
"${CMAKE_CURRENT_LIST_DIR}/tvision/stddlg.cpp"
"${CMAKE_CURRENT_LIST_DIR}/tvision/strmstat.cpp"
"${CMAKE_CURRENT_LIST_DIR}/tvision/syserr.cpp"
Expand Down
6 changes: 5 additions & 1 deletion source/platform/ansidisp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,13 @@ struct alignas(8) colorconv_r
uint8_t unused[2];

colorconv_r() = default;
colorconv_r(TermColor aColor, TColorAttr::Style aExtraFlags=0) noexcept
colorconv_r(TermColor aColor, TColorAttr::Style aExtraFlags = 0) noexcept
{
// Optimization: do bit-casting manually, just like with TermColor.
uint64_t val = aColor | (uint64_t(aExtraFlags) << 32);
#ifdef TV_BIG_ENDIAN
reverseBytes(val);
#endif
memcpy(this, &val, 8);
static_assert(sizeof(*this) == 8, "");
}
Expand Down
2 changes: 1 addition & 1 deletion source/platform/buffdisp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ inline void FlushScreenAlgorithm::writeCell() noexcept
inline void FlushScreenAlgorithm::writeSpace() noexcept
{
TCellChar ch;
ch.moveInt(' ');
ch.moveChar(' ');
writeCell(ch, cell->attr, 0);
}

Expand Down
Loading

0 comments on commit 2290f29

Please sign in to comment.