From 2e9643e3422a4967a77f8f66d1c62386745e8ac7 Mon Sep 17 00:00:00 2001 From: Ash Date: Wed, 18 Jul 2018 21:26:39 +1000 Subject: [PATCH 1/3] include/coreinit/cache: Document Cache function group --- include/coreinit/cache.h | 143 ++++++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 16 deletions(-) diff --git a/include/coreinit/cache.h b/include/coreinit/cache.h index 296bc44..f20a9ed 100644 --- a/include/coreinit/cache.h +++ b/include/coreinit/cache.h @@ -5,7 +5,19 @@ * \defgroup coreinit_cache Cache * \ingroup coreinit * - * Cache synchronisation functions. + * The Cache group of functions provide an interface to the low-level caching + * system of the PowerPC processor. The cache acts as a middleman between main + * memory and the processor, speeding up access to frequently-used data. + * + * However, the Wii U is not cache-coherent - written data may be cached + * without updating main memory, and data read from the cache may be out of date + * with respect to memory. While this isn't a problem for most code, certain + * hardware accesses may require manual synchronisation of the cache. This is + * achieved with coreinit's Cache group of functions. + * + * Since the PowerPC has a seperate cache for data and instructions, any data + * written with the intent of executing it as instructions requires manual + * flushing and invalidation of the data and instruction caches. * @{ */ @@ -13,45 +25,104 @@ extern "C" { #endif - /** - * Equivalent to dcbi instruction. + * Invalidates a range of cached data, in blocks. Equivalent to a loop of + * PowerPC \c dcbi instructions. + * + * This function forces the next reads from the given address to bypass the + * the cache and go straight to memory, resulting in slower reads that are + * guaranteed to reflect main memory. + * + * \param addr + * The effective address of the data to invalidate. + * + * \param size + * The size of the range to invalidate. Will be rounded up to the next 0x20. + * + * \note + * Unnecessary use of caching functions can have an adverse performance impact. + * They should only be used when needed while interfacing with hardware. */ void DCInvalidateRange(void *addr, uint32_t size); - /** - * Equivalent to dcbf, sync, eieio. + * Flushes a range of cached data, in blocks. Equivalent to a loop of PowerPC + * \c dcbf instructions, followed by a \c sync and \c eieio. + * + * This function flushes any recently cached data into main memory. + * This allows other hardware in the console to read the data without worry + * of main memory being outdated. It will also invalidate cached data. + * + * \param addr + * The effective address of the data to flush. + * + * \param size + * The size of the range to flush. Will be rounded up to the next 0x20. + * + * \note + * Unnecessary use of caching functions can have an adverse performance impact. + * They should only be used when needed while interfacing with hardware. */ void DCFlushRange(void *addr, uint32_t size); - /** - * Equivalent to dcbst, sync, eieio. + * Stores a range of cached data, in blocks. Equivalent to a loop of PowerPC + * \c dcbst instructions, followed by a \c sync and \c eieio. + * + * This function writes any recently cached data into main memory. + * This allows other hardware in the console to read the data without worry + * of main memory being outdated. This function does not invalidate + * the cached data. + * + * \param addr + * The effective address of the data to store. + * + * \param size + * The size of the range to store. Will be rounded up to the next 0x20. + * + * \note + * Unnecessary use of caching functions can have an adverse performance impact. + * They should only be used when needed while interfacing with hardware. */ void DCStoreRange(void *addr, uint32_t size); - /** - * Equivalent to dcbf. + * Similar to \link DCFlushRange \endlink, though this function will + * not run PowerPC \c sync and \c eieio instructions after flushing. * - * Does not perform sync, eieio like DCFlushRange. + * \param addr + * The effective address of the data to flush. + * + * \param size + * The size of the range to flush. Will be rounded up to the next 0x20. + * + * \note + * Unnecessary use of caching functions can have an adverse performance impact. + * They should only be used when needed while interfacing with hardware. */ void DCFlushRangeNoSync(void *addr, uint32_t size); - /** - * Equivalent to dcbst. + * Similar to \link DCStoreRange \endlink, though this function will + * not run PowerPC \c sync and \c eieio instructions after storing. * - * Does not perform sync, eieio like DCStoreRange. + * \param addr + * The effective address of the data to store. + * + * \param size + * The size of the range to store. Will be rounded up to the next 0x20. + * + * \note + * Unnecessary use of caching functions can have an adverse performance impact. + * They should only be used when needed while interfacing with hardware. */ void DCStoreRangeNoSync(void *addr, @@ -59,7 +130,22 @@ DCStoreRangeNoSync(void *addr, /** - * Equivalent to dcbz instruction. + * Zeroes the given area of the data cache (to the nearest block) with a loop of + * PowerPC \c dcbz instructions. + * This will not affect main memory immediately, though it will eventually + * trickle down. Can be combined with \link DCFlushRange \endlink or + * \link DCStoreRange \endlink to efficiently set memory to 0. + * + * \warning + * The size of the range passed into this function will be internally rounded up + * to the next multiple of 0x20. Failing to account for this could result in + * delayed, hard-to-diagnose memory corruption. + * + * \param addr + * The effective address of the data to zero. + * + * \param size + * The size of the range to zero. Will be rounded up to the next 0x20. */ void DCZeroRange(void *addr, @@ -67,7 +153,17 @@ DCZeroRange(void *addr, /** - * Equivalent to dcbt instruction. + * Gives the processor a hint that the given range of memory is likely to be + * accessed soon, and that performance would be improved if it were cached. + * The processor does not have to cache the requested area, but it may do so in + * response to this function. This function is equvalent to a loop of PowerPC + * \c dcbt instructions. + * + * \param addr + * The effective address of the data to cache. + * + * \param size + * The size of the range to cache. Will be rounded up to the next 0x20. */ void DCTouchRange(void *addr, @@ -75,7 +171,22 @@ DCTouchRange(void *addr, /** - * Equivalent to icbi instruction. + * Invalidates a range of cached instructions, in blocks. Equivalent to a loop + * of PowerPC \c icbi instructions. + * + * This function forces the next instruction fetches from the given address to + * bypass the the cache and go straight to memory, resulting in slower fetches + * that are guaranteed to reflect main memory. + * + * \param addr + * The effective address of the instructions to invalidate. + * + * \param size + * The size of the range to invalidate. Will be rounded up to the next 0x20. + * + * \note + * Unnecessary use of caching functions can have an adverse performance impact. + * They should only be used when needed while interfacing with hardware. */ void ICInvalidateRange(void *addr, From 9db62789153b61521d6e0c37671f02d8f986f587 Mon Sep 17 00:00:00 2001 From: Ash Date: Wed, 18 Jul 2018 21:33:50 +1000 Subject: [PATCH 2/3] include/coreinit/core.h: Add Doxygen docs for Core group. --- include/coreinit/core.h | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/include/coreinit/core.h b/include/coreinit/core.h index 2298a7e..a34e677 100644 --- a/include/coreinit/core.h +++ b/include/coreinit/core.h @@ -4,6 +4,9 @@ /** * \defgroup coreinit_core Core * \ingroup coreinit + * + * The coreinit Core group of functions provide information about each core of + * the system's processor. * @{ */ @@ -13,28 +16,44 @@ extern "C" { /** - * Returns the number of cores, should always be 3. + * Gets the number of cores in the system. On a retail Wii U, this is always 3. + * + * \returns + * The core count of the system. */ uint32_t OSGetCoreCount(); /** - * Returns the ID of the core currently executing this thread. + * Gets the core executing the current thread. + * + * \returns + * The ID of the current core. */ uint32_t OSGetCoreId(); /** - * Returns the ID of the main core. + * Gets the main core of the system. On a retail Wii U, this is always core 1. + * + * \returns + * The ID of the main core. */ uint32_t OSGetMainCoreId(); /** - * Returns true if the current core is the main core. + * Determines whether the current thread is running on the main core. + * On a retail Wii U, the main core is always core 1. + * + * \returns + * \c true if the current core is the main core. + * + * \sa + * */ BOOL OSIsMainCore(); From e32369dbba5c3ca383ac25bc19030e014599c3c0 Mon Sep 17 00:00:00 2001 From: Ash Date: Tue, 24 Jul 2018 22:04:20 +1000 Subject: [PATCH 3/3] include/coreinit/screen: Add Doxygen docs for OSScreen --- include/coreinit/screen.h | 172 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/include/coreinit/screen.h b/include/coreinit/screen.h index 515266e..421f3c1 100644 --- a/include/coreinit/screen.h +++ b/include/coreinit/screen.h @@ -4,6 +4,35 @@ /** * \defgroup coreinit_screen Screen * \ingroup coreinit + * + * + * Software-rendered graphics system, suitable for text output and simple + * graphics. + * + * OSScreen is much more straightforward than GX2, which makes it appealing for + * situations that do not require complex graphics. It can draw text and pixels + * (one at a time!) to both the Gamepad and TV. + * + * To use OSScreen, first call \link OSScreenInit \endlink. Then, allocate a + * memory area and pass it to OSScreen with \link OSScreenSetBufferEx \endlink - + * after enabling the screens with \link OSScreenEnableEx \endlink, the library + * will be ready to draw! Drawing is accomplished with \link + * OSScreenClearBufferEx \endlink, \link OSScreenPutFontEx \endlink and \link + * OSScreenPutPixelEx \endlink. Once drawing is complete, call \link + * OSScreenFlipBuffersEx \endlink to show the results on-screen. Rinse and + * repeat! + * + * * @{ */ @@ -11,44 +40,187 @@ extern "C" { #endif +//! Defines the ID of a display usable with OSScreen. typedef enum OSScreenID { + //! Represents the TV connected to the system. SCREEN_TV = 0, + //! Represents the screen in the DRC (gamepad). SCREEN_DRC = 1, } OSScreenID; +/** + * Initialises the OSScreen library for use. This function must be called before + * using any other OSScreen functions. + * + * \sa
    + *
  • \link OSScreenSetBufferEx \endlink
  • + *
  • \link OSScreenEnableEx \endlink
  • + *
  • \link OSScreenShutdown \endlink
  • + *
+ */ void OSScreenInit(); +/** + * Cleans up and shuts down the OSScreen library. + * + * \sa
    + *
  • \link OSScreenEnableEx \endlink
  • + *
+ */ void OSScreenShutdown(); +/** + * Gets the amount of memory required to fit both buffers of a given screen. + * + * \param screen + * The ID of the screen to be sized. + * + * \sa
    + *
  • \link OSScreenSetBufferEx \endlink
  • + *
+ */ uint32_t OSScreenGetBufferSizeEx(OSScreenID screen); +/** + * Sets the memory location for both buffers of a given screen. This location + * must be of the size prescribed by \link OSScreenGetBufferSizeEx \endlink and + * at an address aligned to 0x100 bytes. + * + * \param screen + * The ID of the screen whose memory location should be changed. + * + * \param addr + * Pointer to the memory to use. This area must be 0x100 aligned, and of the + * size given by \link OSScreenGetBufferSizeEx \endlink. + * + * \sa
    + *
  • \link OSScreenGetBufferSizeEx \endlink
  • + *
+ */ void OSScreenSetBufferEx(OSScreenID screen, void *addr); +/** + * Clear the work buffer of the given screen by setting all of its pixels to + * a given colour. + * + * \param screen + * The ID of the screen to clear. Only the work buffer will be cleared. + * + * \param colour + * The colour to use, in big-endian RGBX8 format - 0xRRGGBBXX, where X bits are + * ignored. + * + * \note + * Since this function only affects the work buffer, its effect will + * not appear on screen immediately. See \link OSScreenFlipBuffersEx \endlink. + * + * \sa
    + *
  • \link OSScreenPutFontEx \endlink
  • + *
  • \link OSScreenPutPixelEx \endlink
  • + *
+ * + * + */ void OSScreenClearBufferEx(OSScreenID screen, uint32_t colour); +/** + * Swap the buffers of the given screen. The work buffer will become the visible + * buffer and will start being shown on-screen, while the visible buffer becomes + * the new work buffer. This operation is known as "flipping" the buffers. + * + * You must call this function once drawing is complete, otherwise draws will + * not appear on-screen. + * + * \param screen + * The ID of the screen to flip. + */ void OSScreenFlipBuffersEx(OSScreenID screen); +/** + * Draws text at the given position. The text will be drawn to the work + * buffer with a built-in monospace font, coloured white, and anti-aliased. + * The position coordinates are in characters, not pixels. + * + * \param screen + * The ID of the screen to draw to. Only the work buffer will be affected. + * + * \param row + * The row, in characters, to place the text in. 0 corresponds to the top of + * the screen. + * + * \param column + * The column, in characters, to place the text at. 0 corresponds to the left of + * the screen. + * + * \param buffer + * Pointer to the string of text to draw. Null-terminated. + * + * \note + * Since this function only affects the work buffer, its effect will + * not appear on screen immediately. See \link OSScreenFlipBuffersEx \endlink. + * + * \sa
    + *
  • \link OSScreenPutPixelEx \endlink
  • + *
  • \link OSScreenClearBufferEx \endlink
  • + *
+ */ void OSScreenPutFontEx(OSScreenID screen, uint32_t row, uint32_t column, const char *buffer); +/** + * Draws a single pixel at the given position. The pixel, a 32-bit RGBX + * colour, will be placed in the work buffer at the coordinates given. + * + * \param screen + * The ID of the screen to place the pixel in. + * + * \param x + * The x-coordinate, in pixels, to draw the pixel at. + * + * \param y + * The y-coordinate, in pixels, to draw the pixel at. + * + * \param colour + * The desired colour of the pixel to draw, in RGBX32 colour (0xRRGGBBXX, where + * the XX value is ignored). + * + * \note + * Since this function only affects the work buffer, its effect will + * not appear on screen immediately. See \link OSScreenFlipBuffersEx \endlink. + * + * \sa
    + *
  • \link OSScreenPutFontEx \endlink
  • + *
  • \link OSScreenClearBufferEx \endlink
  • + *
+ */ void OSScreenPutPixelEx(OSScreenID screen, uint32_t x, uint32_t y, uint32_t colour); +/** + * Enables or disables a given screen. If a screen is disabled, it shows black. + * + * \param screen + * The ID of the screen to enable or disable. + * + * \param enable + * \c true if the screen should be enabled, otherwise false. + */ void OSScreenEnableEx(OSScreenID screen, BOOL enable);