From b1b3d104f91c1c74147a36a86ea85190624d81f9 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 19 Jun 2020 23:31:07 +0100 Subject: [PATCH 01/37] add displaytest initial checkin --- include/display.h | 26 ++- include/font.h | 254 ++++++++++++------------ src/display.c | 484 +++++++++++++++++++++++----------------------- src/graphics.c | 50 ++++- 4 files changed, 441 insertions(+), 373 deletions(-) diff --git a/include/display.h b/include/display.h index 41a6400f..cf704625 100644 --- a/include/display.h +++ b/include/display.h @@ -13,6 +13,19 @@ * @{ */ +/** + * @brief Valid television types + */ +typedef enum +{ + /** @brief PAL */ + TV_TYPE_PAL, + /** @brief NTSC */ + TV_TYPE_NTSC, + /** @brief MPAL */ + TV_TYPE_MPAL +} tvtype_t; + /** * @brief Valid video resolutions */ @@ -38,7 +51,9 @@ typedef enum /** @brief 16 bits per pixel (5-5-5-1) */ DEPTH_16_BPP, /** @brief 32 bits per pixel (8-8-8-8) */ - DEPTH_32_BPP + DEPTH_32_BPP, + /** @brief 16 bits per pixel (5-5-5-1) with HW Dither */ + DEPTH_16_BPP_DITHER } bitdepth_t; /** @brief Valid gamma correction settings */ @@ -62,7 +77,13 @@ typedef enum /** @brief Anti-aliasing and resampling with fetch-on-need */ ANTIALIAS_RESAMPLE_FETCH_NEEDED, /** @brief Anti-aliasing and resampling with fetch-always */ - ANTIALIAS_RESAMPLE_FETCH_ALWAYS + ANTIALIAS_RESAMPLE_FETCH_ALWAYS, + /** @brief Resampling anti-aliasing Divot off */ + ANTIALIAS_RESAMPLE_NODIVOT, + /** @brief Anti-aliasing and resampling with fetch-on-need Divot off */ + ANTIALIAS_RESAMPLE_FETCH_NEEDED_NODIVOT, + /** @brief Anti-aliasing and resampling with fetch-always Divot off */ + ANTIALIAS_RESAMPLE_FETCH_ALWAYS_NODIVOT } antialias_t; /** @brief Display context */ @@ -73,6 +94,7 @@ extern "C" { #endif void display_init( resolution_t res, bitdepth_t bit, uint32_t num_buffers, gamma_t gamma, antialias_t aa ); +void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t num_buffers, gamma_t gamma, antialias_t aa ); display_context_t display_lock(); void display_show(display_context_t disp); void display_close(); diff --git a/include/font.h b/include/font.h index 355e5fb4..c5adfc61 100644 --- a/include/font.h +++ b/include/font.h @@ -11,133 +11,133 @@ * @ingroup graphics */ static unsigned char const __font_data[2048] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, - 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C, - 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, - 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, - 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, - 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, - 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, - 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, - 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, - 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, - 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, - 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, - 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, - 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, - 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, - 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, - 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, - 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, - 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, - 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, - 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, - 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, - 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00, - 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, - 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, - 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, - 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, - 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00, - 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, - 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, - 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, - 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, - 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, - 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, - 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, - 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, - 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, - 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00, - 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, - 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, - 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, - 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, - 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, - 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, - 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, - 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, - 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, - 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, - 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, - 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, - 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, - 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, - 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, - 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, - 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, - 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, - 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30, - 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, - 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00, 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, - 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, - 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, - 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, - 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, - 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, - 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, - 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, - 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, - 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, - 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, - 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, - 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, - 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, - 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, - 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, - 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, - 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, - 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, + 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C, + 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, + 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, + 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, + 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, + 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7C, 0x28, 0x7C, 0x28, 0x00, 0x00, + 0x00, 0x38, 0x50, 0x38, 0x14, 0x38, 0x00, 0x00, 0x20, 0x24, 0x08, 0x10, 0x24, 0x04, 0x00, 0x00, + 0x00, 0x10, 0x28, 0x10, 0x28, 0x14, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, + 0x00, 0x28, 0x10, 0x38, 0x10, 0x28, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, + 0x08, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00, + 0x18, 0x24, 0x04, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x3C, 0x04, 0x18, 0x04, 0x24, 0x18, 0x00, 0x00, + 0x08, 0x18, 0x28, 0x3C, 0x08, 0x08, 0x00, 0x00, 0x3C, 0x20, 0x38, 0x04, 0x24, 0x18, 0x00, 0x00, + 0x18, 0x20, 0x38, 0x24, 0x24, 0x18, 0x00, 0x00, 0x3C, 0x04, 0x08, 0x08, 0x10, 0x10, 0x00, 0x00, + 0x18, 0x24, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x18, 0x24, 0x24, 0x1C, 0x04, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x10, 0x20, 0x00, + 0x00, 0x04, 0x08, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x08, 0x04, 0x08, 0x10, 0x00, 0x00, 0x08, 0x14, 0x04, 0x08, 0x00, 0x08, 0x00, 0x00, + 0x30, 0x48, 0x58, 0x58, 0x40, 0x30, 0x00, 0x00, 0x30, 0x48, 0x48, 0x78, 0x48, 0x48, 0x00, 0x00, + 0x70, 0x48, 0x70, 0x48, 0x48, 0x70, 0x00, 0x00, 0x30, 0x48, 0x40, 0x40, 0x48, 0x30, 0x00, 0x00, + 0x70, 0x48, 0x48, 0x48, 0x48, 0x70, 0x00, 0x00, 0x78, 0x40, 0x70, 0x40, 0x40, 0x78, 0x00, 0x00, + 0x78, 0x40, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00, 0x30, 0x48, 0x40, 0x58, 0x48, 0x38, 0x00, 0x00, + 0x48, 0x48, 0x78, 0x48, 0x48, 0x48, 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x48, 0x30, 0x00, 0x00, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x00, 0x00, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00, 0x00, 0x48, 0x78, 0x78, 0x48, 0x48, 0x48, 0x00, 0x00, + 0x48, 0x68, 0x68, 0x58, 0x58, 0x48, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, + 0x70, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x68, 0x30, 0x08, 0x00, + 0x70, 0x48, 0x48, 0x70, 0x50, 0x48, 0x00, 0x00, 0x30, 0x48, 0x20, 0x10, 0x48, 0x30, 0x00, 0x00, + 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x48, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, + 0x48, 0x48, 0x48, 0x48, 0x30, 0x30, 0x00, 0x00, 0x48, 0x48, 0x48, 0x78, 0x78, 0x48, 0x00, 0x00, + 0x48, 0x48, 0x30, 0x30, 0x48, 0x48, 0x00, 0x00, 0x28, 0x28, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00, + 0x78, 0x08, 0x10, 0x20, 0x40, 0x78, 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, + 0x00, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, + 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x2C, 0x14, 0x00, 0x00, + 0x20, 0x20, 0x38, 0x24, 0x24, 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, 0x18, 0x00, 0x00, + 0x04, 0x04, 0x1C, 0x24, 0x24, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2C, 0x30, 0x18, 0x00, 0x00, + 0x08, 0x14, 0x10, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x18, 0x20, 0x1C, 0x00, + 0x20, 0x20, 0x38, 0x24, 0x24, 0x24, 0x00, 0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x1C, 0x00, 0x00, + 0x04, 0x00, 0x04, 0x04, 0x04, 0x14, 0x08, 0x00, 0x20, 0x20, 0x28, 0x30, 0x28, 0x24, 0x00, 0x00, + 0x18, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x3C, 0x24, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x24, 0x24, 0x38, 0x20, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x24, 0x1C, 0x04, 0x00, + 0x00, 0x00, 0x38, 0x24, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x30, 0x0C, 0x38, 0x00, 0x00, + 0x10, 0x10, 0x38, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x1C, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x18, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x14, 0x08, 0x10, 0x00, + 0x00, 0x00, 0x3C, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x04, 0x08, 0x18, 0x08, 0x08, 0x04, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x10, 0x08, 0x0C, 0x08, 0x08, 0x10, 0x00, 0x00, + 0x14, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x99, 0xA1, 0xA1, 0x99, 0x42, 0x3C, + 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, + 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, + 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, + 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, + 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, + 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30, + 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, + 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00, 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, + 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, + 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, + 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, + 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, + 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, + 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, + 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, + 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, + 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, + 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/src/display.c b/src/display.c index 2da814b6..d12a1dbc 100644 --- a/src/display.c +++ b/src/display.c @@ -28,8 +28,8 @@ * has been set, a display context can be requested from the display subsystem using * #display_lock. To draw to the acquired display context, code should use functions * present in the @ref graphics and the @ref rdp modules. Once drawing to a display - * context is complete, the rendered graphic can be displayed to the screen using - * #display_show. Once code has finished rendering all graphics, #display_close can + * context is complete, the rendered graphic can be displayed to the screen using + * #display_show. Once code has finished rendering all graphics, #display_close can * be used to shut down the display subsystem. * * @{ @@ -46,132 +46,27 @@ /** @brief Memory location to read which determines the TV type. */ #define TV_TYPE_LOC 0x80000300 -/** +/** * @brief Return the uncached memory address of a cached address * - * @param[in] x + * @param[in] x * The cached address - * + * * @return The uncached address */ #define UNCACHED_ADDR(x) ((void *)(((uint32_t)(x)) | 0xA0000000)) /** - * @brief Align a memory address to 64 byte offset - * + * @brief Align a memory address to 16 byte offset + * * @param[in] x * Unaligned memory address * * @return An aligned address guaranteed to be >= the unaligned address */ -#define ALIGN_64BYTE(x) ((void *)(((uint32_t)(x)+63) & 0xFFFFFFC0)) +#define ALIGN_16BYTE(x) ((void *)(((uint32_t)(x)+15) & 0xFFFFFFF0)) + -/** - * @name Video Mode Register Presets - * @brief Presets to use when setting a particular video mode - * @{ - */ -static const uint32_t ntsc_320[] = { - 0x00000000, 0x00000000, 0x00000140, 0x00000200, - 0x00000000, 0x03e52239, 0x0000020d, 0x00000c15, - 0x0c150c15, 0x006c02ec, 0x002501ff, 0x000e0204, - 0x00000200, 0x00000400 }; -static const uint32_t pal_320[] = { - 0x00000000, 0x00000000, 0x00000140, 0x00000200, - 0x00000000, 0x0404233a, 0x00000271, 0x00150c69, - 0x0c6f0c6e, 0x00800300, 0x005f0239, 0x0009026b, - 0x00000200, 0x00000400 }; -static const uint32_t mpal_320[] = { - 0x00000000, 0x00000000, 0x00000140, 0x00000200, - 0x00000000, 0x04651e39, 0x0000020d, 0x00040c11, - 0x0c190c1a, 0x006c02ec, 0x002501ff, 0x000e0204, - 0x00000200, 0x00000400 }; -static const uint32_t ntsc_640[] = { - 0x00000000, 0x00000000, 0x00000280, 0x00000200, - 0x00000000, 0x03e52239, 0x0000020c, 0x00000c15, - 0x0c150c15, 0x006c02ec, 0x002301fd, 0x000e0204, - 0x00000400, 0x02000800 }; -static const uint32_t pal_640[] = { - 0x00000000, 0x00000000, 0x00000280, 0x00000200, - 0x00000000, 0x0404233a, 0x00000270, 0x00150c69, - 0x0c6f0c6e, 0x00800300, 0x005d0237, 0x0009026b, - 0x00000400, 0x02000800 }; -static const uint32_t mpal_640[] = { - 0x00000000, 0x00000000, 0x00000280, 0x00000200, - 0x00000000, 0x04651e39, 0x0000020c, 0x00000c10, - 0x0c1c0c1c, 0x006c02ec, 0x002301fd, 0x000b0202, - 0x00000400, 0x02000800 }; -static const uint32_t ntsc_256[] = { - 0x00000000, 0x00000000, 0x00000100, 0x00000200, - 0x00000000, 0x03e52239, 0x0000020d, 0x00000c15, - 0x0c150c15, 0x006c02ec, 0x002501ff, 0x000e0204, - 0x0000019A, 0x00000400 }; -static const uint32_t pal_256[] = { - 0x00000000, 0x00000000, 0x00000100, 0x00000200, - 0x00000000, 0x0404233a, 0x00000271, 0x00150c69, - 0x0c6f0c6e, 0x00800300, 0x005f0239, 0x0009026b, - 0x0000019A, 0x00000400 }; -static const uint32_t mpal_256[] = { - 0x00000000, 0x00000000, 0x00000100, 0x00000200, - 0x00000000, 0x04651e39, 0x0000020d, 0x00040c11, - 0x0c190c1a, 0x006c02ec, 0x002501ff, 0x000e0204, - 0x0000019A, 0x00000400 }; -static const uint32_t ntsc_512[] = { - 0x00000000, 0x00000000, 0x00000200, 0x00000200, - 0x00000000, 0x03e52239, 0x0000020c, 0x00000c15, - 0x0c150c15, 0x006c02ec, 0x002301fd, 0x000e0204, - 0x00000334, 0x02000800 }; -static const uint32_t pal_512[] = { - 0x00000000, 0x00000000, 0x00000200, 0x00000200, - 0x00000000, 0x0404233a, 0x00000270, 0x00150c69, - 0x0c6f0c6e, 0x00800300, 0x005d0237, 0x0009026b, - 0x00000334, 0x02000800 }; -static const uint32_t mpal_512[] = { - 0x00000000, 0x00000000, 0x00000200, 0x00000200, - 0x00000000, 0x04651e39, 0x0000020c, 0x00000c10, - 0x0c1c0c1c, 0x006c02ec, 0x002301fd, 0x000b0202, - 0x00000334, 0x02000800 }; -static const uint32_t ntsc_512p[] = { - 0x00000000, 0x00000000, 0x00000200, 0x00000200, - 0x00000000, 0x03e52239, 0x0000020d, 0x00000c15, - 0x0c150c15, 0x006c02ec, 0x002501ff, 0x000e0204, - 0x00000333, 0x00000400 }; -static const uint32_t pal_512p[] = { - 0x00000000, 0x00000000, 0x00000200, 0x00000200, - 0x00000000, 0x0404233a, 0x00000271, 0x00150c69, - 0x0c6f0c6e, 0x00800300, 0x005f0239, 0x0009026b, - 0x00000333, 0x00000400 }; -static const uint32_t mpal_512p[] = { - 0x00000000, 0x00000000, 0x00000200, 0x00000200, - 0x00000000, 0x04651e39, 0x0000020d, 0x00040c11, - 0x0c190c1a, 0x006c02ec, 0x002501ff, 0x000e0204, - 0x00000333, 0x00000400 }; -static const uint32_t ntsc_640p[] = { - 0x00000000, 0x00000000, 0x00000280, 0x00000200, - 0x00000000, 0x03e52239, 0x0000020d, 0x00000c15, - 0x0c150c15, 0x006c02ec, 0x002501ff, 0x000e0204, - 0x00000400, 0x00000400 }; -static const uint32_t pal_640p[] = { - 0x00000000, 0x00000000, 0x00000280, 0x00000200, - 0x00000000, 0x0404233a, 0x00000271, 0x00150c69, - 0x0c6f0c6e, 0x00800300, 0x005f0239, 0x0009026b, - 0x00000400, 0x00000400 }; -static const uint32_t mpal_640p[] = { - 0x00000000, 0x00000000, 0x00000280, 0x00000200, - 0x00000000, 0x04651e39, 0x0000020d, 0x00040c11, - 0x0c190c1a, 0x006c02ec, 0x002501ff, 0x000e0204, - 0x00000400, 0x00000400 }; -/** @} */ - -/** @brief Register initial value array */ -static const uint32_t * const reg_values[] = { - pal_320, ntsc_320, mpal_320, - pal_640, ntsc_640, mpal_640, - pal_256, ntsc_256, mpal_256, - pal_512, ntsc_512, mpal_512, - pal_512p, ntsc_512p, mpal_512p, - pal_640p, ntsc_640p, mpal_640p, -}; /** @brief Video buffer pointers */ static void *buffer[NUM_BUFFERS]; /** @brief Currently active bit depth */ @@ -184,6 +79,8 @@ uint32_t __height; uint32_t __buffers = NUM_BUFFERS; /** @brief Pointer to uncached 16-bit aligned version of buffers */ void *__safe_buffer[NUM_BUFFERS]; +/** @brief Current VI register settings (for two fields) */ +uint32_t __registers[REGISTER_COUNT*2]; /** @brief Currently displayed buffer */ static int now_showing = -1; @@ -210,12 +107,15 @@ static void __write_registers( uint32_t const * const registers ) /* Just straight copy */ for( int i = 0; i < REGISTER_COUNT; i++ ) { + /* Don't set frame buffer base */ + if( i == 1 ) { continue; } /* Don't clear interrupts */ if( i == 3 ) { continue; } if( i == 4 ) { continue; } - reg_base[i] = registers[i]; + reg_base[i] = __registers[i]; MEMORY_BARRIER(); + //MEMORY_BARRIER(); //removed in latest download } } @@ -229,8 +129,19 @@ static void __write_dram_register( void const * const dram_val ) { uint32_t *reg_base = (uint32_t *)REGISTER_BASE; - reg_base[1] = (uint32_t)dram_val; - MEMORY_BARRIER(); + if ( reg_base[4] & 1 ) + { + /* field 2 */ + reg_base[1] = (uint32_t)dram_val + __registers[1 + REGISTER_COUNT]; + MEMORY_BARRIER(); + } + else + { + /* field 1 */ + reg_base[1] = (uint32_t)dram_val + __registers[1]; + MEMORY_BARRIER(); + } + //MEMORY_BARRIER(); // Removed in latest download } /** @@ -240,22 +151,40 @@ static void __write_dram_register( void const * const dram_val ) */ static void __display_callback() { - /* Only swap frames if we have a new frame to swap, otherwise just - leave up the current frame */ + uint32_t *reg_base = (uint32_t *)REGISTER_BASE; + + /* Only swap frames if we have a new frame to swap */ if(show_next >= 0 && show_next != now_drawing) { - __write_dram_register( __safe_buffer[show_next] ); - now_showing = show_next; show_next = -1; } + __write_dram_register( __safe_buffer[now_showing] ); /* call every time for field offset */ + + /* write field dependent values */ + if ( reg_base[4] & 1 ) + { + /* field 2 */ + reg_base[10] = __registers[10 + REGISTER_COUNT]; + MEMORY_BARRIER(); + reg_base[11] = __registers[11 + REGISTER_COUNT]; + MEMORY_BARRIER(); + } + else + { + /* field 1 */ + reg_base[10] = __registers[10]; + MEMORY_BARRIER(); + reg_base[11] = __registers[11]; + MEMORY_BARRIER(); + } } /** * @brief Initialize the display to a particular resolution and bit depth * * Initialize video system. This sets up a double or triple buffered drawing surface which can - * be blitted or rendered to using software or hardware. + * be blitted or rendered to using software or hardware. Uses the default tv type for region. * * @param[in] res * The requested resolution @@ -270,165 +199,238 @@ static void __display_callback() */ void display_init( resolution_t res, bitdepth_t bit, uint32_t num_buffers, gamma_t gamma, antialias_t aa ) { - uint32_t registers[REGISTER_COUNT]; - uint32_t tv_type = *((uint32_t *)TV_TYPE_LOC); - uint32_t control = 0x3000; + tvtype_t tv = (tvtype_t)*((uint32_t *)TV_TYPE_LOC); + display_init_ex( tv, res, bit, num_buffers, gamma, aa ); +} +/** + * @brief Initialize the display to a particular tv type, resolution, and bit depth + * + * Initialize video system. This sets up a double or triple buffered drawing surface which can + * be blitted or rendered to using software or hardware. + * + * @param[in] tv + * The requested tv type + * @param[in] res + * The requested resolution + * @param[in] bit + * The requested bit depth + * @param[in] num_buffers + * Number of buffers (2 or 3) + * @param[in] gamma + * The requested gamma setting + * @param[in] aa + * The requested anti-aliasing setting + */ +void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t num_buffers, gamma_t gamma, antialias_t aa ) +{ /* Can't have the video interrupt happening here */ disable_interrupts(); - /* Ensure that buffering is either double or twiple */ - if( num_buffers != 2 && num_buffers != 3 ) - { - __buffers = NUM_BUFFERS; - } - else - { - __buffers = num_buffers; - } - - switch( res ) - { - case RESOLUTION_640x480: - /* Serrate on to stop vertical jitter */ - control |= 0x40; - tv_type += 3; - break; - case RESOLUTION_256x240: - tv_type += 6; - break; - case RESOLUTION_512x480: - /* Serrate on to stop vertical jitter */ - control |= 0x40; - tv_type += 9; - break; - case RESOLUTION_512x240: - tv_type += 12; - break; - case RESOLUTION_640x240: - tv_type += 15; - break; - case RESOLUTION_320x240: - default: - break; - } - - /* Copy over to temporary for extra initializations */ - memcpy( registers, reg_values[tv_type], sizeof( uint32_t ) * REGISTER_COUNT ); - /* Figure out control register based on input given */ - switch( bit ) + __registers[0] = 0x3000; + /* Enable Dither�Filter */ + if(bit == DEPTH_16_BPP_DITHER) + { + __registers[0] |= 0x10000; + bit = DEPTH_16_BPP; + } + if ( bit == DEPTH_16_BPP ) + __registers[0] |= 0x0002; /* 16-bit color mode */ + else if ( bit == DEPTH_32_BPP ) + __registers[0] |= 0x0003; /* 32-bit color mode */ + if ( gamma == GAMMA_CORRECT ) + __registers[0] |= 0x0008; /* enable gamma correction */ + else if ( gamma == GAMMA_CORRECT_DITHER ) + __registers[0] |= 0x000C; /* enable gamma correction and dithering */ + if ( (res == RESOLUTION_640x480) || (res == RESOLUTION_512x480) ) + __registers[0] |= 0x0040; /* enable hsync serration for interlaced modes */ + if ( aa == ANTIALIAS_OFF ) + __registers[0] |= 0x0300; /* aa off */ + else if ( aa == ANTIALIAS_RESAMPLE ) + __registers[0] |= 0x0210; /* resample only, enable divot */ + else if ( aa == ANTIALIAS_RESAMPLE_FETCH_NEEDED ) + __registers[0] |= 0x0110; /* aa & resample (fetch lines as needed), enable divot */ + else if ( aa == ANTIALIAS_RESAMPLE_FETCH_ALWAYS ) + __registers[0] |= 0x0010; /* aa & resample (fetch lines always), enable divot */ + else if ( aa == ANTIALIAS_RESAMPLE_NODIVOT ) + __registers[0] |= 0x0200; /* resample only*/ + else if ( aa == ANTIALIAS_RESAMPLE_FETCH_NEEDED_NODIVOT ) + __registers[0] |= 0x0100; /* aa & resample (fetch lines as needed)*/ + + /* Figure out origin, width, and x-scale registers based on input given */ + switch ( res ) { - case DEPTH_16_BPP: - /* We enable divot filter in 16bpp mode to give our gradients - a slightly smoother look */ - control |= 0x10002; - break; - case DEPTH_32_BPP: - control |= 0x3; + case RESOLUTION_320x240: + __width = 320; + __height = 240; + __registers[1] = 320; /* base offset for field 1 */ + __registers[1 + REGISTER_COUNT] = 320; /* base offset for field 2 */ + __registers[2] = 320; /* width */ + __registers[12] = 0x00000200; /* x-scale */ break; - } - - switch( gamma ) - { - case GAMMA_NONE: - /* Nothing to set here */ + case RESOLUTION_640x480: + __width = 640; + __height = 480; + __registers[1] = 640; /* base offset for field 1 */ + __registers[1 + REGISTER_COUNT] = 1280; /* base offset for field 2 */ + __registers[2] = 640; /* width */ + __registers[12] = 0x00000400; /* x-scale */ break; - case GAMMA_CORRECT: - control |= 0x8; + case RESOLUTION_256x240: + __width = 256; + __height = 240; + __registers[1] = 256; /* base offset for field 1 */ + __registers[1 + REGISTER_COUNT] = 256; /* base offset for field 2 */ + __registers[2] = 256; /* width */ + __registers[12] = 0x0000019A; /* x-scale */ break; - case GAMMA_CORRECT_DITHER: - control |= 0xC; + case RESOLUTION_512x480: + __width = 512; + __height = 480; + __registers[1] = 512; /* base offset for field 1 */ + __registers[1 + REGISTER_COUNT] = 1024; /* base offset for field 2 */ + __registers[2] = 512; /* width */ + __registers[12] = 0x00000334; /* x-scale */ break; } + if ( bit == DEPTH_16_BPP ) + { + __registers[1] <<= 1; + __registers[1 + REGISTER_COUNT] <<= 1; + __bitdepth = 2; + } + else + { + __registers[1] <<= 2; + __registers[1 + REGISTER_COUNT] <<= 2; + __bitdepth = 4; + } - switch( aa ) + /* Interrupt on first line (2nd half-line) */ + __registers[3] = 2; + + /* Figure out burst, vsync, hsync, leap, hstart, vstart, + vburst, and y-scale registers based on input given */ + switch ( tv ) { - case ANTIALIAS_OFF: - /* Set AA off flag */ - control |= 0x300; - break; - case ANTIALIAS_RESAMPLE: - /* Set AA on resample as well as divot on */ - control |= 0x210; + case TV_TYPE_PAL: + __registers[5] = 0x0404233A; /* burst */ + __registers[7] = 0x00150C69; /* hsync */ + __registers[8] = 0x0C6F0C6E; /* leap */ + __registers[9] = 0x00800300; /* hstart */ + if ( (res == RESOLUTION_640x480) || (res == RESOLUTION_512x480) ) + { + /* hi-res interlaced display */ + __registers[6] = 0x270; /* vsync */ + __registers[10] = 0x005D0237; /* vstart for field 1 */ + __registers[10 + REGISTER_COUNT] = 0x005F0239; /* vstart for field 2 */ + __registers[11] = 0x0009026B; /* vburst for field 1 */ + __registers[11 + REGISTER_COUNT] = 0x000D0269; /* vburst for field 2 */ + __registers[13] = 0x02000800; /* y-scale */ + } + else + { + /* lo-res non-interlaced display */ + __registers[6] = 0x271; /* vsync */ + __registers[10] = 0x005F0239; /* vstart for field 1 */ + __registers[10 + REGISTER_COUNT] = 0x005F0239; /* vstart for field 2 */ + __registers[11] = 0x0009026B; /* vburst for field 1 */ + __registers[11 + REGISTER_COUNT] = 0x0009026B; /* vburst for field 2 */ + __registers[13] = 0x00000400; /* y-scale */ + } break; - case ANTIALIAS_RESAMPLE_FETCH_NEEDED: - /* Set AA on resample and fetch as well as divot on */ - control |= 0x110; + case TV_TYPE_NTSC: + __registers[5] = 0x03E52239; /* burst */ + __registers[7] = 0x00000C15; /* hsync */ + __registers[8] = 0x0C150C15; /* leap */ + __registers[9] = 0x006C02EC; /* hstart */ + if ( (res == RESOLUTION_640x480) || (res == RESOLUTION_512x480) ) + { + /* hi-res interlaced display */ + __registers[6] = 0x20C; /* vsync */ + __registers[10] = 0x002301FD; /* vstart for field 1 */ + __registers[10 + REGISTER_COUNT] = 0x002501FF; /* vstart for field 2 */ + __registers[11] = 0x000E0204; /* vburst for field 1 */ + __registers[11 + REGISTER_COUNT] = 0x000E0204; /* vburst for field 2 */ + __registers[13] = 0x02000800; /* y-scale */ + } + else + { + /* lo-res non-interlaced display */ + __registers[6] = 0x20C; /* vsync */ + __registers[10] = 0x002301FD; /* vstart for field 1 */ + __registers[10 + REGISTER_COUNT] = 0x002501FF; /* vstart for field 2 */ + __registers[11] = 0x000E0204; /* vburst for field 1 */ + __registers[11 + REGISTER_COUNT] = 0x000E0204; /* vburst for field 2 */ + __registers[13] = 0x0000400; /* y-scale */ + } break; - case ANTIALIAS_RESAMPLE_FETCH_ALWAYS: - /* Set AA on resample always and fetch as well as divot on */ - control |= 0x010; + case TV_TYPE_MPAL: + __registers[5] = 0x04651E39; /* burst */ + __registers[7] = 0x00040C11; /* hsync */ + __registers[8] = 0x0C190C1A; /* leap */ + __registers[9] = 0x006C02EC; /* hstart */ + if ( (res == RESOLUTION_640x480) || (res == RESOLUTION_512x480) ) + { + /* hi-res interlaced display */ + __registers[6] = 0x20C; /* vsync */ + __registers[10] = 0x002301FD; /* vstart for field 1 */ + __registers[10 + REGISTER_COUNT] = 0x002501FF; /* vstart for field 2 */ + __registers[11] = 0x000B0202; /* vburst for field 1 */ + __registers[11 + REGISTER_COUNT] = 0x000E0204; /* vburst for field 2 */ + __registers[13] = 0x02000800; /* y-scale */ + } + else + { + /* lo-res non-interlaced display */ + __registers[6] = 0x20D; /* vsync */ + __registers[10] = 0x002501FF; /* vstart for field 1 */ + __registers[10 + REGISTER_COUNT] = 0x002501FF; /* vstart for field 2 */ + __registers[11] = 0x000E0204; /* vburst for field 1 */ + __registers[11 + REGISTER_COUNT] = 0x000E0204; /* vburst for field 2 */ + __registers[13] = 0x00000400; /* y-scale */ + } break; } - /* Set the control register in our template */ - registers[0] = control; - - /* Black screen please, the clearing takes a couple frames, and - garbage would be visible. */ - registers[9] = 0; - /* Set up initial registers */ - __write_registers( registers ); + __write_registers( __registers ); - /* Set up the display */ - switch( res ) - { - case RESOLUTION_320x240: - __width = 320; - __height = 240; - break; - case RESOLUTION_640x480: - __width = 640; - __height = 480; - break; - case RESOLUTION_256x240: - __width = 256; - __height = 240; - break; - case RESOLUTION_512x480: - __width = 512; - __height = 480; - break; - case RESOLUTION_512x240: - __width = 512; - __height = 240; - break; - case RESOLUTION_640x240: - __width = 640; - __height = 240; - break; - } - __bitdepth = ( bit == DEPTH_16_BPP ) ? 2 : 4; + /* Ensure that buffering is either double or triple */ + if( num_buffers != 2 && num_buffers != 3 ) + { + __buffers = NUM_BUFFERS; + } + else + { + __buffers = num_buffers; + } /* Initialize buffers and set parameters */ for( int i = 0; i < __buffers; i++ ) { /* Set parameters necessary for drawing */ /* Grab a location to render to */ - buffer[i] = malloc( __width * __height * __bitdepth + 63 ); - __safe_buffer[i] = ALIGN_64BYTE( UNCACHED_ADDR( buffer[i] ) ); + buffer[i] = malloc( __width * __height * __bitdepth + 15 ); + __safe_buffer[i] = ALIGN_16BYTE( UNCACHED_ADDR( buffer[i] ) ); /* Baseline is blank */ memset( __safe_buffer[i], 0, __width * __height * __bitdepth ); } /* Set the first buffer as the displaying buffer */ + __write_dram_register( __safe_buffer[0] ); + now_showing = 0; now_drawing = -1; show_next = -1; - /* Show our screen normally */ - registers[1] = (uintptr_t) __safe_buffer[0]; - registers[9] = reg_values[tv_type][9]; - __write_registers( registers ); - enable_interrupts(); /* Set which line to call back on in order to flip screens */ register_VI_handler( __display_callback ); - set_VI_interrupt( 1, 0x200 ); + set_VI_interrupt( 1, 2 ); /* interrupt on line 1 (2nd half-line) */ } /** diff --git a/src/graphics.c b/src/graphics.c index 3f9295ee..1fc4de46 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -100,6 +100,10 @@ extern void *__safe_buffer[]; * This is white on 16 and 32 BPP modes */ static uint32_t f_color = 0xFFFFFFFF; + +static uint32_t old_f_color = 0xFFFFFFFF; + +static int highlight = 0; /** * @brief Generic background color * @@ -753,14 +757,54 @@ void graphics_draw_text( display_context_t disp, int x, int y, const char * cons ty += 8; break; case ' ': - tx += 8; + tx += 5; // My font break; case '\t': - tx += 8 * 5; + tx += 5 * 5; ; // My font break; + case '#': + highlight = !highlight; + + if(highlight) + { + old_f_color = f_color; + text++; + if(f_color != 0x00000000) + switch(*text) + { + case 'R': + f_color = graphics_make_color(0xff, 0x00, 0x00, 0xff); + break; + case 'G': + f_color = graphics_make_color(0x00, 0xff, 0x00, 0xff); + break; + case 'B': + f_color = graphics_make_color(0x00, 0x00, 0xff, 0xff); + break; + case 'Y': + f_color = graphics_make_color(0xff, 0xff, 0x00, 0xff); + break; + case 'C': + f_color = graphics_make_color(0x00, 0xff, 0xff, 0xff); + break; + case 'M': + f_color = graphics_make_color(0xff, 0xff, 0x00, 0xff); + break; + case 'W': + default: + f_color = graphics_make_color(0xff, 0xff, 0xff, 0xff); + break; + } + } + else + { + f_color = old_f_color; + text++; + } + break; default: graphics_draw_character( disp, tx, ty, *text ); - tx += 8; + tx += 5; ; // My font break; } From 3ee90102a8bd1d46fe36f3f458ec06e44c3bc8ea Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 19 Jun 2020 23:39:08 +0100 Subject: [PATCH 02/37] comment out unsupported res (for the moment) --- include/display.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/display.h b/include/display.h index cf704625..d7f919c6 100644 --- a/include/display.h +++ b/include/display.h @@ -40,9 +40,10 @@ typedef enum /** @brief 512x480 mode */ RESOLUTION_512x480, /** @brief 512x240 mode, high-res progressive */ - RESOLUTION_512x240, - /** @brief 640x240 mode, high-res progressive */ - RESOLUTION_640x240, + //TODO: add resolutions to demo!!! + // RESOLUTION_512x240, + // /** @brief 640x240 mode, high-res progressive */ + // RESOLUTION_640x240, } resolution_t; /** @brief Valid bit depths */ From 7820a323c24e2e6219d4c0a099e815a72547c3a1 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Sat, 20 Jun 2020 01:33:24 +0100 Subject: [PATCH 03/37] fix lost issues with mkdfs on windows --- tools/mkdfs/mkdfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mkdfs/mkdfs.c b/tools/mkdfs/mkdfs.c index f3d3c98b..21b6aab2 100644 --- a/tools/mkdfs/mkdfs.c +++ b/tools/mkdfs/mkdfs.c @@ -336,4 +336,4 @@ int main(int argc, char *argv[]) kill_fs(); return 0; -} +} \ No newline at end of file From ef4d14ecba7c70a31887495aeb59c56b55742a0e Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Mon, 22 Jun 2020 08:56:36 +0100 Subject: [PATCH 04/37] fix tools --- tools/mksprite/mksprite.c | 2 +- tools/n64tool.c | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/tools/mksprite/mksprite.c b/tools/mksprite/mksprite.c index b441a457..c42ffa3f 100644 --- a/tools/mksprite/mksprite.c +++ b/tools/mksprite/mksprite.c @@ -46,7 +46,7 @@ int read_png( char *png_file, char *spr_file, uint8_t depth, uint8_t hslices, ui png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; - uint8_t wval8; + int wval8; uint16_t wval16; FILE *fp; FILE *op; diff --git a/tools/n64tool.c b/tools/n64tool.c index 747119f8..8e040e35 100644 --- a/tools/n64tool.c +++ b/tools/n64tool.c @@ -166,15 +166,22 @@ int output_zeros(FILE *dest, int amount) return -1; } + if(amount <= 0) + { + /* We are done */ + return 0; + } + int i; - while (amount > 0) { - int sz = amount; - if (sz > sizeof(zero)) - sz = sizeof(zero); - fwrite(zero, 1, sz, dest); - amount -= sz; + + for(i = 0; i < (amount >> 2); i++) + { + /* Write out a word at a time */ + uint32_t byte = 0; + + fwrite(&byte, 1, 4, dest); } - + return 0; } @@ -345,7 +352,7 @@ int main(int argc, char *argv[]) if(output_zeros(write_file, num_zeros)) { - fprintf(stderr, "Invalid offset to seek to in %s!\n", output); + fprintf(stderr, "Invalid offset to seek to!\n"); return -1; } @@ -432,7 +439,7 @@ int main(int argc, char *argv[]) if(output_zeros(write_file, num_zeros)) { - fprintf(stderr, "Couldn't pad image in %s!\n", output); + fprintf(stderr, "Couldn't pad image!\n"); return -1; } From e780767c070a3d926f32cd7a8c2feaa54dbad558 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 23 Jun 2020 20:28:02 +0100 Subject: [PATCH 05/37] Add newest resolutions found in official version --- include/display.h | 7 +++---- src/display.c | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/display.h b/include/display.h index d7f919c6..1d331283 100644 --- a/include/display.h +++ b/include/display.h @@ -40,10 +40,9 @@ typedef enum /** @brief 512x480 mode */ RESOLUTION_512x480, /** @brief 512x240 mode, high-res progressive */ - //TODO: add resolutions to demo!!! - // RESOLUTION_512x240, - // /** @brief 640x240 mode, high-res progressive */ - // RESOLUTION_640x240, + RESOLUTION_512x240, + /** @brief 640x240 mode, high-res progressive */ + RESOLUTION_640x240 } resolution_t; /** @brief Valid bit depths */ diff --git a/src/display.c b/src/display.c index d12a1dbc..2c81f3f8 100644 --- a/src/display.c +++ b/src/display.c @@ -51,7 +51,7 @@ * * @param[in] x * The cached address - * + * * @return The uncached address */ #define UNCACHED_ADDR(x) ((void *)(((uint32_t)(x)) | 0xA0000000)) @@ -293,6 +293,22 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu __registers[2] = 512; /* width */ __registers[12] = 0x00000334; /* x-scale */ break; + case RESOLUTION_512x240: /* high-res progressive */ + __width = 512; + __height = 240; + __registers[1] = 512; /* base offset for field 1 */ + __registers[1 + REGISTER_COUNT] = 1024; /* base offset for field 2 */ //TODO: probably wrong + __registers[2] = 512; /* width */ + __registers[12] = 0x00000334; /* x-scale */ //TODO: probably wrong + break; + case RESOLUTION_640x240: /* high-res progressive */ + __width = 640; + __height = 240; + __registers[1] = 640; /* base offset for field 1 */ + __registers[1 + REGISTER_COUNT] = 1280; /* base offset for field 2 */ //TODO: probably wrong + __registers[2] = 640; /* width */ + __registers[12] = 0x00000400; /* x-scale */ //TODO: probably wrong + break; } if ( bit == DEPTH_16_BPP ) { From 7d3e459a5de6741ec0c90c8525797d041b48585c Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 23 Jun 2020 22:19:41 +0100 Subject: [PATCH 06/37] add n64memory --- Makefile | 1 + files.in | 4 + include/n64memory.h | 227 ++++++++++++++++++ src/n64memory.c | 554 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 786 insertions(+) create mode 100644 include/n64memory.h create mode 100644 src/n64memory.c diff --git a/Makefile b/Makefile index d9dd726e..d29e7c84 100755 --- a/Makefile +++ b/Makefile @@ -66,6 +66,7 @@ install: libdragon.a libdragonsys.a install -m 0644 include/interrupt.h $(INSTALLDIR)/mips64-elf/include/interrupt.h install -m 0644 include/libdragon.h $(INSTALLDIR)/mips64-elf/include/libdragon.h install -m 0644 include/mempak.h $(INSTALLDIR)/mips64-elf/include/mempak.h + install -m 0644 include/n64sys.h $(INSTALLDIR)/mips64-elf/include/n64memory.h install -m 0644 include/n64sys.h $(INSTALLDIR)/mips64-elf/include/n64sys.h install -m 0644 include/rdp.h $(INSTALLDIR)/mips64-elf/include/rdp.h #install -m 0644 include/regsinternal.h $(INSTALLDIR)/mips64-elf/include/regsinternal.h diff --git a/files.in b/files.in index e070bc34..d77aa52e 100755 --- a/files.in +++ b/files.in @@ -12,6 +12,7 @@ OFILES_LD += $(CURDIR)/build/graphics.o OFILES_LD += $(CURDIR)/build/interrupt.o OFILES_LD += $(CURDIR)/build/inthandler.o OFILES_LD += $(CURDIR)/build/mempak.o +OFILES_LD += $(CURDIR)/build/n64memory.o OFILES_LD += $(CURDIR)/build/n64sys.o OFILES_LD += $(CURDIR)/build/rdp.o OFILES_LD += $(CURDIR)/build/regs.o @@ -28,6 +29,9 @@ OFILES_LDS = $(CURDIR)/build/system.o $(CURDIR)/build/n64sys.o: $(CURDIR)/src/n64sys.c mkdir -p $(CURDIR)/build $(CC) $(CFLAGS) -c -o $(CURDIR)/build/n64sys.o $(CURDIR)/src/n64sys.c +$(CURDIR)/build/n64memory.o: $(CURDIR)/src/n64memory.c + mkdir -p $(CURDIR)/build + $(CC) $(CFLAGS) -c -o $(CURDIR)/build/n64memory.o $(CURDIR)/src/n64memory.c $(CURDIR)/build/interrupt.o: $(CURDIR)/src/interrupt.c mkdir -p $(CURDIR)/build $(CC) $(CFLAGS) -c -o $(CURDIR)/build/interrupt.o $(CURDIR)/src/interrupt.c diff --git a/include/n64memory.h b/include/n64memory.h new file mode 100644 index 00000000..72172b5b --- /dev/null +++ b/include/n64memory.h @@ -0,0 +1,227 @@ +#ifndef __N64MEMORY_H +#define __N64MEMORY_H + +#include +#include + +extern void *malloc(size_t n); +extern void free(void *p); + +typedef struct kv_s +{ + uint32_t address; + size_t size; +} kv_t, *kv_p; + +static kv_p kv_set = (kv_p)NULL; + +size_t num_kv = 0; +size_t last_size = 0; + +// added for internal convenience +static int last_mapfind_index = -1; + +#if 0 +#define n64_free(b) \ +free((b)) + +//n64_free2((b), __FILE__, __LINE__) + +#define n64_malloc(s) \ +malloc((s)) + +//n64_malloc2((s), __FILE__, __LINE__) +#endif + +#define n64_memcpy(d,s,t) \ +memcpy((d),(s),(t)) + +#define n64_memmove_naive_no_malloc(d,s,n) \ +memmove((d),(s),(n)) + +#define n64_memmove_naive(d,s,n) \ +memmove((d),(s),(n)) + +#define n64_memmove(d,s,n) \ +memmove((d),(s),(n)) + +#define n64_memmove_old_with_potential_bug(d,s,n) \ +memmove((d),(s),(n)) + +#define n64_memset(p,v,n) \ +memset((p),(v),(n)) + +#define n64_memset2(p,v,n) \ +memset((p),(v),(n)) + +#define n64_realloc(p,n) \ +realloc((p),(n)) + + +void n64_free2(void *buf, char *file, int line); +void *n64_malloc2(size_t size_to_alloc, char *file, int line); +void *n64_memcpy2(void *d, const void *s, size_t n); +void *n64_memmove_naive_no_malloc2(void *dest, const void *src, size_t n); +void *n64_memmove_naive2(void *dest, const void *src, size_t n); +void *n64_memmove2(void *d, const void *s, size_t n); +void *n64_memmove_old_with_potential_bug2(void *d, const void *s, size_t n); +void *n64_memset2_(void *p, int v, size_t n); +void *n64_memset22(void *p, int v, size_t n); +void *n64_realloc2(void *p, size_t n); + +size_t get_allocated_byte_count(void); +size_t get_unmapped_free_count(void); +size_t get_null_free_count(void); + +static void mapresize(size_t new_size); +void mapadd(uint32_t address, size_t size); +void mapremove(uint32_t address); +kv_t *mapfind(uint32_t address); +void mapdump(void); +void new_kv(size_t size); +size_t active_allocations(void); + + +size_t active_allocations(void) +{ + return num_kv; +} + + +void mapadd(uint32_t address, size_t size) +{ + if (NULL == kv_set) + { + new_kv(16); + } + +#ifdef KV_DEBUG // start #ifdef KV_DEBUG + kv_t *kv = mapfind(address); +#if 1 // start #if 1 + if (NULL != kv) + { + printf("mapadd: already mapped kv[%d] == [0x%08X,0x%08X]\n", last_mapfind_index, kv->address, kv->size); + exit(-1); + } +#endif // end #if 1 +#if 0 // start #if 0 +/* if (NULL != kv) + { + kv->address = address; + kv->size = size; + }*/ +#endif // end #if 0 +#if 1 +/* else + {*/ +#endif // end #if 1 +#endif // end #ifdef KV_DEBUG + if (num_kv == last_size) + { + mapresize(last_size * 2); + } + + kv_set[num_kv].address = address; + kv_set[num_kv].size = size; + + num_kv += 1; +#ifdef KV_DEBUG // start #ifdef KV_DEBUG +#if 1 +/* }*/ +#endif +#endif +} + + +static void mapresize(size_t new_size) +{ + size_t i; + + kv_t *tmp_set = (kv_t *)malloc(new_size * sizeof(kv_t)); + memset(tmp_set, 0xFF, new_size * sizeof(kv_t)); + + for (i=0;i /* for size_t */ +#include +#include /* for memcpy */ + +#include "n64memory.h" + +char memory_log[256]; + +#define ALIGNED(addr) (((int)addr % 4) == 0) + +static void mapresize(size_t new_size); + +void mapadd(uint32_t address, size_t size); +void mapremove(uint32_t address); +void mapdump(void); +kv_t *mapfind(uint32_t address); +void new_kv(size_t size); +size_t active_allocations(void); + +size_t allocated_bytes = 0; +size_t null_frees = 0; +size_t unmapped_frees = 0; + + +size_t get_allocated_byte_count() +{ + return allocated_bytes; +} + + +size_t get_unmapped_free_count() +{ + return unmapped_frees; +} + + +size_t get_null_free_count() +{ + return null_frees; +} + +/* +NAME + + realloc - memory reallocator + +SYNOPSIS + + #include + + void *realloc(void *ptr, size_t size); + +DESCRIPTION + + [CX] [Option Start] The functionality described on this reference page is aligned with the ISO C standard. + Any conflict between the requirements described here and the ISO C standard is unintentional. + This volume of IEEE Std 1003.1-2001 defers to the ISO C standard. [Option End] + + The realloc() function shall change the size of the memory object pointed to by ptr to the size specified by size. + The contents of the object shall remain unchanged up to the lesser of the new and old sizes. If the new size of the + memory object would require movement of the object, the space for the previous instantiation of the object is freed. + If the new size is larger, the contents of the newly allocated portion of the object are unspecified. If size is 0 and + ptr is not a null pointer, the object pointed to is freed. If the space cannot be allocated, the object shall remain unchanged. + + If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. + + If ptr does not match a pointer returned earlier by calloc(), malloc(), or realloc() or if the space has previously been + deallocated by a call to free() or realloc(), the behavior is undefined. + + The order and contiguity of storage allocated by successive calls to realloc() is unspecified. The pointer returned if the + allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then + used to access such an object in the space allocated (until the space is explicitly freed or reallocated). Each such + allocation shall yield a pointer to an object disjoint from any other object. The pointer returned shall point to the start + (lowest byte address) of the allocated space. If the space cannot be allocated, a null pointer shall be returned. + +RETURN VALUE + + Upon successful completion with a size not equal to 0, realloc() shall return a pointer to the (possibly moved) allocated space. + If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() shall be returned. + If there is not enough available memory, realloc() shall return a null pointer [CX] [Option Start] and set errno to [ENOMEM]. [Option End] + +ERRORS + + The realloc() function shall fail if: + + [ENOMEM] + [CX] [Option Start] Insufficient memory is available. [Option End] +*/ +void *n64_realloc2(void *ptr, size_t size) +{ + void *return_buffer; + +// printf("args-->[ptr:size]<->[%p,%08X]\n",ptr,(unsigned int)size); + + // "If size is 0" + if (0 == size) + { +// printf("0 == size\n"); + // "and ptr is not a null pointer, the object pointed to is freed." + if (NULL != ptr) + { +// printf("\t0 != ptr\n"); + n64_free(ptr); + } + + // "If size is 0, [...] a null pointer [...] shall be returned." + return_buffer = 0; + goto realloc_return; + } + + // "If ptr is a null pointer, realloc() shall be equivalent + // to malloc() for the specified size." + if (NULL == ptr) + { +// printf("0 == ptr\n"); + return_buffer = n64_malloc(size); + goto realloc_return; + } + + return_buffer = n64_malloc(size); + + // "If there is not enough available memory" + if (NULL == return_buffer) + { +// printf("0 == return_buffer\n"); + // "realloc() shall return a null pointer" + return_buffer = 0; + // "and set errno to [ENOMEM]." +// __errno = ENOMEM; + goto realloc_return; + } + + // retrieve size of old buffer +// printf("%08X\n",(unsigned int)( ((uint32_t)ptr)&0x0FFFFFFF)); + kv_t *old_buffer = mapfind((uint32_t)ptr); + + if (NULL == old_buffer) + { +// printf("0 == old_buffer\n"); +// mapdump(kv_set); + return_buffer = n64_malloc(size); + goto realloc_return; + } + +// printf("old_buffer-->[ptr:size]<->[%08X,%08X]\n", (unsigned int)old_buffer->address, (unsigned int)old_buffer->size); + + size_t old_size = old_buffer->size; + size_t copy_size = size; + + // "The contents of the object shall remain unchanged up to the lesser of the new and old sizes." + if (old_size < size) + { + copy_size = old_size; + } + + // "If the new size is larger, the contents of the newly allocated portion of the object are unspecified." + n64_memcpy(return_buffer, ptr, copy_size); + + // "If the new size of the memory object would require movement of the object, + // the space for the previous instantiation of the object is freed." + n64_free(ptr); + + // single point of return + realloc_return: + return return_buffer; +} + + +void *n64_malloc2(size_t size_to_alloc, char *file, int line) +{ + n64_memset(memory_log, 0x00, 256); + sprintf(memory_log, "n64_malloc(0x%08X): %s %d\n", size_to_alloc, file, line); + + size_t adjusted_size = (size_to_alloc + 3) & ~3; +/* + if (size_to_alloc < 8) + { + adjusted_size = 8; + } + + else if (size_to_alloc % 8 != 0) + { + adjusted_size += (8 - (size_to_alloc % 8)); + } +*/ + void *buf = malloc(adjusted_size); + + if (NULL == buf) + { +// return buf; + goto malloc_return; + } + +// if (0 != buf) +// { + allocated_bytes += adjusted_size; +// } + + // map address to size and store somewhere + mapadd((uint32_t)buf, adjusted_size); + + malloc_return: + return buf; +} + + +void n64_free2(void *buf, char *file, int line) +{ + n64_memset(memory_log, 0x00, 256); + sprintf(memory_log, "n64_free(%p): %s %d\n", buf, file, line); + + if (NULL == buf) + { + null_frees += 1; + return; + } + + kv_t *kv = mapfind((uint32_t)buf); + + // it got malloc'd but we missed it + if (NULL == kv) + { + unmapped_frees += 1; +#if 0 + free(buf); +#endif + } + // we saw the malloc too + else + { + size_t size_to_free = kv->size; + + mapremove((uint32_t)buf); + + free(buf); + + allocated_bytes -= size_to_free; + } +} + + +// A sample naive, literal implementation: +void *n64_memmove_naive_no_malloc2(void *dest, const void *src, size_t n) +{ + unsigned char tmp[n]; + n64_memcpy(tmp,src,n); + n64_memcpy(dest,tmp,n); + return dest; +} + + +// A sample naive, literal implementation: +void *n64_memmove_naive2(void *dest, const void *src, size_t n) +{ + void *tmp = (void *)n64_malloc(n); + if(NULL == tmp) + { + return dest; + } + n64_memcpy(tmp,src,n); + n64_memcpy(dest,tmp,n); + n64_free(tmp); + return dest; +} + + +void *n64_memmove2(void *dest, const void *src, size_t size) +{ + int i; + int size_in_uint32_ts; + int size_in_bytes; + + uint32_t *wd; + uint32_t *ws; + uint8_t *bd; + uint8_t *bs; + uint32_t *wtmp; + uint8_t *btmp; + uint8_t *d; + uint8_t *s; + + void *tmp = (void *)n64_malloc(size); + + if(NULL == tmp) + { +// return dest; + goto memmove_return; + } + + if (ALIGNED(dest) && ALIGNED(src)) + { + wd = (uint32_t*)dest; + ws = (uint32_t*)src; + + size_in_uint32_ts = size >> 2; + size_in_bytes = size % 4; + + bd = (uint8_t*)(dest + (size_in_uint32_ts << 2)); + bs = (uint8_t*)(src + (size_in_uint32_ts << 2)); + + wtmp = (uint32_t*)tmp; + + for (i=0;i> 2; + int size_in_bytes = size % 4; + + wtmp = (uint32_t*)tmp; + + for (i=0;i 0) + { + *bdst++ = *bsrc++; + *bdst++ = *bsrc++; + *bdst++ = *bsrc++; + *bdst++ = *bsrc++; + + w_to_copy--; + } + + while(b_to_copy--) + { + *bdst++ = *bsrc++; + } + } + + return dst; +} + + +// n64_memset is special-cased to fill zeros +// all but two or three calls in Doom had 0 as the fill value +void *n64_memset2_(void *ptr, int value, size_t num) +{ + uint32_t *w = (uint32_t *)ptr; + uint8_t *p = (uint8_t *)ptr; + + if (ALIGNED(ptr)) + { + int words = num / 4; + int bytes = num % 4; + + while (words--) + { + *w++ = 0x00000000; + } + + p = (unsigned char*)w; + + while (bytes--) + { + *p++ = 0x00; + } + } + else + { + while (num--) + { + *p++ = 0x00; + } + } + + return ptr; +} + + +// the non-special case version that accepts arbitrary fill value +void *n64_memset22(void *ptr, int value, size_t num) +{ + uint32_t *w = (uint32_t *)ptr; + uint8_t *p = (uint8_t*)ptr; + uint8_t v; + uint32_t wv; + + v = (uint8_t)(value & 0x0000FF); + wv = (v << 24) | (v << 16) | (v << 8) | v; + + if (ALIGNED(ptr)) + { + int words = num / 4; + int bytes = num % 4; + while (words--) + { + *w++ = wv; + } + + p = (unsigned char*)w; + + while (bytes--) + { + *p++ = v; + } + } + else + { + while (num--) + { + *p++ = v; + } + } + + return ptr; +} + +/** @} */ /* n64memory */ From dae15fa9da1df04cd1390871836ec9debf5dba35 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 23 Jun 2020 22:44:19 +0100 Subject: [PATCH 07/37] fix compiler errors (not sure if they are correct) --- src/n64memory.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/n64memory.c b/src/n64memory.c index c2382963..b82a9a65 100644 --- a/src/n64memory.c +++ b/src/n64memory.c @@ -107,7 +107,7 @@ void *n64_realloc2(void *ptr, size_t size) if (NULL != ptr) { // printf("\t0 != ptr\n"); - n64_free(ptr); + n64_free2(ptr); } // "If size is 0, [...] a null pointer [...] shall be returned." @@ -120,11 +120,11 @@ void *n64_realloc2(void *ptr, size_t size) if (NULL == ptr) { // printf("0 == ptr\n"); - return_buffer = n64_malloc(size); + return_buffer = n64_malloc2(size); goto realloc_return; } - return_buffer = n64_malloc(size); + return_buffer = n64_malloc2(size); // "If there is not enough available memory" if (NULL == return_buffer) @@ -145,7 +145,7 @@ void *n64_realloc2(void *ptr, size_t size) { // printf("0 == old_buffer\n"); // mapdump(kv_set); - return_buffer = n64_malloc(size); + return_buffer = n64_malloc2(size); goto realloc_return; } @@ -165,7 +165,7 @@ void *n64_realloc2(void *ptr, size_t size) // "If the new size of the memory object would require movement of the object, // the space for the previous instantiation of the object is freed." - n64_free(ptr); + n64_free2(ptr); // single point of return realloc_return: @@ -176,7 +176,7 @@ void *n64_realloc2(void *ptr, size_t size) void *n64_malloc2(size_t size_to_alloc, char *file, int line) { n64_memset(memory_log, 0x00, 256); - sprintf(memory_log, "n64_malloc(0x%08X): %s %d\n", size_to_alloc, file, line); + sprintf(memory_log, "n64_malloc2(0x%08X): %s %d\n", size_to_alloc, file, line); size_t adjusted_size = (size_to_alloc + 3) & ~3; /* @@ -259,14 +259,14 @@ void *n64_memmove_naive_no_malloc2(void *dest, const void *src, size_t n) // A sample naive, literal implementation: void *n64_memmove_naive2(void *dest, const void *src, size_t n) { - void *tmp = (void *)n64_malloc(n); + void *tmp = (void *)n64_malloc2(n); if(NULL == tmp) { return dest; } n64_memcpy(tmp,src,n); n64_memcpy(dest,tmp,n); - n64_free(tmp); + n64_free2(tmp); return dest; } @@ -286,7 +286,7 @@ void *n64_memmove2(void *dest, const void *src, size_t size) uint8_t *d; uint8_t *s; - void *tmp = (void *)n64_malloc(size); + void *tmp = (void *)n64_malloc2(size); if(NULL == tmp) { @@ -347,7 +347,7 @@ void *n64_memmove2(void *dest, const void *src, size_t size) } } - n64_free(tmp); + n64_free2(tmp); memmove_return: return dest; @@ -419,7 +419,7 @@ void *n64_memmove_old_with_potential_bug2(void *dest, const void *src, size_t si } } - n64_free(tmp); + n64_free2(tmp); return dest; } From deaf509a44c16abe1d483c74cc08337bd8508606 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 23 Jun 2020 22:56:05 +0100 Subject: [PATCH 08/37] revert n64memory, it is too sketchy! --- Makefile | 1 - files.in | 4 - include/n64memory.h | 227 ------------------ src/n64memory.c | 554 -------------------------------------------- 4 files changed, 786 deletions(-) delete mode 100644 include/n64memory.h delete mode 100644 src/n64memory.c diff --git a/Makefile b/Makefile index d29e7c84..d9dd726e 100755 --- a/Makefile +++ b/Makefile @@ -66,7 +66,6 @@ install: libdragon.a libdragonsys.a install -m 0644 include/interrupt.h $(INSTALLDIR)/mips64-elf/include/interrupt.h install -m 0644 include/libdragon.h $(INSTALLDIR)/mips64-elf/include/libdragon.h install -m 0644 include/mempak.h $(INSTALLDIR)/mips64-elf/include/mempak.h - install -m 0644 include/n64sys.h $(INSTALLDIR)/mips64-elf/include/n64memory.h install -m 0644 include/n64sys.h $(INSTALLDIR)/mips64-elf/include/n64sys.h install -m 0644 include/rdp.h $(INSTALLDIR)/mips64-elf/include/rdp.h #install -m 0644 include/regsinternal.h $(INSTALLDIR)/mips64-elf/include/regsinternal.h diff --git a/files.in b/files.in index d77aa52e..e070bc34 100755 --- a/files.in +++ b/files.in @@ -12,7 +12,6 @@ OFILES_LD += $(CURDIR)/build/graphics.o OFILES_LD += $(CURDIR)/build/interrupt.o OFILES_LD += $(CURDIR)/build/inthandler.o OFILES_LD += $(CURDIR)/build/mempak.o -OFILES_LD += $(CURDIR)/build/n64memory.o OFILES_LD += $(CURDIR)/build/n64sys.o OFILES_LD += $(CURDIR)/build/rdp.o OFILES_LD += $(CURDIR)/build/regs.o @@ -29,9 +28,6 @@ OFILES_LDS = $(CURDIR)/build/system.o $(CURDIR)/build/n64sys.o: $(CURDIR)/src/n64sys.c mkdir -p $(CURDIR)/build $(CC) $(CFLAGS) -c -o $(CURDIR)/build/n64sys.o $(CURDIR)/src/n64sys.c -$(CURDIR)/build/n64memory.o: $(CURDIR)/src/n64memory.c - mkdir -p $(CURDIR)/build - $(CC) $(CFLAGS) -c -o $(CURDIR)/build/n64memory.o $(CURDIR)/src/n64memory.c $(CURDIR)/build/interrupt.o: $(CURDIR)/src/interrupt.c mkdir -p $(CURDIR)/build $(CC) $(CFLAGS) -c -o $(CURDIR)/build/interrupt.o $(CURDIR)/src/interrupt.c diff --git a/include/n64memory.h b/include/n64memory.h deleted file mode 100644 index 72172b5b..00000000 --- a/include/n64memory.h +++ /dev/null @@ -1,227 +0,0 @@ -#ifndef __N64MEMORY_H -#define __N64MEMORY_H - -#include -#include - -extern void *malloc(size_t n); -extern void free(void *p); - -typedef struct kv_s -{ - uint32_t address; - size_t size; -} kv_t, *kv_p; - -static kv_p kv_set = (kv_p)NULL; - -size_t num_kv = 0; -size_t last_size = 0; - -// added for internal convenience -static int last_mapfind_index = -1; - -#if 0 -#define n64_free(b) \ -free((b)) - -//n64_free2((b), __FILE__, __LINE__) - -#define n64_malloc(s) \ -malloc((s)) - -//n64_malloc2((s), __FILE__, __LINE__) -#endif - -#define n64_memcpy(d,s,t) \ -memcpy((d),(s),(t)) - -#define n64_memmove_naive_no_malloc(d,s,n) \ -memmove((d),(s),(n)) - -#define n64_memmove_naive(d,s,n) \ -memmove((d),(s),(n)) - -#define n64_memmove(d,s,n) \ -memmove((d),(s),(n)) - -#define n64_memmove_old_with_potential_bug(d,s,n) \ -memmove((d),(s),(n)) - -#define n64_memset(p,v,n) \ -memset((p),(v),(n)) - -#define n64_memset2(p,v,n) \ -memset((p),(v),(n)) - -#define n64_realloc(p,n) \ -realloc((p),(n)) - - -void n64_free2(void *buf, char *file, int line); -void *n64_malloc2(size_t size_to_alloc, char *file, int line); -void *n64_memcpy2(void *d, const void *s, size_t n); -void *n64_memmove_naive_no_malloc2(void *dest, const void *src, size_t n); -void *n64_memmove_naive2(void *dest, const void *src, size_t n); -void *n64_memmove2(void *d, const void *s, size_t n); -void *n64_memmove_old_with_potential_bug2(void *d, const void *s, size_t n); -void *n64_memset2_(void *p, int v, size_t n); -void *n64_memset22(void *p, int v, size_t n); -void *n64_realloc2(void *p, size_t n); - -size_t get_allocated_byte_count(void); -size_t get_unmapped_free_count(void); -size_t get_null_free_count(void); - -static void mapresize(size_t new_size); -void mapadd(uint32_t address, size_t size); -void mapremove(uint32_t address); -kv_t *mapfind(uint32_t address); -void mapdump(void); -void new_kv(size_t size); -size_t active_allocations(void); - - -size_t active_allocations(void) -{ - return num_kv; -} - - -void mapadd(uint32_t address, size_t size) -{ - if (NULL == kv_set) - { - new_kv(16); - } - -#ifdef KV_DEBUG // start #ifdef KV_DEBUG - kv_t *kv = mapfind(address); -#if 1 // start #if 1 - if (NULL != kv) - { - printf("mapadd: already mapped kv[%d] == [0x%08X,0x%08X]\n", last_mapfind_index, kv->address, kv->size); - exit(-1); - } -#endif // end #if 1 -#if 0 // start #if 0 -/* if (NULL != kv) - { - kv->address = address; - kv->size = size; - }*/ -#endif // end #if 0 -#if 1 -/* else - {*/ -#endif // end #if 1 -#endif // end #ifdef KV_DEBUG - if (num_kv == last_size) - { - mapresize(last_size * 2); - } - - kv_set[num_kv].address = address; - kv_set[num_kv].size = size; - - num_kv += 1; -#ifdef KV_DEBUG // start #ifdef KV_DEBUG -#if 1 -/* }*/ -#endif -#endif -} - - -static void mapresize(size_t new_size) -{ - size_t i; - - kv_t *tmp_set = (kv_t *)malloc(new_size * sizeof(kv_t)); - memset(tmp_set, 0xFF, new_size * sizeof(kv_t)); - - for (i=0;i /* for size_t */ -#include -#include /* for memcpy */ - -#include "n64memory.h" - -char memory_log[256]; - -#define ALIGNED(addr) (((int)addr % 4) == 0) - -static void mapresize(size_t new_size); - -void mapadd(uint32_t address, size_t size); -void mapremove(uint32_t address); -void mapdump(void); -kv_t *mapfind(uint32_t address); -void new_kv(size_t size); -size_t active_allocations(void); - -size_t allocated_bytes = 0; -size_t null_frees = 0; -size_t unmapped_frees = 0; - - -size_t get_allocated_byte_count() -{ - return allocated_bytes; -} - - -size_t get_unmapped_free_count() -{ - return unmapped_frees; -} - - -size_t get_null_free_count() -{ - return null_frees; -} - -/* -NAME - - realloc - memory reallocator - -SYNOPSIS - - #include - - void *realloc(void *ptr, size_t size); - -DESCRIPTION - - [CX] [Option Start] The functionality described on this reference page is aligned with the ISO C standard. - Any conflict between the requirements described here and the ISO C standard is unintentional. - This volume of IEEE Std 1003.1-2001 defers to the ISO C standard. [Option End] - - The realloc() function shall change the size of the memory object pointed to by ptr to the size specified by size. - The contents of the object shall remain unchanged up to the lesser of the new and old sizes. If the new size of the - memory object would require movement of the object, the space for the previous instantiation of the object is freed. - If the new size is larger, the contents of the newly allocated portion of the object are unspecified. If size is 0 and - ptr is not a null pointer, the object pointed to is freed. If the space cannot be allocated, the object shall remain unchanged. - - If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. - - If ptr does not match a pointer returned earlier by calloc(), malloc(), or realloc() or if the space has previously been - deallocated by a call to free() or realloc(), the behavior is undefined. - - The order and contiguity of storage allocated by successive calls to realloc() is unspecified. The pointer returned if the - allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then - used to access such an object in the space allocated (until the space is explicitly freed or reallocated). Each such - allocation shall yield a pointer to an object disjoint from any other object. The pointer returned shall point to the start - (lowest byte address) of the allocated space. If the space cannot be allocated, a null pointer shall be returned. - -RETURN VALUE - - Upon successful completion with a size not equal to 0, realloc() shall return a pointer to the (possibly moved) allocated space. - If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() shall be returned. - If there is not enough available memory, realloc() shall return a null pointer [CX] [Option Start] and set errno to [ENOMEM]. [Option End] - -ERRORS - - The realloc() function shall fail if: - - [ENOMEM] - [CX] [Option Start] Insufficient memory is available. [Option End] -*/ -void *n64_realloc2(void *ptr, size_t size) -{ - void *return_buffer; - -// printf("args-->[ptr:size]<->[%p,%08X]\n",ptr,(unsigned int)size); - - // "If size is 0" - if (0 == size) - { -// printf("0 == size\n"); - // "and ptr is not a null pointer, the object pointed to is freed." - if (NULL != ptr) - { -// printf("\t0 != ptr\n"); - n64_free2(ptr); - } - - // "If size is 0, [...] a null pointer [...] shall be returned." - return_buffer = 0; - goto realloc_return; - } - - // "If ptr is a null pointer, realloc() shall be equivalent - // to malloc() for the specified size." - if (NULL == ptr) - { -// printf("0 == ptr\n"); - return_buffer = n64_malloc2(size); - goto realloc_return; - } - - return_buffer = n64_malloc2(size); - - // "If there is not enough available memory" - if (NULL == return_buffer) - { -// printf("0 == return_buffer\n"); - // "realloc() shall return a null pointer" - return_buffer = 0; - // "and set errno to [ENOMEM]." -// __errno = ENOMEM; - goto realloc_return; - } - - // retrieve size of old buffer -// printf("%08X\n",(unsigned int)( ((uint32_t)ptr)&0x0FFFFFFF)); - kv_t *old_buffer = mapfind((uint32_t)ptr); - - if (NULL == old_buffer) - { -// printf("0 == old_buffer\n"); -// mapdump(kv_set); - return_buffer = n64_malloc2(size); - goto realloc_return; - } - -// printf("old_buffer-->[ptr:size]<->[%08X,%08X]\n", (unsigned int)old_buffer->address, (unsigned int)old_buffer->size); - - size_t old_size = old_buffer->size; - size_t copy_size = size; - - // "The contents of the object shall remain unchanged up to the lesser of the new and old sizes." - if (old_size < size) - { - copy_size = old_size; - } - - // "If the new size is larger, the contents of the newly allocated portion of the object are unspecified." - n64_memcpy(return_buffer, ptr, copy_size); - - // "If the new size of the memory object would require movement of the object, - // the space for the previous instantiation of the object is freed." - n64_free2(ptr); - - // single point of return - realloc_return: - return return_buffer; -} - - -void *n64_malloc2(size_t size_to_alloc, char *file, int line) -{ - n64_memset(memory_log, 0x00, 256); - sprintf(memory_log, "n64_malloc2(0x%08X): %s %d\n", size_to_alloc, file, line); - - size_t adjusted_size = (size_to_alloc + 3) & ~3; -/* - if (size_to_alloc < 8) - { - adjusted_size = 8; - } - - else if (size_to_alloc % 8 != 0) - { - adjusted_size += (8 - (size_to_alloc % 8)); - } -*/ - void *buf = malloc(adjusted_size); - - if (NULL == buf) - { -// return buf; - goto malloc_return; - } - -// if (0 != buf) -// { - allocated_bytes += adjusted_size; -// } - - // map address to size and store somewhere - mapadd((uint32_t)buf, adjusted_size); - - malloc_return: - return buf; -} - - -void n64_free2(void *buf, char *file, int line) -{ - n64_memset(memory_log, 0x00, 256); - sprintf(memory_log, "n64_free(%p): %s %d\n", buf, file, line); - - if (NULL == buf) - { - null_frees += 1; - return; - } - - kv_t *kv = mapfind((uint32_t)buf); - - // it got malloc'd but we missed it - if (NULL == kv) - { - unmapped_frees += 1; -#if 0 - free(buf); -#endif - } - // we saw the malloc too - else - { - size_t size_to_free = kv->size; - - mapremove((uint32_t)buf); - - free(buf); - - allocated_bytes -= size_to_free; - } -} - - -// A sample naive, literal implementation: -void *n64_memmove_naive_no_malloc2(void *dest, const void *src, size_t n) -{ - unsigned char tmp[n]; - n64_memcpy(tmp,src,n); - n64_memcpy(dest,tmp,n); - return dest; -} - - -// A sample naive, literal implementation: -void *n64_memmove_naive2(void *dest, const void *src, size_t n) -{ - void *tmp = (void *)n64_malloc2(n); - if(NULL == tmp) - { - return dest; - } - n64_memcpy(tmp,src,n); - n64_memcpy(dest,tmp,n); - n64_free2(tmp); - return dest; -} - - -void *n64_memmove2(void *dest, const void *src, size_t size) -{ - int i; - int size_in_uint32_ts; - int size_in_bytes; - - uint32_t *wd; - uint32_t *ws; - uint8_t *bd; - uint8_t *bs; - uint32_t *wtmp; - uint8_t *btmp; - uint8_t *d; - uint8_t *s; - - void *tmp = (void *)n64_malloc2(size); - - if(NULL == tmp) - { -// return dest; - goto memmove_return; - } - - if (ALIGNED(dest) && ALIGNED(src)) - { - wd = (uint32_t*)dest; - ws = (uint32_t*)src; - - size_in_uint32_ts = size >> 2; - size_in_bytes = size % 4; - - bd = (uint8_t*)(dest + (size_in_uint32_ts << 2)); - bs = (uint8_t*)(src + (size_in_uint32_ts << 2)); - - wtmp = (uint32_t*)tmp; - - for (i=0;i> 2; - int size_in_bytes = size % 4; - - wtmp = (uint32_t*)tmp; - - for (i=0;i 0) - { - *bdst++ = *bsrc++; - *bdst++ = *bsrc++; - *bdst++ = *bsrc++; - *bdst++ = *bsrc++; - - w_to_copy--; - } - - while(b_to_copy--) - { - *bdst++ = *bsrc++; - } - } - - return dst; -} - - -// n64_memset is special-cased to fill zeros -// all but two or three calls in Doom had 0 as the fill value -void *n64_memset2_(void *ptr, int value, size_t num) -{ - uint32_t *w = (uint32_t *)ptr; - uint8_t *p = (uint8_t *)ptr; - - if (ALIGNED(ptr)) - { - int words = num / 4; - int bytes = num % 4; - - while (words--) - { - *w++ = 0x00000000; - } - - p = (unsigned char*)w; - - while (bytes--) - { - *p++ = 0x00; - } - } - else - { - while (num--) - { - *p++ = 0x00; - } - } - - return ptr; -} - - -// the non-special case version that accepts arbitrary fill value -void *n64_memset22(void *ptr, int value, size_t num) -{ - uint32_t *w = (uint32_t *)ptr; - uint8_t *p = (uint8_t*)ptr; - uint8_t v; - uint32_t wv; - - v = (uint8_t)(value & 0x0000FF); - wv = (v << 24) | (v << 16) | (v << 8) | v; - - if (ALIGNED(ptr)) - { - int words = num / 4; - int bytes = num % 4; - while (words--) - { - *w++ = wv; - } - - p = (unsigned char*)w; - - while (bytes--) - { - *p++ = v; - } - } - else - { - while (num--) - { - *p++ = v; - } - } - - return ptr; -} - -/** @} */ /* n64memory */ From d77f87df489b35434627ed584d7a223d79186591 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 23 Jun 2020 23:58:59 +0100 Subject: [PATCH 09/37] Bring in latest libdragon change align display buf --- src/display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/display.c b/src/display.c index 2c81f3f8..73599f61 100644 --- a/src/display.c +++ b/src/display.c @@ -64,7 +64,7 @@ * * @return An aligned address guaranteed to be >= the unaligned address */ -#define ALIGN_16BYTE(x) ((void *)(((uint32_t)(x)+15) & 0xFFFFFFF0)) +#define ALIGN_64BYTE(x) ((void *)(((uint32_t)(x)+63) & 0xFFFFFFC0)) /** @brief Video buffer pointers */ @@ -428,8 +428,8 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu { /* Set parameters necessary for drawing */ /* Grab a location to render to */ - buffer[i] = malloc( __width * __height * __bitdepth + 15 ); - __safe_buffer[i] = ALIGN_16BYTE( UNCACHED_ADDR( buffer[i] ) ); + buffer[i] = malloc( __width * __height * __bitdepth + 63 ); + __safe_buffer[i] = ALIGN_64BYTE( UNCACHED_ADDR( buffer[i] ) ); /* Baseline is blank */ memset( __safe_buffer[i], 0, __width * __height * __bitdepth ); From 05b32df8e9f7c9921161c28351f93af2dec8fe90 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 23 Jun 2020 23:59:56 +0100 Subject: [PATCH 10/37] Update comment in previous commit. --- src/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index 73599f61..79a6d998 100644 --- a/src/display.c +++ b/src/display.c @@ -57,7 +57,7 @@ #define UNCACHED_ADDR(x) ((void *)(((uint32_t)(x)) | 0xA0000000)) /** - * @brief Align a memory address to 16 byte offset + * @brief Align a memory address to 64 byte offset * * @param[in] x * Unaligned memory address From cfd51bd7b5dd8f3581fa92dc8be5b0c311c502d2 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Wed, 24 Jun 2020 01:19:14 +0100 Subject: [PATCH 11/37] write register rather than DRAM register brings changes from later libdragon verions. --- src/display.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index 79a6d998..b1d21ce1 100644 --- a/src/display.c +++ b/src/display.c @@ -436,12 +436,16 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu } /* Set the first buffer as the displaying buffer */ - __write_dram_register( __safe_buffer[0] ); now_showing = 0; now_drawing = -1; show_next = -1; + /* Show our screen normally */ + //__registers[1] = (uintptr_t) __safe_buffer[0]; + //__registers[9] = __reg_values[tv_type][9]; + __write_registers( __registers ); + enable_interrupts(); /* Set which line to call back on in order to flip screens */ From 18ff6ebc224a2c48f92981587390433f84bfdc89 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 11:23:29 +0100 Subject: [PATCH 12/37] Adds latest changes --- include/audio.h | 5 + include/controller.h | 18 +- include/rdp.h | 29 +- include/rsp.h | 74 +++++- src/audio.c | 115 +++++++- src/controller.c | 50 +++- src/display.c | 8 +- src/dma.c | 14 +- src/rdp.c | 182 ++++--------- src/rsp.c | 613 ++++++++++++++++++++++++++++++++++++------- src/system.c | 34 +-- 11 files changed, 855 insertions(+), 287 deletions(-) diff --git a/include/audio.h b/include/audio.h index 0ac3067a..3d52f82d 100644 --- a/include/audio.h +++ b/include/audio.h @@ -25,6 +25,8 @@ extern "C" { */ typedef void(*audio_fill_buffer_callback)(short *buffer, size_t numsamples); +void audio_init_ex(const int frequency, int numbuffers, int maxsamples, void (*cb)()); + void audio_init(const int frequency, int numbuffers); void audio_set_buffer_callback(audio_fill_buffer_callback fill_buffer_callback); void audio_pause(bool pause); @@ -34,6 +36,9 @@ void audio_write_silence(); void audio_close(); int audio_get_frequency(); int audio_get_buffer_length(); +void audio_set_num_samples(int numsamples); +short *audio_get_next_buffer(int *lastbuf); +volatile int audio_send_buffer(int lastbuf); #ifdef __cplusplus } diff --git a/include/controller.h b/include/controller.h index 115764c8..964763ed 100755 --- a/include/controller.h +++ b/include/controller.h @@ -14,7 +14,7 @@ /** * @name Bitmasks for controller status * @see #get_controllers_present - * @see #get_accessories_present + * @see #get_accessories_present * @{ */ /** @brief Controller 1 Inserted */ @@ -44,6 +44,21 @@ #define ACCESSORY_TRANSFERPAK 4 /** @} */ +/** + * @name Controller ID Values + * @see #identify_controller + * @{ + */ +/** @brief No controller present */ +#define CONTROLLER_NONE 0xFF +/** @brief Mouse present */ +#define CONTROLLER_MOUSE 2 +/** @brief Keyboard present */ +#define CONTROLLER_KEYBOARD 4 // ?? fixme! +/** @brief Digital pad present */ +#define CONTROLLER_PAD 5 +/** @} */ + /** * @name SI Error Values * @{ @@ -192,6 +207,7 @@ int get_dpad_direction( int controller ); int read_mempak_address( int controller, uint16_t address, uint8_t *data ); int write_mempak_address( int controller, uint16_t address, uint8_t *data ); int identify_accessory( int controller ); +int identify_controller( int controller ); void rumble_start( int controller ); void rumble_stop( int controller ); void execute_raw_command( int controller, int command, int bytesout, int bytesin, unsigned char *out, unsigned char *in ); diff --git a/include/rdp.h b/include/rdp.h index 56090874..8fcd68e5 100644 --- a/include/rdp.h +++ b/include/rdp.h @@ -21,12 +21,14 @@ typedef enum { /** @brief Disable texture mirroring */ MIRROR_DISABLED, - /** @brief Enable texture mirroring on x axis */ - MIRROR_X, - /** @brief Enable texture mirroring on y axis */ - MIRROR_Y, - /** @brief Enable texture mirroring on both x & y axis */ - MIRROR_XY + /** @brief Enable texture mirroring */ //removed + MIRROR_ENABLED //removed + // /** @brief Enable texture mirroring on x axis */ + // MIRROR_X, + // /** @brief Enable texture mirroring on y axis */ + // MIRROR_Y, + // /** @brief Enable texture mirroring on both x & y axis */ + // MIRROR_XY } mirror_t; /** @@ -70,12 +72,13 @@ void rdp_set_default_clipping( void ); void rdp_enable_primitive_fill( void ); void rdp_enable_blend_fill( void ); void rdp_enable_texture_copy( void ); -uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite ); -uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset ); -void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ); -void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror ); -void rdp_draw_sprite( uint32_t texslot, int x, int y , mirror_t mirror); -void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror); +void rdp_enable_texture_copy_flags( uint32_t flags1, uint32_t flags2 ); +uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite ); //uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite ) +uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite, int offset ); //uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset ); +void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by ); //void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ); +void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale ); //void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror ); +void rdp_draw_sprite( uint32_t texslot, int x, int y ); //void rdp_draw_sprite( uint32_t texslot, int x, int y , mirror_t mirror); +void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale ); //void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror); void rdp_set_primitive_color( uint32_t color ); void rdp_set_blend_color( uint32_t color ); void rdp_draw_filled_rectangle( int tx, int ty, int bx, int by ); @@ -83,6 +86,8 @@ void rdp_draw_filled_triangle( float x1, float y1, float x2, float y2, float x3, void rdp_set_texture_flush( flush_t flush ); void rdp_close( void ); +void rdp_DrawImageBig(int x, int y, sprite_t *image); + #ifdef __cplusplus } #endif diff --git a/include/rsp.h b/include/rsp.h index 29dfebc1..918a22cc 100644 --- a/include/rsp.h +++ b/include/rsp.h @@ -1,21 +1,81 @@ /** * @file rsp.h - * @brief Hardware Vector Interface + * @brief Hardware Coprocessor Interface * @ingroup rsp */ #ifndef __LIBDRAGON_RSP_H #define __LIBDRAGON_RSP_H +/** + * @addtogroup rsp + * @{ + */ + +/** + * @brief Internal Job structure + */ +typedef struct ijob { + struct ijob *prev; + struct ijob *next; + + void (*cb)(struct ijob *); + + volatile uint32_t state; + uint32_t fn; + uint32_t args[16]; + +} job_t; + +/** + * @brief Job states + */ +#define JOB_STATE_IDLE 0 +#define JOB_STATE_QUEUED 1 +#define JOB_STATE_RUNNING 2 +#define JOB_STATE_FINISHED 3 + +/** + * @brief Internal Job Queue structure + */ +typedef struct { + job_t *head; + job_t *tail; + +} job_queue_t; + +/** @} */ + #ifdef __cplusplus extern "C" { #endif -void rsp_init(); -void load_ucode(void * start, unsigned long size); -void read_ucode(void* start, unsigned long size); -void load_data(void * start, unsigned long size); -void read_data(void* start, unsigned long size); -void run_ucode(); +/** + * @brief Low Level Functions + */ +uint32_t __rsp_lock( uint32_t wait ); +void __rsp_unlock( void ); +void __rsp_wait_dma( uint32_t busy ); +void __rsp_dma_read( uint32_t offs, void *src, uint32_t len ); +void __rsp_dma_write( uint32_t offs, void *dst, uint32_t len ); +void __rsp_blk_read( uint32_t offs, void *src, uint16_t pitch, uint16_t width, uint16_t height, uint16_t bpp ); +void __rsp_blk_write( uint32_t offs, void *dst, uint16_t pitch, uint16_t width, uint16_t height, uint16_t bpp ); +uint32_t __rsp_get_status( void ); +void __rsp_set_status( uint32_t flags ); +void __rsp_set_pc( uint32_t pc ); + +/** + * @brief High Level Functions + */ +void rsp_init( void ); +void rsp_close( void ); +void rsp_load_lib( uint8_t *lib ); +uint32_t rsp_lib_fn( char *mod, uint32_t fn ); +void rsp_queue_job( job_t *job ); +void rsp_do_job( job_t *job ); +void rsp_wait_job( job_t *job ); +void rsp_abort_job( job_t *job ); +job_t *rsp_new_job( uint32_t fn, void (*cb)(job_t *), uint32_t count, ... ); +void rsp_dispose_job( job_t *job ); #ifdef __cplusplus } diff --git a/src/audio.c b/src/audio.c index 04322d3d..d7a3a6df 100644 --- a/src/audio.c +++ b/src/audio.c @@ -86,10 +86,14 @@ */ #define CALC_BUFFER(x) ( ( ( ( x ) / 25 ) >> 3 ) << 3 ) +/** @brief The actual frequency the AI will run at */ +static void (*_callback)() = NULL; /** @brief The actual frequency the AI will run at */ static int _frequency = 0; /** @brief The number of buffers currently allocated */ static int _num_buf = NUM_BUFFERS; +/** @brief The number of samples to write into each buffer */ +static int _num_samp = 0; /** @brief The buffer size in bytes for each buffer allocated */ static int _buf_size = 0; /** @brief Array of pointers to the allocated buffers */ @@ -194,10 +198,36 @@ static void audio_callback() * The frequency in Hz to play back samples at * @param[in] numbuffers * The number of buffers to allocate internally - * @param[in] fill_buffer_callback + * * @param[in] fill_buffer_callback * A function to be called when more sample data is needed */ void audio_init(const int frequency, int numbuffers) +{ + audio_init_ex(frequency, numbuffers, CALC_BUFFER(frequency) >> 2, NULL); +} + +/** + * @brief Initialize the audio subsystem (extended) + * + * This function will set up the AI to play at a given frequency, + * allocate a number of back buffers to write data to using the + * specified max number of stereo samples, and set the provided + * callback function. Max samples must be even, and if the callback + * is NULL, the built-in callback is used. + * + * @note Before re-initializing the audio subsystem to a new playback + * frequency, remember to call #audio_close. + * + * @param[in] frequency + * The frequency in Hz to play back samples at + * @param[in] numbuffers + * The number of buffers to allocate internally + * @param[in] maxsamples + * The max number of stereo 16-bit samples each buffer will hold + * @param[in] cb + * The callback function for audio interrupts + */ +void audio_init_ex(const int frequency, int numbuffers, int maxsamples, void (*cb)()) { int clockrate; @@ -234,11 +264,16 @@ void audio_init(const int frequency, int numbuffers) _frequency = 2 * clockrate / ((2 * clockrate / frequency) + 1); /* Set up hardware to notify us when it needs more data */ - register_AI_handler(audio_callback); + if (cb) + _callback = cb; + else + _callback = audio_callback; + register_AI_handler(_callback); set_AI_interrupt(1); /* Set up buffers */ - _buf_size = CALC_BUFFER(_frequency); + _num_samp = maxsamples & ~1; /* maxsamples MUST be even */ + _buf_size = _num_samp; _num_buf = (numbuffers > 1) ? numbuffers : NUM_BUFFERS; buffers = malloc(_num_buf * sizeof(short *)); @@ -275,7 +310,7 @@ void audio_set_buffer_callback(audio_fill_buffer_callback fill_buffer_callback) void audio_close() { set_AI_interrupt(0); - unregister_AI_handler(audio_callback); + unregister_AI_handler(_callback); if(buffers) { @@ -295,6 +330,7 @@ void audio_close() } _frequency = 0; + _num_samp = 0; _buf_size = 0; } @@ -325,7 +361,6 @@ void audio_pause(bool pause) { enable_interrupts(); } } - /** * @brief Write a chunk of audio data * @@ -447,4 +482,74 @@ int audio_get_buffer_length() return _buf_size; } +/** + * @brief Change the number of stereo samples to write to each buffer + * + * This function sets how many stereo samples to write to the audio + * buffers. It should be even so that the buffer length is divisible + * by eight bytes for DMA restrictions. It MUST be smaller than the + * max number of samples passed to #audio_init_ex, but is not checked. + * + * @param[in] numsamples + * number of stereo samples to write to each buffer + */ +void audio_set_num_samples(int numsamples) +{ + _num_samp = numsamples & ~1; /* numsamples MUST be even */ + _buf_size = _num_samp; +} + +/** + * @brief Return the address of the next buffer to fill + * + * This function returns a pointer to the next buffer to fill with + * stereo 16-bit samples. The number of stereo samples to write may + * be found by calling #audio_get_buffer_length. Pointer is uncached. + * + * @param[in] lastbuf + * pointer to previous buffer index + * + * @return Uncached pointer to the next available sample buffer + */ +short *audio_get_next_buffer(int *lastbuf) +{ + if(!buffers) + { + return NULL; + } + + int next = (*lastbuf + 1) % _num_buf; + *lastbuf = next; + return UncachedShortAddr(buffers[next]); +} + +/** + * @brief Start audio DMA on buffer + * + * This function sets the audio DMA for the indexed buffer (should be + * the same as set by #audio_get_next_buffer), and starts the DMA. + * + * @param[in] lastbuf + * last buffer index returned by #audio_get_next_buffer + * + * @return 0 if audio DMA is full, or 1 if indexed buffer queued + */ +volatile int audio_send_buffer(int lastbuf) +{ + if (__full()) + return 0; + + /* Set up DMA */ + AI_regs->address = UncachedAddr(buffers[lastbuf]); + MEMORY_BARRIER(); + AI_regs->length = _num_samp << 2; + MEMORY_BARRIER(); + + /* Start DMA */ + AI_regs->control = 1; + MEMORY_BARRIER(); + + return 1; +} + /** @} */ /* audio */ diff --git a/src/controller.c b/src/controller.c index 803d4507..adfcd830 100755 --- a/src/controller.c +++ b/src/controller.c @@ -12,7 +12,7 @@ * @ingroup libdragon * @brief Controller and accessory interface. * - * The controller subsystem is in charge of communication with all controllers + * The controller subsystem is in charge of communication with all controllers * and accessories plugged into the N64. The controller subsystem is responsible * for interfacing with the serial interface (SI) registers to provide controller * data, mempak and rumblepak interfacing, and EEPROM interfacing. @@ -20,7 +20,7 @@ * Code wishing to communicate with a controller or an accessory should first call * #controller_init. Once the controller subsystem has been initialized, code can * either scan the controller interface for changes or perform direct reads from - * the controller interface. Controllers can be enumerated with + * the controller interface. Controllers can be enumerated with * #get_controllers_present. Similarly, accessories can be enumerated with * #get_accessories_present and #identify_accesory. * @@ -72,8 +72,8 @@ static struct controller_data current; /** @brief The previously sampled controller data */ static struct controller_data last; -/** - * @brief Initialize the controller subsystem +/** + * @brief Initialize the controller subsystem */ void controller_init() { @@ -172,7 +172,7 @@ int eeprom_present() /** * @brief Read a block from EEPROM - * + * * @param[in] block * Block to read data from. The N64 accesses eeprom in 8 byte blocks. * @param[out] buf @@ -182,8 +182,8 @@ void eeprom_read(int block, uint8_t * const buf) { static unsigned long long SI_eeprom_read_block[8] = { - 0x0000000002080400, // LSB is block - 0xffffffffffffffff, // return data will be this quad + 0x0000000002080400, // LSB is block + 0xffffffffffffffff, // return data will be this quad 0xfe00000000000000, 0, 0, @@ -193,7 +193,7 @@ void eeprom_read(int block, uint8_t * const buf) }; static unsigned long long output[8]; - SI_eeprom_read_block[0] = 0x0000000002080400 | (block & 255); + SI_eeprom_read_block[0] = 0x0000000002080400 | (block & 255); __controller_exec_PIF(SI_eeprom_read_block,output); memcpy( buf, &output[1], 8 ); } @@ -210,9 +210,9 @@ void eeprom_write(int block, const uint8_t * const data) { static unsigned long long SI_eeprom_write_block[8] = { - 0x000000000a010500, // LSB is block - 0x0000000000000000, // send data is this quad - 0xfffe000000000000, // MSB will be status of write + 0x000000000a010500, // LSB is block + 0x0000000000000000, // send data is this quad + 0xfffe000000000000, // MSB will be status of write 0, 0, 0, @@ -221,7 +221,7 @@ void eeprom_write(int block, const uint8_t * const data) }; static unsigned long long output[8]; - SI_eeprom_write_block[0] = 0x000000000a010500 | (block & 255); + SI_eeprom_write_block[0] = 0x000000000a010500 | (block & 255); memcpy( &SI_eeprom_write_block[1], data, 8 ); __controller_exec_PIF(SI_eeprom_write_block,output); } @@ -623,7 +623,7 @@ static void __get_accessories_present( struct controller_data *output ) * @brief Return a bitmask specifying which controllers have recognized accessories * * Queries the controller interface and returns a bitmask specifying which - * controllers have recognized accessories present. See #CONTROLLER_1_INSERTED, + * controllers have recognized accessories present. See #CONTROLLER_1_INSERTED, * #CONTROLLER_2_INSERTED, #CONTROLLER_3_INSERTED and #CONTROLLER_4_INSERTED. * * @return A bitmask representing accessories recognized @@ -911,7 +911,6 @@ static bool __is_transfer_pak( int controller ) * * @retval #ACCESSORY_RUMBLEPAK The accessory connected is a rumblepak * @retval #ACCESSORY_MEMPAK The accessory connected is a mempak - * @retval #ACCESSORY_TRANSFERPAK The accessory connected is a transferpak * @retval #ACCESSORY_VRU The accessory connected is a VRU * @retval #ACCESSORY_NONE The accessory was not recognized */ @@ -965,6 +964,29 @@ int identify_accessory( int controller ) return ACCESSORY_NONE; } +/** + * @brief Identify the controller connected to a controller port + * + * Given a controller port, identify the particular controller. + * + * @param[in] controller + * The controller port (0-3) to identify controller on + * + * @retval #CONTROLLER_PAD The controller connected is a standard pad + * @retval #CONTROLLER_MOUSE The controller connected is a mouse + * @retval #CONTROLLER_KEYBOARD The controller connected is a keyboard + * @retval #CONTROLLER_NONE The controller port has no controller connected + */ +int identify_controller( int controller ) +{ + struct controller_data output; + + /* get the controller status bytes */ + __get_accessories_present( &output ); + + return output.c[controller].data >> 24; +} + /** * @brief Turn rumble on for a particular controller * diff --git a/src/display.c b/src/display.c index b1d21ce1..569c6a4d 100644 --- a/src/display.c +++ b/src/display.c @@ -51,7 +51,7 @@ * * @param[in] x * The cached address - * + * * @return The uncached address */ #define UNCACHED_ADDR(x) ((void *)(((uint32_t)(x)) | 0xA0000000)) @@ -374,12 +374,12 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu else { /* lo-res non-interlaced display */ - __registers[6] = 0x20C; /* vsync */ - __registers[10] = 0x002301FD; /* vstart for field 1 */ + __registers[6] = 0x20D; /* vsync */ + __registers[10] = 0x002501FF; /* vstart for field 1 */ __registers[10 + REGISTER_COUNT] = 0x002501FF; /* vstart for field 2 */ __registers[11] = 0x000E0204; /* vburst for field 1 */ __registers[11 + REGISTER_COUNT] = 0x000E0204; /* vburst for field 2 */ - __registers[13] = 0x0000400; /* y-scale */ + __registers[13] = 0x00000400; /* y-scale */ } break; case TV_TYPE_MPAL: diff --git a/src/dma.c b/src/dma.c index 853cc852..c6495926 100644 --- a/src/dma.c +++ b/src/dma.c @@ -42,12 +42,12 @@ /** @brief Structure used to interact with the PI registers */ static volatile struct PI_regs_s * const PI_regs = (struct PI_regs_s *)0xa4600000; -/** +/** * @brief Return whether the DMA controller is currently busy * * @return nonzero if the DMA controller is busy or 0 otherwise */ -volatile int dma_busy() +volatile int dma_busy() { return PI_regs->status & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY); } @@ -64,7 +64,7 @@ volatile int dma_busy() * @param[in] len * Length in bytes to read into ram_address */ -void dma_read(void * ram_address, unsigned long pi_address, unsigned long len) +void dma_read(void * ram_address, unsigned long pi_address, unsigned long len) { disable_interrupts(); @@ -72,7 +72,7 @@ void dma_read(void * ram_address, unsigned long pi_address, unsigned long len) MEMORY_BARRIER(); PI_regs->ram_address = ram_address; MEMORY_BARRIER(); - PI_regs->pi_address = (pi_address | 0x10000000) & 0x1FFFFFFF; + PI_regs->pi_address = pi_address; //(pi_address | 0x10000000) & 0x1FFFFFFF; MEMORY_BARRIER(); PI_regs->write_length = len-1; MEMORY_BARRIER(); @@ -93,7 +93,7 @@ void dma_read(void * ram_address, unsigned long pi_address, unsigned long len) * @param[in] len * Length in bytes to write to peripheral */ -void dma_write(void * ram_address, unsigned long pi_address, unsigned long len) +void dma_write(void * ram_address, unsigned long pi_address, unsigned long len) { disable_interrupts(); @@ -101,7 +101,7 @@ void dma_write(void * ram_address, unsigned long pi_address, unsigned long len) MEMORY_BARRIER(); PI_regs->ram_address = ram_address; MEMORY_BARRIER(); - PI_regs->pi_address = (pi_address | 0x10000000) & 0x1FFFFFFF; + PI_regs->pi_address = pi_address; //(pi_address | 0x10000000) & 0x1FFFFFFF; MEMORY_BARRIER(); PI_regs->read_length = len-1; MEMORY_BARRIER(); @@ -144,7 +144,7 @@ uint32_t io_read(uint32_t pi_address) * @param[in] data * 32 bit value to write to peripheral */ -void io_write(uint32_t pi_address, uint32_t data) +void io_write(uint32_t pi_address, uint32_t data) { volatile uint32_t *uncached_address = (uint32_t *)(pi_address | 0xa0000000); diff --git a/src/rdp.c b/src/rdp.c index 8f8054a0..a56eb669 100644 --- a/src/rdp.c +++ b/src/rdp.c @@ -87,10 +87,10 @@ typedef struct uint32_t width; /** @brief Height of the texture */ uint32_t height; - /** @brief Width of the texture rounded up to next power of 2 */ - uint16_t real_width; - /** @brief Height of the texture rounded up to next power of 2 */ - uint16_t real_height; + // /** @brief Width of the texture rounded up to next power of 2 */ + // uint16_t real_width; + // /** @brief Height of the texture rounded up to next power of 2 */ + // uint16_t real_height; } sprite_cache; extern uint32_t __bitdepth; @@ -412,14 +412,16 @@ void rdp_enable_primitive_fill( void ) } /** - * @brief Enable display of 2D filled (untextured) triangles + * @brief Enable display of 2D sprites * - * This must be called before using #rdp_draw_filled_triangle. + * This must be called before using #rdp_draw_textured_rectangle_scaled, + * #rdp_draw_textured_rectangle, #rdp_draw_sprite or #rdp_draw_sprite_scaled. */ -void rdp_enable_blend_fill( void ) +void rdp_enable_texture_copy( void ) { - __rdp_ringbuffer_queue( 0xEF0000FF ); - __rdp_ringbuffer_queue( 0x80000000 ); + /* Set other modes to copy and other defaults */ + __rdp_ringbuffer_queue( 0xEFA000FF ); + __rdp_ringbuffer_queue( 0x00004001 ); __rdp_ringbuffer_send(); } @@ -429,11 +431,11 @@ void rdp_enable_blend_fill( void ) * This must be called before using #rdp_draw_textured_rectangle_scaled, * #rdp_draw_textured_rectangle, #rdp_draw_sprite or #rdp_draw_sprite_scaled. */ -void rdp_enable_texture_copy( void ) +void rdp_enable_texture_copy_flags( uint32_t flags1, uint32_t flags2 ) { /* Set other modes to copy and other defaults */ - __rdp_ringbuffer_queue( 0xEFA000FF ); - __rdp_ringbuffer_queue( 0x00004001 ); + __rdp_ringbuffer_queue( flags1 ); + __rdp_ringbuffer_queue( flags2 ); __rdp_ringbuffer_send(); } @@ -492,7 +494,7 @@ static uint32_t __rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t /* Instruct the RDP to copy the sprite data out */ __rdp_ringbuffer_queue( 0xF5000000 | ((sprite->bitdepth == 2) ? 0x00100000 : 0x00180000) | (((((real_width / 8) + round_amount) * sprite->bitdepth) & 0x1FF) << 9) | ((texloc / 8) & 0x1FF) ); - __rdp_ringbuffer_queue( ((texslot & 0x7) << 24) | (mirror_enabled != MIRROR_DISABLED ? 0x40100 : 0) | (hbits << 14 ) | (wbits << 4) ); + __rdp_ringbuffer_queue( ((texslot & 0x7) << 24) | (mirror_enabled == MIRROR_ENABLED ? 0x40100 : 0) | (hbits << 14 ) | (wbits << 4) ); //__rdp_ringbuffer_queue( ((texslot & 0x7) << 24) | (mirror_enabled != MIRROR_DISABLED ? 0x40100 : 0) | (hbits << 14 ) | (wbits << 4) ); __rdp_ringbuffer_send(); /* Copying out only a chunk this time */ @@ -505,8 +507,8 @@ static uint32_t __rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t cache[texslot & 0x7].height = theight - 1; cache[texslot & 0x7].s = sl; cache[texslot & 0x7].t = tl; - cache[texslot & 0x7].real_width = real_width; - cache[texslot & 0x7].real_height = real_height; + // cache[texslot & 0x7].real_width = real_width; + // cache[texslot & 0x7].real_height = real_height; /* Return the amount of texture memory consumed by this texture */ return ((real_width / 8) + round_amount) * 8 * real_height * sprite->bitdepth; @@ -519,25 +521,25 @@ static uint32_t __rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t * The RDP texture slot to load this sprite into (0-7) * @param[in] texloc * The RDP TMEM offset to place the texture at - * @param[in] mirror + * @param[in] mirror_enabled //mirror * Whether the sprite should be mirrored when displaying past boundaries * @param[in] sprite * Pointer to sprite structure to load the texture from * * @return The number of bytes consumed in RDP TMEM by loading this sprite */ -uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite ) +uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite ) //uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite ) { if( !sprite ) { return 0; } - return __rdp_load_texture( texslot, texloc, mirror, sprite, 0, 0, sprite->width - 1, sprite->height - 1 ); + return __rdp_load_texture( texslot, texloc, mirror_enabled, sprite, 0, 0, sprite->width - 1, sprite->height - 1 ); //return __rdp_load_texture( texslot, texloc, mirror, sprite, 0, 0, sprite->width - 1, sprite->height - 1 ); } /** * @brief Load part of a sprite into RDP TMEM * * Given a sprite with vertical and horizontal slices defined, this function will load the slice specified in - * offset into texture memory. This is usefl for treating a large sprite as a tilemap. + * offset into texture memory. This is useful for treating a large sprite as a tilemap. * * Given a sprite with 3 horizontal slices and two vertical slices, the offsets are as follows: * @@ -553,7 +555,7 @@ uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, s * The RDP texture slot to load this sprite into (0-7) * @param[in] texloc * The RDP TMEM offset to place the texture at - * @param[in] mirror + * @param[in] mirror_enabled //mirror * Whether the sprite should be mirrored when displaying past boundaries * @param[in] sprite * Pointer to sprite structure to load the texture from @@ -562,7 +564,7 @@ uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, s * * @return The number of bytes consumed in RDP TMEM by loading this sprite */ -uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset ) +uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite, int offset ) //uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset ) { if( !sprite ) { return 0; } @@ -575,7 +577,7 @@ uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mi int sh = sl + twidth - 1; int th = tl + theight - 1; - return __rdp_load_texture( texslot, texloc, mirror, sprite, sl, tl, sh, th ); + return __rdp_load_texture( texslot, texloc, mirror_enabled, sprite, sl, tl, sh, th ); //return __rdp_load_texture( texslot, texloc, mirror, sprite, sl, tl, sh, th ); } /** @@ -603,40 +605,40 @@ uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mi * Horizontal scaling factor * @param[in] y_scale * Vertical scaling factor - * @param[in] mirror - * Whether the texture should be mirrored +// * * @param[in] mirror +// * Whether the texture should be mirrored */ -void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror) +void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale ) //void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror) { uint16_t s = cache[texslot & 0x7].s << 5; uint16_t t = cache[texslot & 0x7].t << 5; - uint32_t width = cache[texslot & 0x7].width; - uint32_t height = cache[texslot & 0x7].height; - + // uint32_t width = cache[texslot & 0x7].width; + // uint32_t height = cache[texslot & 0x7].height; + /* Cant display < 0, so must clip size and move S,T coord accordingly */ if( tx < 0 ) { - if ( tx < -width * x_scale) { return; } + //if ( tx < -width * x_scale) { return; } s += (int)(((double)((-tx) << 5)) * (1.0 / x_scale)); tx = 0; } if( ty < 0 ) { - if ( ty < -height * y_scale ) { return; } + //if ( ty < -height * y_scale ) { return; } t += (int)(((double)((-ty) << 5)) * (1.0 / y_scale)); ty = 0; } - // mirror horizontally or vertically - if (mirror != MIRROR_DISABLED) - { - if (mirror == MIRROR_X || mirror == MIRROR_XY) - s += ( (width+1) + ((cache[texslot & 0x7].real_width-(width+1))<<1) ) << 5; - - if (mirror == MIRROR_Y || mirror == MIRROR_XY) - t += ( (height+1) + ((cache[texslot & 0x7].real_height-(height+1))<<1) ) << 5; - } + // // mirror horizontally or vertically + // if (mirror != MIRROR_DISABLED) + // { + // if (mirror == MIRROR_X || mirror == MIRROR_XY) + // s += ( (width+1) + ((cache[texslot & 0x7].real_width-(width+1))<<1) ) << 5; + + // if (mirror == MIRROR_Y || mirror == MIRROR_XY) + // t += ( (height+1) + ((cache[texslot & 0x7].real_height-(height+1))<<1) ) << 5; + // } /* Calculate the scaling constants based on a 6.10 fixed point system */ int xs = (int)((1.0 / x_scale) * 4096.0); @@ -674,13 +676,13 @@ void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int b * The pixel X location of the bottom right of the rectangle * @param[in] by * The pixel Y location of the bottom right of the rectangle - * @param[in] mirror - * Whether the texture should be mirrored +// * @param[in] mirror +// * Whether the texture should be mirrored */ -void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ) +void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by ) //void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ) { /* Simple wrapper */ - rdp_draw_textured_rectangle_scaled( texslot, tx, ty, bx, by, 1.0, 1.0, mirror ); + rdp_draw_textured_rectangle_scaled( texslot, tx, ty, bx, by, 1.0, 1.0 ); //rdp_draw_textured_rectangle_scaled( texslot, tx, ty, bx, by, 1.0, 1.0, mirror ); } /** @@ -697,13 +699,13 @@ void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int * The pixel X location of the top left of the sprite * @param[in] y * The pixel Y location of the top left of the sprite - * @param[in] mirror - * Whether the texture should be mirrored +// * @param[in] mirror +// * Whether the texture should be mirrored */ -void rdp_draw_sprite( uint32_t texslot, int x, int y, mirror_t mirror ) +void rdp_draw_sprite( uint32_t texslot, int x, int y ) //void rdp_draw_sprite( uint32_t texslot, int x, int y, mirror_t mirror ) { /* Just draw a rectangle the size of the sprite */ - rdp_draw_textured_rectangle_scaled( texslot, x, y, x + cache[texslot & 0x7].width, y + cache[texslot & 0x7].height, 1.0, 1.0, mirror ); + rdp_draw_textured_rectangle_scaled( texslot, x, y, x + cache[texslot & 0x7].width, y + cache[texslot & 0x7].height, 1.0, 1.0 ); //rdp_draw_textured_rectangle_scaled( texslot, x, y, x + cache[texslot & 0x7].width, y + cache[texslot & 0x7].height, 1.0, 1.0, mirror ); } /** @@ -724,17 +726,17 @@ void rdp_draw_sprite( uint32_t texslot, int x, int y, mirror_t mirror ) * Horizontal scaling factor * @param[in] y_scale * Vertical scaling factor - * @param[in] mirror - * Whether the texture should be mirrored +// * @param[in] mirror +// * Whether the texture should be mirrored */ -void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror ) +void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale ) //void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror ) { /* Since we want to still view the whole sprite, we must resize the rectangle area too */ int new_width = (int)(((double)cache[texslot & 0x7].width * x_scale) + 0.5); int new_height = (int)(((double)cache[texslot & 0x7].height * y_scale) + 0.5); /* Draw a rectangle the size of the new sprite */ - rdp_draw_textured_rectangle_scaled( texslot, x, y, x + new_width, y + new_height, x_scale, y_scale, mirror ); + rdp_draw_textured_rectangle_scaled( texslot, x, y, x + new_width, y + new_height, x_scale, y_scale ); //rdp_draw_textured_rectangle_scaled( texslot, x, y, x + new_width, y + new_height, x_scale, y_scale, mirror ); } /** @@ -756,21 +758,6 @@ void rdp_set_primitive_color( uint32_t color ) __rdp_ringbuffer_send(); } -/** - * @brief Set the blend draw color for subsequent filled primitive operations - * - * This function sets the color of all #rdp_draw_filled_triangle operations that follow. - * - * @param[in] color - * Color to draw primitives in - */ -void rdp_set_blend_color( uint32_t color ) -{ - __rdp_ringbuffer_queue( 0xF9000000 ); - __rdp_ringbuffer_queue( color ); - __rdp_ringbuffer_send(); -} - /** * @brief Draw a filled rectangle * @@ -802,69 +789,6 @@ void rdp_draw_filled_rectangle( int tx, int ty, int bx, int by ) __rdp_ringbuffer_send(); } -/** - * @brief Draw a filled triangle - * - * Given a color set with #rdp_set_blend_color, this will draw a filled triangle - * to the screen. Vertex order is not important. - * - * Before calling this function, make sure that the RDP is set to blend mode by - * calling #rdp_enable_blend_fill. - * - * @param[in] x1 - * Pixel X1 location of triangle - * @param[in] y1 - * Pixel Y1 location of triangle - * @param[in] x2 - * Pixel X2 location of triangle - * @param[in] y2 - * Pixel Y2 location of triangle - * @param[in] x3 - * Pixel X3 location of triangle - * @param[in] y3 - * Pixel Y3 location of triangle - */ -void rdp_draw_filled_triangle( float x1, float y1, float x2, float y2, float x3, float y3 ) -{ - float temp_x, temp_y; - const float to_fixed_11_2 = 4.0f; - const float to_fixed_16_16 = 65536.0f; - - /* sort vertices by Y ascending to find the major, mid and low edges */ - if( y1 > y2 ) { temp_x = x2, temp_y = y2; y2 = y1; y1 = temp_y; x2 = x1; x1 = temp_x; } - if( y2 > y3 ) { temp_x = x3, temp_y = y3; y3 = y2; y2 = temp_y; x3 = x2; x2 = temp_x; } - if( y1 > y2 ) { temp_x = x2, temp_y = y2; y2 = y1; y1 = temp_y; x2 = x1; x1 = temp_x; } - - /* calculate Y edge coefficients in 11.2 fixed format */ - int yh = y1 * to_fixed_11_2; - int ym = (int)( y2 * to_fixed_11_2 ) << 16; // high word - int yl = y3 * to_fixed_11_2; - - /* calculate X edge coefficients in 16.16 fixed format */ - int xh = x1 * to_fixed_16_16; - int xm = x1 * to_fixed_16_16; - int xl = x2 * to_fixed_16_16; - - /* calculate inverse slopes in 16.16 fixed format */ - int dxhdy = ( y3 == y1 ) ? 0 : ( ( x3 - x1 ) / ( y3 - y1 ) ) * to_fixed_16_16; - int dxmdy = ( y2 == y1 ) ? 0 : ( ( x2 - x1 ) / ( y2 - y1 ) ) * to_fixed_16_16; - int dxldy = ( y3 == y2 ) ? 0 : ( ( x3 - x2 ) / ( y3 - y2 ) ) * to_fixed_16_16; - - /* determine the winding of the triangle */ - int winding = ( x1 * y2 - x2 * y1 ) + ( x2 * y3 - x3 * y2 ) + ( x3 * y1 - x1 * y3 ); - int flip = ( winding > 0 ? 1 : 0 ) << 23; - - __rdp_ringbuffer_queue( 0xC8000000 | flip | yl ); - __rdp_ringbuffer_queue( ym | yh ); - __rdp_ringbuffer_queue( xl ); - __rdp_ringbuffer_queue( dxldy ); - __rdp_ringbuffer_queue( xh ); - __rdp_ringbuffer_queue( dxhdy ); - __rdp_ringbuffer_queue( xm ); - __rdp_ringbuffer_queue( dxmdy ); - __rdp_ringbuffer_send(); -} - /** * @brief Set the flush strategy for texture loads * diff --git a/src/rsp.c b/src/rsp.c index 37ecb3b6..ad20bafb 100644 --- a/src/rsp.c +++ b/src/rsp.c @@ -1,146 +1,577 @@ /** * @file rsp.c - * @brief Hardware Vector Interface + * @brief Hardware Coprocessor Interface * @ingroup rsp */ +#include +#include +#include +#include #include "libdragon.h" -#include "regsinternal.h" -/** @brief SP DMA busy */ -#define SP_STATUS_DMA_BUSY ( 1 << 2 ) -/** @brief SP IO busy */ -#define SP_STATUS_IO_BUSY ( 1 << 4 ) -/** @brief SP broke */ -#define SP_STATUS_INTERRUPT_ON_BREAK ( 1 << 6 ) -/** @brief SP halted */ -#define SP_STATUS_HALTED ( 1 ) +/** + * @defgroup rsp Hardware Coprocessor Interface + * @ingroup libdragon + * @brief Interface to the hardware coprocessor (RSP). + * + * The hardware coprocessor interface sets up and talks with the RSP in order to perform + * parallel processing of data. The code executed by the RSP is loaded as a library of + * modules that fit within the 4KB of IMEM. Module functions are queued for execution + * as the RSP finishes previously queued functions (FIFO queue). + * + * Before attempting to queue any functions on the RSP, the hardware coprocessor interface + * should be initialized with #rsp_init. After the RSP is no longer needed, be sure + * to free all resources using #rsp_close. + * + * After the interface is initialized, the library should be loaded with #rsp_load_lib. + * The entry vectors for functions of a particular module can then be fetched using + * #rsp_lib_fn. The functions can then be used to create a job to perform on the RSP + * using #rsp_new_job. The job can be queued for execution with #rsp_queue_job, or + * #rsp_do_job, which also waits until the queued job is finished before returning. + * + * @{ + */ -#define SP_STATUS_CLEAR_HALT 0x00001 -#define SP_STATUS_SET_HALT 0x00002 -#define SP_STATUS_CLEAR_BROKE 0x00004 -#define SP_STATUS_CLEAR_INTR 0x00008 -#define SP_STATUS_SET_INTR 0x00010 -#define SP_STATUS_CLEAR_SSTEP 0x00020 -#define SP_STATUS_SET_SSTEP 0x00040 -#define SP_STATUS_CLEAR_INTR_BREAK 0x00080 -#define SP_STATUS_SET_INTR_BREAK 0x00100 -#define SP_STATUS_CLEAR_SIG0 0x00200 -#define SP_STATUS_SET_SIG0 0x00400 -#define SP_STATUS_CLEAR_SIG1 0x00800 -#define SP_STATUS_SET_SIG1 0x01000 -#define SP_STATUS_CLEAR_SIG2 0x02000 -#define SP_STATUS_SET_SIG2 0x04000 -#define SP_STATUS_CLEAR_SIG3 0x08000 -#define SP_STATUS_SET_SIG3 0x10000 -#define SP_STATUS_CLEAR_SIG4 0x20000 -#define SP_STATUS_SET_SIG4 0x40000 -#define SP_STATUS_CLEAR_SIG5 0x80000 -#define SP_STATUS_SET_SIG5 0x100000 -#define SP_STATUS_CLEAR_SIG6 0x200000 -#define SP_STATUS_SET_SIG6 0x400000 -#define SP_STATUS_CLEAR_SIG7 0x800000 -#define SP_STATUS_SET_SIG7 0x1000000 -#define SP_DMA_DMEM 0x04000000 -#define SP_DMA_IMEM 0x04001000 +job_queue_t jobQueue; -/** @brief Static structure to address SP registers */ -static volatile struct SP_regs_s * const SP_regs = (struct SP_regs_s *)0xa4040000; /** - * @brief Wait until the SI is finished with a DMA request + * @brief Add job to end of queue */ -static void __SP_DMA_wait(void) +static inline void ADD_TAIL( job_queue_t *q, job_t *j ) { - while (SP_regs->status & (SP_STATUS_DMA_BUSY | SP_STATUS_IO_BUSY)) ; + j->next = 0; + j->prev = q->tail; + q->tail = j; } -void rsp_init() +/** + * @brief Remove job from head of queue and return it + * + * @return Job from the head of queue. + */ +static inline job_t *REMOVE_HEAD( job_queue_t *q ) { - /* Make sure RSP is halted */ - *(volatile uint32_t *) 0xA4080000 = SP_DMA_IMEM; - SP_regs->status = SP_STATUS_SET_HALT; + job_t *j = q->head; + + if ( j ) + { + q->head = j->next; + if ( q->head ) + q->head->prev = NULL; + } + else + { + q->head = q->tail = NULL; + } - return; + return j; } -void load_ucode(void* start, unsigned long size) +/** + * @brief Remove job from queue + */ +static inline void REMOVE_NODE( job_queue_t *q, job_t *j ) { - disable_interrupts(); - __SP_DMA_wait(); + if ( q->head == j) + { + q->head = j->next; + if ( q->head ) + q->head->prev = NULL; + } + else if ( q->tail == j) + { + q->tail = j->prev; + if ( q->tail ) + q->tail->next = NULL; + } + else + { + j->next->prev = j->prev; + j->prev->next = j->next; + } +} - SP_regs->DRAM_addr = start; +/** + * @brief Lock access to RSP DMA + * + * @param[in] wait + * Wait until lock successful if set + * + * @return Non-zero if RSP already locked. Zero if successfully locked RSP. + */ +uint32_t __rsp_lock( uint32_t wait ) +{ + if ( wait ) + { + while ( ((uint32_t *)0xA4040000)[7] ) + MEMORY_BARRIER(); + return 0; + } + + return ((uint32_t *)0xA4040000)[7]; +} + +/** + * @brief Unlock access to RSP DMA + */ +void __rsp_unlock( ) +{ + ((uint32_t *)0xA4040000)[7] = 0; MEMORY_BARRIER(); - SP_regs->RSP_addr = (void*)SP_DMA_IMEM; +} + +/** + * @brief Wait for RSP DMA + * + * @param[in] busy + * Wait on DMA not busy (1), or not full (0) + */ +void __rsp_wait_dma( uint32_t busy ) +{ + if ( busy ) + while ( ((uint32_t *)0xA4040000)[6] ) + MEMORY_BARRIER(); // wait until not busy + else + while ( ((uint32_t *)0xA4040000)[5] ) + MEMORY_BARRIER(); // wait until not full +} + +/** + * @brief Set RSP DMA for read to D/IMEM from DRAM + * + * @param[in] offs + * Offset into D/IMEM (0x0000 to 0x1FFF - must be 8-byte aligned!) + * @param[in] src + * Address in DRAM of data (must be 8-byte aligned!) + * @param[in] len + * Length in bytes (max of 4KB) + */ +void __rsp_dma_read( uint32_t offs, void *src, uint32_t len ) +{ + ((uint32_t *)0xA4040000)[0] = offs & 0x1FFF; MEMORY_BARRIER(); - SP_regs->rsp_read_length = size - 1; + ((uint32_t *)0xA4040000)[1] = (uint32_t)src; MEMORY_BARRIER(); + ((uint32_t *)0xA4040000)[2] = (len - 1) & 0x0FFF; + MEMORY_BARRIER(); +} - __SP_DMA_wait(); - enable_interrupts(); - return; +/** + * @brief Set RSP DMA for write to DRAM from D/IMEM + * + * @param[in] offs + * Offset into D/IMEM (0x0000 to 0x1FFF - must be 8-byte aligned!) + * @param[in] dst + * Address in DRAM for data (must be 8-byte aligned!) + * @param[in] len + * Length in bytes (max of 4KB) + */ +void __rsp_dma_write( uint32_t offs, void *dst, uint32_t len ) +{ + ((uint32_t *)0xA4040000)[0] = offs & 0x1FFF; + MEMORY_BARRIER(); + ((uint32_t *)0xA4040000)[1] = (uint32_t)dst; + MEMORY_BARRIER(); + ((uint32_t *)0xA4040000)[3] = (len - 1) & 0x0FFF; + MEMORY_BARRIER(); } -void load_data(void* start, unsigned long size) +/** + * @brief Set RSP DMA for read block to D/IMEM from DRAM + * + * @param[in] offs + * Offset into D/IMEM (0x0000 to 0x1FFF - must be 8-byte aligned!) + * @param[in] src + * Address in DRAM of data (must be 8-byte aligned!) + * @param[in] pitch + * Number of total columns in pixels (max of 4096/bpp) + * @param[in] width + * Number of columns in pixels (max of 4096/bpp) + * @param[in] height + * Number of rows in lines (max of 256) + * @param[in] bpp + * Number of bytes per pixel (max of 4) + */ +void __rsp_blk_read( uint32_t offs, void *src, uint16_t pitch, uint16_t width, uint16_t height, uint16_t bpp ) { - disable_interrupts(); - __SP_DMA_wait(); + ((uint32_t *)0xA4040000)[0] = offs & 0x1FFF; + MEMORY_BARRIER(); + ((uint32_t *)0xA4040000)[1] = (uint32_t)src; + MEMORY_BARRIER(); + ((uint32_t *)0xA4040000)[2] = ((pitch-width)*bpp << 20) | ((height-1) << 12) | (width*bpp - 1); + MEMORY_BARRIER(); +} - SP_regs->DRAM_addr = start; +/** + * @brief Set RSP DMA for write block to DRAM from D/IMEM + * + * @param[in] offs + * Offset into D/IMEM (0x0000 to 0x1FFF - must be 8-byte aligned!) + * @param[in] dst + * Address in DRAM for data (must be 8-byte aligned!) + * @param[in] pitch + * Number of total columns in pixels (max of 4096/bpp) + * @param[in] width + * Number of columns in pixels (max of 4096/bpp) + * @param[in] height + * Number of rows in lines (max of 256) + * @param[in] bpp + * Number of bytes per pixel (max of 4) + */ +void __rsp_blk_write( uint32_t offs, void *dst, uint16_t pitch, uint16_t width, uint16_t height, uint16_t bpp ) +{ + ((uint32_t *)0xA4040000)[0] = offs & 0x1FFF; + MEMORY_BARRIER(); + ((uint32_t *)0xA4040000)[1] = (uint32_t)dst; + MEMORY_BARRIER(); + ((uint32_t *)0xA4040000)[3] = ((pitch-width)*bpp << 20) | ((height-1) << 12) | (width*bpp - 1); MEMORY_BARRIER(); - SP_regs->RSP_addr = (void*)SP_DMA_DMEM; +} + +/** + * @brief Return the status bits in the RSP + * + * @return RSP status bits. + */ +uint32_t __rsp_get_status( ) +{ + return ((uint32_t *)0xA4040000)[4]; +} + +/** + * @brief Set or clear the status bits in the RSP + * + * @param[in] flags + * A set of SET and CLR status bits + */ +void __rsp_set_status( uint32_t flags ) +{ + ((uint32_t *)0xA4040000)[4] = flags; MEMORY_BARRIER(); - SP_regs->rsp_read_length = size - 1; +} + +/** + * @brief Set RSP PC + * + * @param[in] pc + * Function entry point in IMEM + */ +void __rsp_set_pc( uint32_t pc ) +{ + *((uint32_t *)0xA4080000) = pc; MEMORY_BARRIER(); +} + +/** + * @brief RSP interrupt handler + * + * This interrupt is called when a the RSP executes a break instruction. This + * signifies the job being executed is finished or errored out. + */ +static void __rsp_interrupt() +{ + job_t *j; + + disable_interrupts(); + + /* set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ + __rsp_set_status(0x8E); + + j = REMOVE_HEAD(&jobQueue); + if ( j ) + { + j->state = JOB_STATE_FINISHED; + /* do callback of finished job (if any) */ + if ( j->cb ) + j->cb(j); + j->state = JOB_STATE_IDLE; + } + + j = jobQueue.head; + if ( j && j->fn ) + { + memcpy((void *)(0xA4001000 - 16*4), j->args, 16*4); // copy args to stack + __rsp_set_pc(j->fn); + /* clear HALT, SSTEP, and all signals, set INTERRUPT ON BREAK */ + __rsp_set_status(0xAAAB21); + /* set running flag */ + j->state = JOB_STATE_RUNNING; + } - __SP_DMA_wait(); enable_interrupts(); - return; } -void read_ucode(void* start, unsigned long size) + +/** + * @brief Initialize the RSP system + */ +void rsp_init( void ) +{ + /* Set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ + __rsp_set_status(0x8E); + + /* until until all RSP DMA done */ + __rsp_wait_dma( 1 ); + + /* Clear the job queue */ + jobQueue.head = 0; + jobQueue.tail = 0; + + /* Set up interrupt for RSP BROKE */ + register_SP_handler( __rsp_interrupt ); + set_SP_interrupt( 1 ); +} + +/** + * @brief Close the RSP system + */ +void rsp_close( void ) +{ + /* Set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ + __rsp_set_status(0x8E); + + /* wait until all RSP DMA done */ + __rsp_wait_dma( 1 ); + + /* Clear the job queue */ + jobQueue.head = 0; + jobQueue.tail = 0; + + set_SP_interrupt( 0 ); + unregister_SP_handler( __rsp_interrupt ); +} + +/** + * @brief Load RSP library to D/IMEM + * + * There's no need to lock the RSP DMA here since we've halted the RSP. + * The library must be 8KB long and in DRAM on an 8 byte alignment. + * + * @param[in] lib + * Pointer to library + */ +void rsp_load_lib( uint8_t *lib ) +{ + /* Set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ + __rsp_set_status(0x8E); + + /* wait until all RSP DMA done */ + __rsp_wait_dma( 1 ); + + /* Clear the job queue */ + jobQueue.head = 0; + jobQueue.tail = 0; + + /* transfer data segment to DMEM */ + __rsp_dma_read(0x0000, &lib[0], 0x1000); + /* wait unti RSP DMA not full */ + __rsp_wait_dma( 0 ); + /* transfer text segment to IMEM */ + __rsp_dma_read(0x1000, &lib[0x1000], 0x1000); + + /* wait until all RSP DMA done */ + __rsp_wait_dma( 1 ); +} + +/** + * @brief Return the vector of the function entry point in a module + * + * @param[in] mod + * Module name string + * @param[in] fn + * Index of function in module + * + * @return Vector for function in module inside IMEM. + */ +uint32_t rsp_lib_fn( char *mod, uint32_t fn ) +{ + uint32_t *p = (uint32_t *)0xA4001000; // module table at start of IMEM + uint32_t *f; + int i = 0; + + while ( p[i] ) + { + if ( !strcmp((char *)(0xA4000000 + p[i]), mod) ) + break; // found module + i += 2; + } + if ( !p[i] ) + return 0; // couldn't find module! + + f = (uint32_t *)(0xA4000000 + p[i + 1]); + return f[fn]; // no error checking on function index +} + +/** + * @brief Queue a job for the RSP + * + * @param[in] job + * Job for execution on the RSP + */ +void rsp_queue_job( job_t *job ) { + uint32_t s; + job_t *j; + disable_interrupts(); - __SP_DMA_wait(); - SP_regs->DRAM_addr = start; - MEMORY_BARRIER(); - SP_regs->RSP_addr = (void*)SP_DMA_IMEM; - MEMORY_BARRIER(); - SP_regs->rsp_write_length = size - 1; - MEMORY_BARRIER(); - __SP_DMA_wait(); - data_cache_hit_invalidate(start, size); + ADD_TAIL(&jobQueue, job); + job->state = JOB_STATE_QUEUED; + + /* check if RSP running */ + s = __rsp_get_status( ); + if ( s & 3 ) + { + /* RSP not running, start first job */ + j = jobQueue.head; + if (j && j->fn) + { + memcpy((void *)(0xA4001000 - 16*4), j->args, 16*4); // copy args to stack + __rsp_set_pc(j->fn); + /* clear HALT, SSTEP, and all signals, set INTERRUPT ON BREAK */ + __rsp_set_status(0xAAAB21); + /* set running flag */ + j->state = JOB_STATE_RUNNING; + } + } enable_interrupts(); - return; } +/** + * @brief Queue a job for the RSP and wait until it's done + * + * @param[in] job + * Job for execution on the RSP + */ +void rsp_do_job( job_t *job ) +{ + rsp_queue_job( job ); + while ( job->state != JOB_STATE_IDLE ) + MEMORY_BARRIER(); +} + +/** + * @brief Wait on a queued job for the RSP + * + * @param[in] job + * Job to wait on + */ +void rsp_wait_job( job_t *job ) +{ + while ( job->state != JOB_STATE_IDLE ) + MEMORY_BARRIER(); +} -void read_data(void* start, unsigned long size) +/** + * @brief Abort a queued job for the RSP + * + * @param[in] job + * Job to remove from queue + * + * The job may be running. If so, the RSP is forced to stop, the callback is + * ignored, and the next job is started. + */ +void rsp_abort_job( job_t *job ) { + uint32_t s; + disable_interrupts(); - __SP_DMA_wait(); - SP_regs->DRAM_addr = start; - MEMORY_BARRIER(); - SP_regs->RSP_addr = (void*)SP_DMA_DMEM; - MEMORY_BARRIER(); - SP_regs->rsp_write_length = size - 1; - MEMORY_BARRIER(); - __SP_DMA_wait(); - data_cache_hit_invalidate(start, size); + s = __rsp_get_status(); + __rsp_set_status(2); /* set HALT */ + + if ( job->state == JOB_STATE_QUEUED ) + { + REMOVE_NODE(&jobQueue, job); + + /* if RSP was running, clear HALT */ + if ( (s & 3) == 0 ) + __rsp_set_status(1); + } + else if ( job->state == JOB_STATE_RUNNING ) + { + job_t *j; + + /* set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ + __rsp_set_status(0x8E); + + j = REMOVE_HEAD(&jobQueue); + + /* start next job */ + j = jobQueue.head; + if ( j && j->fn ) + { + memcpy((void *)(0xA4001000 - 16*4), j->args, 16*4); // copy args to stack + __rsp_set_pc(j->fn); + /* clear HALT, SSTEP, and all signals, set INTERRUPT ON BREAK */ + __rsp_set_status(0xAAAB21); + /* set running flag */ + j->state = JOB_STATE_RUNNING; + } + } + else + { + /* if RSP was running, clear HALT */ + if ( (s & 3) == 0 ) + __rsp_set_status(1); + } enable_interrupts(); - return; + + job->state = JOB_STATE_IDLE; } +/** + * @brief Return a new job structure with fields filled in + * + * @param[in] fn + * Index of function in module + * @param[in] cb + * callback for the job + * @param[in] count + * number of args passed (max of 16) + * @param[in] ... + * arguments for the job (max of 16) + * + * @return New job with fields filled in, or NULL. + */ +job_t *rsp_new_job( uint32_t fn, void (*cb)(job_t *), uint32_t count, ... ) +{ + va_list opt; + job_t *j; + int i; + + j = (job_t *)malloc(sizeof(job_t)); + if ( j ) + { + memset(j, 0, sizeof(job_t)); + j->fn = fn; + j->cb = cb; + va_start(opt, count); + for ( i=0; iargs[i] = va_arg(opt, uint32_t); + va_end(opt); + } + + return j; +} -void run_ucode() +/** + * @brief Dispose of an existing job structure + * + * @param[in] job + * Job created by #rsp_new_job + * + * Job must not be currently queued or running. + */ +void rsp_dispose_job( job_t *job ) { - // set RSP program counter - *(volatile uint32_t *) 0xA4080000 = SP_DMA_IMEM; - SP_regs->status = SP_STATUS_CLEAR_HALT | SP_STATUS_SET_INTR_BREAK; - return; + free(job); } + + +/** @} */ diff --git a/src/system.c b/src/system.c index a7f2a8d5..4cfb0966 100644 --- a/src/system.c +++ b/src/system.c @@ -17,7 +17,7 @@ #undef errno -/** +/** * @defgroup system newlib Interface Hooks * @brief System hooks to provide low level threading and filesystem functionality to newlib. * @@ -43,7 +43,7 @@ * code if the file prefix matches, allowing code to make use of your filesystyem * without being rewritten. * - * For example, your filesystem provides libdragon an interface to access a + * For example, your filesystem provides libdragon an interface to access a * homebrew SD card interface. You register a filesystem with "sd:/" as the prefix * and then attempt to open "sd://directory/file.txt". The open callback for your * filesystem will be passed the file "/directory/file.txt". The file handle returned @@ -91,12 +91,12 @@ */ char *__env[1] = { 0 }; -/** +/** * @brief Environment variables */ char **environ = __env; -/** +/** * @brief Dummy declaration of timeval */ struct timeval; @@ -122,7 +122,7 @@ typedef struct /** @brief Filesystem prefix * * This controls what filesystem prefix should link to this filesystem - * (eg. 'rom:/' or 'cf:/') + * (eg. 'rom:/' or 'cf:/') */ char *prefix; /** @brief Filesystem callback pointers */ @@ -139,7 +139,7 @@ typedef struct { /** @brief Index into #filesystems */ int fs_mapping; - /** @brief The handle assigned to this open file as returned by the + /** @brief The handle assigned to this open file as returned by the * filesystem code called to handle the open operation. Will * be passed to all subsequent file operations on the file. */ void *handle; @@ -312,7 +312,7 @@ static int __get_new_handle() * Structure of callbacks for various functions in the filesystem. * If the registered filesystem doesn't support an operation, it * should leave the callback null. - * + * * @retval -1 if the parameters are invalid * @retval -2 if the prefix is already in use * @retval -3 if there are no more slots for filesystems @@ -321,10 +321,10 @@ static int __get_new_handle() int attach_filesystem( const char * const prefix, filesystem_t *filesystem ) { /* Sanity checking */ - if( !prefix || !filesystem ) - { + if( !prefix || !filesystem ) + { errno = EINVAL; - return -1; + return -1; } /* Make sure prefix is valid */ @@ -395,10 +395,10 @@ int attach_filesystem( const char * const prefix, filesystem_t *filesystem ) int detach_filesystem( const char * const prefix ) { /* Sanity checking */ - if( !prefix ) - { + if( !prefix ) + { errno = EINVAL; - return -1; + return -1; } for( int i = 0; i < MAX_FILESYSTEMS; i++ ) @@ -439,7 +439,7 @@ int detach_filesystem( const char * const prefix ) * * @param[in] fileno * File handle - * + * * @return Pointer to a filesystem callback structure or null if not found. */ static filesystem_t *__get_fs_pointer_by_handle( int fileno ) @@ -862,7 +862,7 @@ int open( char *file, int flags, int mode ) errno = ENOMEM; return -1; } - + void *ptr = fs->open( file + __strlen( filesystems[mapping].prefix ), flags ); if( ptr ) @@ -957,7 +957,7 @@ int read( int file, char *ptr, int len ) * Buffer to read the link into * @param[in] bufsize * Size of the buffer - * + * * @return 0 on success or a negative value on error. */ int readlink( const char *path, char *buf, size_t bufsize ) @@ -1217,7 +1217,7 @@ int dir_findfirst( const char * const path, dir_t *dir ) return -1; } - return fs->findfirst( (char *)path + + __strlen( filesystems[mapping].prefix ), dir ); + return fs->findfirst( (char *)path + __strlen( filesystems[mapping].prefix ), dir ); } /** From 94ccc58d2adca865882b799968f493dcfd8e9ca5 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 11:37:05 +0100 Subject: [PATCH 13/37] Reintroduce sprite mirroring --- include/rdp.h | 26 ++++++++--------- src/rdp.c | 80 +++++++++++++++++++++++++-------------------------- 2 files changed, 52 insertions(+), 54 deletions(-) diff --git a/include/rdp.h b/include/rdp.h index 8fcd68e5..016760b0 100644 --- a/include/rdp.h +++ b/include/rdp.h @@ -21,14 +21,12 @@ typedef enum { /** @brief Disable texture mirroring */ MIRROR_DISABLED, - /** @brief Enable texture mirroring */ //removed - MIRROR_ENABLED //removed - // /** @brief Enable texture mirroring on x axis */ - // MIRROR_X, - // /** @brief Enable texture mirroring on y axis */ - // MIRROR_Y, - // /** @brief Enable texture mirroring on both x & y axis */ - // MIRROR_XY + /** @brief Enable texture mirroring on x axis */ + MIRROR_X, + /** @brief Enable texture mirroring on y axis */ + MIRROR_Y, + /** @brief Enable texture mirroring on both x & y axis */ + MIRROR_XY } mirror_t; /** @@ -73,12 +71,12 @@ void rdp_enable_primitive_fill( void ); void rdp_enable_blend_fill( void ); void rdp_enable_texture_copy( void ); void rdp_enable_texture_copy_flags( uint32_t flags1, uint32_t flags2 ); -uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite ); //uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite ) -uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite, int offset ); //uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset ); -void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by ); //void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ); -void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale ); //void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror ); -void rdp_draw_sprite( uint32_t texslot, int x, int y ); //void rdp_draw_sprite( uint32_t texslot, int x, int y , mirror_t mirror); -void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale ); //void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror); +uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite ); +uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset ); +void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ); +void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror ); +void rdp_draw_sprite( uint32_t texslot, int x, int y , mirror_t mirror); +void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror); void rdp_set_primitive_color( uint32_t color ); void rdp_set_blend_color( uint32_t color ); void rdp_draw_filled_rectangle( int tx, int ty, int bx, int by ); diff --git a/src/rdp.c b/src/rdp.c index a56eb669..1370f231 100644 --- a/src/rdp.c +++ b/src/rdp.c @@ -87,10 +87,10 @@ typedef struct uint32_t width; /** @brief Height of the texture */ uint32_t height; - // /** @brief Width of the texture rounded up to next power of 2 */ - // uint16_t real_width; - // /** @brief Height of the texture rounded up to next power of 2 */ - // uint16_t real_height; + /** @brief Width of the texture rounded up to next power of 2 */ + uint16_t real_width; + /** @brief Height of the texture rounded up to next power of 2 */ + uint16_t real_height; } sprite_cache; extern uint32_t __bitdepth; @@ -494,7 +494,7 @@ static uint32_t __rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t /* Instruct the RDP to copy the sprite data out */ __rdp_ringbuffer_queue( 0xF5000000 | ((sprite->bitdepth == 2) ? 0x00100000 : 0x00180000) | (((((real_width / 8) + round_amount) * sprite->bitdepth) & 0x1FF) << 9) | ((texloc / 8) & 0x1FF) ); - __rdp_ringbuffer_queue( ((texslot & 0x7) << 24) | (mirror_enabled == MIRROR_ENABLED ? 0x40100 : 0) | (hbits << 14 ) | (wbits << 4) ); //__rdp_ringbuffer_queue( ((texslot & 0x7) << 24) | (mirror_enabled != MIRROR_DISABLED ? 0x40100 : 0) | (hbits << 14 ) | (wbits << 4) ); + __rdp_ringbuffer_queue( ((texslot & 0x7) << 24) | (mirror_enabled != MIRROR_DISABLED ? 0x40100 : 0) | (hbits << 14 ) | (wbits << 4) ); __rdp_ringbuffer_send(); /* Copying out only a chunk this time */ @@ -507,8 +507,8 @@ static uint32_t __rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t cache[texslot & 0x7].height = theight - 1; cache[texslot & 0x7].s = sl; cache[texslot & 0x7].t = tl; - // cache[texslot & 0x7].real_width = real_width; - // cache[texslot & 0x7].real_height = real_height; + cache[texslot & 0x7].real_width = real_width; + cache[texslot & 0x7].real_height = real_height; /* Return the amount of texture memory consumed by this texture */ return ((real_width / 8) + round_amount) * 8 * real_height * sprite->bitdepth; @@ -521,18 +521,18 @@ static uint32_t __rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t * The RDP texture slot to load this sprite into (0-7) * @param[in] texloc * The RDP TMEM offset to place the texture at - * @param[in] mirror_enabled //mirror + * @param[in] mirror * Whether the sprite should be mirrored when displaying past boundaries * @param[in] sprite * Pointer to sprite structure to load the texture from * * @return The number of bytes consumed in RDP TMEM by loading this sprite */ -uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite ) //uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite ) +uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite ) { if( !sprite ) { return 0; } - return __rdp_load_texture( texslot, texloc, mirror_enabled, sprite, 0, 0, sprite->width - 1, sprite->height - 1 ); //return __rdp_load_texture( texslot, texloc, mirror, sprite, 0, 0, sprite->width - 1, sprite->height - 1 ); + return __rdp_load_texture( texslot, texloc, mirror, sprite, 0, 0, sprite->width - 1, sprite->height - 1 ); } /** @@ -555,7 +555,7 @@ uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror_en * The RDP texture slot to load this sprite into (0-7) * @param[in] texloc * The RDP TMEM offset to place the texture at - * @param[in] mirror_enabled //mirror + * @param[in] mirror * Whether the sprite should be mirrored when displaying past boundaries * @param[in] sprite * Pointer to sprite structure to load the texture from @@ -564,7 +564,7 @@ uint32_t rdp_load_texture( uint32_t texslot, uint32_t texloc, mirror_t mirror_en * * @return The number of bytes consumed in RDP TMEM by loading this sprite */ -uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror_enabled, sprite_t *sprite, int offset ) //uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset ) +uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mirror, sprite_t *sprite, int offset ) { if( !sprite ) { return 0; } @@ -577,7 +577,7 @@ uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mi int sh = sl + twidth - 1; int th = tl + theight - 1; - return __rdp_load_texture( texslot, texloc, mirror_enabled, sprite, sl, tl, sh, th ); //return __rdp_load_texture( texslot, texloc, mirror, sprite, sl, tl, sh, th ); + return __rdp_load_texture( texslot, texloc, mirror, sprite, sl, tl, sh, th ); } /** @@ -605,40 +605,40 @@ uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mi * Horizontal scaling factor * @param[in] y_scale * Vertical scaling factor -// * * @param[in] mirror -// * Whether the texture should be mirrored + * * @param[in] mirror + * Whether the texture should be mirrored */ -void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale ) //void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror) +void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror) { uint16_t s = cache[texslot & 0x7].s << 5; uint16_t t = cache[texslot & 0x7].t << 5; - // uint32_t width = cache[texslot & 0x7].width; - // uint32_t height = cache[texslot & 0x7].height; + uint32_t width = cache[texslot & 0x7].width; + uint32_t height = cache[texslot & 0x7].height; /* Cant display < 0, so must clip size and move S,T coord accordingly */ if( tx < 0 ) { - //if ( tx < -width * x_scale) { return; } + if ( tx < -width * x_scale) { return; } s += (int)(((double)((-tx) << 5)) * (1.0 / x_scale)); tx = 0; } if( ty < 0 ) { - //if ( ty < -height * y_scale ) { return; } + if ( ty < -height * y_scale ) { return; } t += (int)(((double)((-ty) << 5)) * (1.0 / y_scale)); ty = 0; } - // // mirror horizontally or vertically - // if (mirror != MIRROR_DISABLED) - // { - // if (mirror == MIRROR_X || mirror == MIRROR_XY) - // s += ( (width+1) + ((cache[texslot & 0x7].real_width-(width+1))<<1) ) << 5; + // mirror horizontally or vertically + if (mirror != MIRROR_DISABLED) + { + if (mirror == MIRROR_X || mirror == MIRROR_XY) + s += ( (width+1) + ((cache[texslot & 0x7].real_width-(width+1))<<1) ) << 5; - // if (mirror == MIRROR_Y || mirror == MIRROR_XY) - // t += ( (height+1) + ((cache[texslot & 0x7].real_height-(height+1))<<1) ) << 5; - // } + if (mirror == MIRROR_Y || mirror == MIRROR_XY) + t += ( (height+1) + ((cache[texslot & 0x7].real_height-(height+1))<<1) ) << 5; + } /* Calculate the scaling constants based on a 6.10 fixed point system */ int xs = (int)((1.0 / x_scale) * 4096.0); @@ -676,13 +676,13 @@ void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int b * The pixel X location of the bottom right of the rectangle * @param[in] by * The pixel Y location of the bottom right of the rectangle -// * @param[in] mirror -// * Whether the texture should be mirrored + * @param[in] mirror + * Whether the texture should be mirrored */ -void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by ) //void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ) +void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ) { /* Simple wrapper */ - rdp_draw_textured_rectangle_scaled( texslot, tx, ty, bx, by, 1.0, 1.0 ); //rdp_draw_textured_rectangle_scaled( texslot, tx, ty, bx, by, 1.0, 1.0, mirror ); + rdp_draw_textured_rectangle_scaled( texslot, tx, ty, bx, by, 1.0, 1.0, mirror ); } /** @@ -699,13 +699,13 @@ void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int * The pixel X location of the top left of the sprite * @param[in] y * The pixel Y location of the top left of the sprite -// * @param[in] mirror -// * Whether the texture should be mirrored + * @param[in] mirror + * Whether the texture should be mirrored */ -void rdp_draw_sprite( uint32_t texslot, int x, int y ) //void rdp_draw_sprite( uint32_t texslot, int x, int y, mirror_t mirror ) +void rdp_draw_sprite( uint32_t texslot, int x, int y, mirror_t mirror ) { /* Just draw a rectangle the size of the sprite */ - rdp_draw_textured_rectangle_scaled( texslot, x, y, x + cache[texslot & 0x7].width, y + cache[texslot & 0x7].height, 1.0, 1.0 ); //rdp_draw_textured_rectangle_scaled( texslot, x, y, x + cache[texslot & 0x7].width, y + cache[texslot & 0x7].height, 1.0, 1.0, mirror ); + rdp_draw_textured_rectangle_scaled( texslot, x, y, x + cache[texslot & 0x7].width, y + cache[texslot & 0x7].height, 1.0, 1.0, mirror ); } /** @@ -726,17 +726,17 @@ void rdp_draw_sprite( uint32_t texslot, int x, int y ) //void rdp_draw_sprite( u * Horizontal scaling factor * @param[in] y_scale * Vertical scaling factor -// * @param[in] mirror -// * Whether the texture should be mirrored + * @param[in] mirror + * Whether the texture should be mirrored */ -void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale ) //void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror ) +void rdp_draw_sprite_scaled( uint32_t texslot, int x, int y, double x_scale, double y_scale, mirror_t mirror ) { /* Since we want to still view the whole sprite, we must resize the rectangle area too */ int new_width = (int)(((double)cache[texslot & 0x7].width * x_scale) + 0.5); int new_height = (int)(((double)cache[texslot & 0x7].height * y_scale) + 0.5); /* Draw a rectangle the size of the new sprite */ - rdp_draw_textured_rectangle_scaled( texslot, x, y, x + new_width, y + new_height, x_scale, y_scale ); //rdp_draw_textured_rectangle_scaled( texslot, x, y, x + new_width, y + new_height, x_scale, y_scale, mirror ); + rdp_draw_textured_rectangle_scaled( texslot, x, y, x + new_width, y + new_height, x_scale, y_scale, mirror ); } /** From 7355868f3d91fbcb9b5198766714360ad663e503 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 12:16:37 +0100 Subject: [PATCH 14/37] Fix sprite rendering when mirror disabled? --- src/rdp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/rdp.c b/src/rdp.c index 1370f231..9821367e 100644 --- a/src/rdp.c +++ b/src/rdp.c @@ -618,14 +618,20 @@ void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int b /* Cant display < 0, so must clip size and move S,T coord accordingly */ if( tx < 0 ) { - if ( tx < -width * x_scale) { return; } + if (mirror != MIRROR_DISABLED) + { + if ( tx < -width * x_scale) { return; } + } s += (int)(((double)((-tx) << 5)) * (1.0 / x_scale)); tx = 0; } if( ty < 0 ) { - if ( ty < -height * y_scale ) { return; } + if (mirror != MIRROR_DISABLED) + { + if ( ty < -height * y_scale ) { return; } + } t += (int)(((double)((-ty) << 5)) * (1.0 / y_scale)); ty = 0; } From db578eb0675f204c1929a5ebd4b8717e2fa13cff Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 12:34:06 +0100 Subject: [PATCH 15/37] Minor fixups --- src/audio.c | 3 ++- src/controller.c | 1 + src/rdp.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/audio.c b/src/audio.c index d7a3a6df..2c771190 100644 --- a/src/audio.c +++ b/src/audio.c @@ -198,7 +198,7 @@ static void audio_callback() * The frequency in Hz to play back samples at * @param[in] numbuffers * The number of buffers to allocate internally - * * @param[in] fill_buffer_callback + * @param[in] fill_buffer_callback * A function to be called when more sample data is needed */ void audio_init(const int frequency, int numbuffers) @@ -310,6 +310,7 @@ void audio_set_buffer_callback(audio_fill_buffer_callback fill_buffer_callback) void audio_close() { set_AI_interrupt(0); + unregister_AI_handler(audio_callback); unregister_AI_handler(_callback); if(buffers) diff --git a/src/controller.c b/src/controller.c index adfcd830..4cac7464 100755 --- a/src/controller.c +++ b/src/controller.c @@ -911,6 +911,7 @@ static bool __is_transfer_pak( int controller ) * * @retval #ACCESSORY_RUMBLEPAK The accessory connected is a rumblepak * @retval #ACCESSORY_MEMPAK The accessory connected is a mempak + * @retval #ACCESSORY_TRANSFERPAK The accessory connected is a transferpak * @retval #ACCESSORY_VRU The accessory connected is a VRU * @retval #ACCESSORY_NONE The accessory was not recognized */ diff --git a/src/rdp.c b/src/rdp.c index 9821367e..383e5861 100644 --- a/src/rdp.c +++ b/src/rdp.c @@ -605,7 +605,7 @@ uint32_t rdp_load_texture_stride( uint32_t texslot, uint32_t texloc, mirror_t mi * Horizontal scaling factor * @param[in] y_scale * Vertical scaling factor - * * @param[in] mirror + * @param[in] mirror * Whether the texture should be mirrored */ void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int bx, int by, double x_scale, double y_scale, mirror_t mirror) @@ -682,7 +682,7 @@ void rdp_draw_textured_rectangle_scaled( uint32_t texslot, int tx, int ty, int b * The pixel X location of the bottom right of the rectangle * @param[in] by * The pixel Y location of the bottom right of the rectangle - * @param[in] mirror + * @param[in] mirror * Whether the texture should be mirrored */ void rdp_draw_textured_rectangle( uint32_t texslot, int tx, int ty, int bx, int by, mirror_t mirror ) From 13ab9c3c83e28d52175cd80f5409a037eaf106da Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 12:36:46 +0100 Subject: [PATCH 16/37] revert RSP to official version for the moment (I dont think the changes were actually used) --- include/rsp.h | 76 +------ src/rsp.c | 615 ++++++++------------------------------------------ 2 files changed, 100 insertions(+), 591 deletions(-) diff --git a/include/rsp.h b/include/rsp.h index 918a22cc..b1026502 100644 --- a/include/rsp.h +++ b/include/rsp.h @@ -1,84 +1,24 @@ /** * @file rsp.h - * @brief Hardware Coprocessor Interface + * @brief Hardware Vector Interface * @ingroup rsp */ #ifndef __LIBDRAGON_RSP_H #define __LIBDRAGON_RSP_H -/** - * @addtogroup rsp - * @{ - */ - -/** - * @brief Internal Job structure - */ -typedef struct ijob { - struct ijob *prev; - struct ijob *next; - - void (*cb)(struct ijob *); - - volatile uint32_t state; - uint32_t fn; - uint32_t args[16]; - -} job_t; - -/** - * @brief Job states - */ -#define JOB_STATE_IDLE 0 -#define JOB_STATE_QUEUED 1 -#define JOB_STATE_RUNNING 2 -#define JOB_STATE_FINISHED 3 - -/** - * @brief Internal Job Queue structure - */ -typedef struct { - job_t *head; - job_t *tail; - -} job_queue_t; - -/** @} */ - #ifdef __cplusplus extern "C" { #endif -/** - * @brief Low Level Functions - */ -uint32_t __rsp_lock( uint32_t wait ); -void __rsp_unlock( void ); -void __rsp_wait_dma( uint32_t busy ); -void __rsp_dma_read( uint32_t offs, void *src, uint32_t len ); -void __rsp_dma_write( uint32_t offs, void *dst, uint32_t len ); -void __rsp_blk_read( uint32_t offs, void *src, uint16_t pitch, uint16_t width, uint16_t height, uint16_t bpp ); -void __rsp_blk_write( uint32_t offs, void *dst, uint16_t pitch, uint16_t width, uint16_t height, uint16_t bpp ); -uint32_t __rsp_get_status( void ); -void __rsp_set_status( uint32_t flags ); -void __rsp_set_pc( uint32_t pc ); - -/** - * @brief High Level Functions - */ -void rsp_init( void ); -void rsp_close( void ); -void rsp_load_lib( uint8_t *lib ); -uint32_t rsp_lib_fn( char *mod, uint32_t fn ); -void rsp_queue_job( job_t *job ); -void rsp_do_job( job_t *job ); -void rsp_wait_job( job_t *job ); -void rsp_abort_job( job_t *job ); -job_t *rsp_new_job( uint32_t fn, void (*cb)(job_t *), uint32_t count, ... ); -void rsp_dispose_job( job_t *job ); +void rsp_init(); +void load_ucode(void * start, unsigned long size); +void read_ucode(void* start, unsigned long size); +void load_data(void * start, unsigned long size); +void read_data(void* start, unsigned long size); +void run_ucode(); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/src/rsp.c b/src/rsp.c index ad20bafb..cf44bae5 100644 --- a/src/rsp.c +++ b/src/rsp.c @@ -1,577 +1,146 @@ /** * @file rsp.c - * @brief Hardware Coprocessor Interface + * @brief Hardware Vector Interface * @ingroup rsp */ -#include -#include -#include -#include #include "libdragon.h" +#include "regsinternal.h" -/** - * @defgroup rsp Hardware Coprocessor Interface - * @ingroup libdragon - * @brief Interface to the hardware coprocessor (RSP). - * - * The hardware coprocessor interface sets up and talks with the RSP in order to perform - * parallel processing of data. The code executed by the RSP is loaded as a library of - * modules that fit within the 4KB of IMEM. Module functions are queued for execution - * as the RSP finishes previously queued functions (FIFO queue). - * - * Before attempting to queue any functions on the RSP, the hardware coprocessor interface - * should be initialized with #rsp_init. After the RSP is no longer needed, be sure - * to free all resources using #rsp_close. - * - * After the interface is initialized, the library should be loaded with #rsp_load_lib. - * The entry vectors for functions of a particular module can then be fetched using - * #rsp_lib_fn. The functions can then be used to create a job to perform on the RSP - * using #rsp_new_job. The job can be queued for execution with #rsp_queue_job, or - * #rsp_do_job, which also waits until the queued job is finished before returning. - * - * @{ - */ +/** @brief SP DMA busy */ +#define SP_STATUS_DMA_BUSY ( 1 << 2 ) +/** @brief SP IO busy */ +#define SP_STATUS_IO_BUSY ( 1 << 4 ) +/** @brief SP broke */ +#define SP_STATUS_INTERRUPT_ON_BREAK ( 1 << 6 ) +/** @brief SP halted */ +#define SP_STATUS_HALTED ( 1 ) +#define SP_STATUS_CLEAR_HALT 0x00001 +#define SP_STATUS_SET_HALT 0x00002 +#define SP_STATUS_CLEAR_BROKE 0x00004 +#define SP_STATUS_CLEAR_INTR 0x00008 +#define SP_STATUS_SET_INTR 0x00010 +#define SP_STATUS_CLEAR_SSTEP 0x00020 +#define SP_STATUS_SET_SSTEP 0x00040 +#define SP_STATUS_CLEAR_INTR_BREAK 0x00080 +#define SP_STATUS_SET_INTR_BREAK 0x00100 +#define SP_STATUS_CLEAR_SIG0 0x00200 +#define SP_STATUS_SET_SIG0 0x00400 +#define SP_STATUS_CLEAR_SIG1 0x00800 +#define SP_STATUS_SET_SIG1 0x01000 +#define SP_STATUS_CLEAR_SIG2 0x02000 +#define SP_STATUS_SET_SIG2 0x04000 +#define SP_STATUS_CLEAR_SIG3 0x08000 +#define SP_STATUS_SET_SIG3 0x10000 +#define SP_STATUS_CLEAR_SIG4 0x20000 +#define SP_STATUS_SET_SIG4 0x40000 +#define SP_STATUS_CLEAR_SIG5 0x80000 +#define SP_STATUS_SET_SIG5 0x100000 +#define SP_STATUS_CLEAR_SIG6 0x200000 +#define SP_STATUS_SET_SIG6 0x400000 +#define SP_STATUS_CLEAR_SIG7 0x800000 +#define SP_STATUS_SET_SIG7 0x1000000 -job_queue_t jobQueue; +#define SP_DMA_DMEM 0x04000000 +#define SP_DMA_IMEM 0x04001000 +/** @brief Static structure to address SP registers */ +static volatile struct SP_regs_s * const SP_regs = (struct SP_regs_s *)0xa4040000; /** - * @brief Add job to end of queue + * @brief Wait until the SI is finished with a DMA request */ -static inline void ADD_TAIL( job_queue_t *q, job_t *j ) +static void __SP_DMA_wait(void) { - j->next = 0; - j->prev = q->tail; - q->tail = j; + while (SP_regs->status & (SP_STATUS_DMA_BUSY | SP_STATUS_IO_BUSY)) ; } -/** - * @brief Remove job from head of queue and return it - * - * @return Job from the head of queue. - */ -static inline job_t *REMOVE_HEAD( job_queue_t *q ) +void rsp_init() { - job_t *j = q->head; - - if ( j ) - { - q->head = j->next; - if ( q->head ) - q->head->prev = NULL; - } - else - { - q->head = q->tail = NULL; - } + /* Make sure RSP is halted */ + *(volatile uint32_t *) 0xA4080000 = SP_DMA_IMEM; + SP_regs->status = SP_STATUS_SET_HALT; - return j; + return; } -/** - * @brief Remove job from queue - */ -static inline void REMOVE_NODE( job_queue_t *q, job_t *j ) +void load_ucode(void* start, unsigned long size) { - if ( q->head == j) - { - q->head = j->next; - if ( q->head ) - q->head->prev = NULL; - } - else if ( q->tail == j) - { - q->tail = j->prev; - if ( q->tail ) - q->tail->next = NULL; - } - else - { - j->next->prev = j->prev; - j->prev->next = j->next; - } -} - -/** - * @brief Lock access to RSP DMA - * - * @param[in] wait - * Wait until lock successful if set - * - * @return Non-zero if RSP already locked. Zero if successfully locked RSP. - */ -uint32_t __rsp_lock( uint32_t wait ) -{ - if ( wait ) - { - while ( ((uint32_t *)0xA4040000)[7] ) - MEMORY_BARRIER(); - return 0; - } - - return ((uint32_t *)0xA4040000)[7]; -} - -/** - * @brief Unlock access to RSP DMA - */ -void __rsp_unlock( ) -{ - ((uint32_t *)0xA4040000)[7] = 0; - MEMORY_BARRIER(); -} - -/** - * @brief Wait for RSP DMA - * - * @param[in] busy - * Wait on DMA not busy (1), or not full (0) - */ -void __rsp_wait_dma( uint32_t busy ) -{ - if ( busy ) - while ( ((uint32_t *)0xA4040000)[6] ) - MEMORY_BARRIER(); // wait until not busy - else - while ( ((uint32_t *)0xA4040000)[5] ) - MEMORY_BARRIER(); // wait until not full -} + disable_interrupts(); + __SP_DMA_wait(); -/** - * @brief Set RSP DMA for read to D/IMEM from DRAM - * - * @param[in] offs - * Offset into D/IMEM (0x0000 to 0x1FFF - must be 8-byte aligned!) - * @param[in] src - * Address in DRAM of data (must be 8-byte aligned!) - * @param[in] len - * Length in bytes (max of 4KB) - */ -void __rsp_dma_read( uint32_t offs, void *src, uint32_t len ) -{ - ((uint32_t *)0xA4040000)[0] = offs & 0x1FFF; + SP_regs->DRAM_addr = start; MEMORY_BARRIER(); - ((uint32_t *)0xA4040000)[1] = (uint32_t)src; + SP_regs->RSP_addr = (void*)SP_DMA_IMEM; MEMORY_BARRIER(); - ((uint32_t *)0xA4040000)[2] = (len - 1) & 0x0FFF; + SP_regs->rsp_read_length = size - 1; MEMORY_BARRIER(); -} -/** - * @brief Set RSP DMA for write to DRAM from D/IMEM - * - * @param[in] offs - * Offset into D/IMEM (0x0000 to 0x1FFF - must be 8-byte aligned!) - * @param[in] dst - * Address in DRAM for data (must be 8-byte aligned!) - * @param[in] len - * Length in bytes (max of 4KB) - */ -void __rsp_dma_write( uint32_t offs, void *dst, uint32_t len ) -{ - ((uint32_t *)0xA4040000)[0] = offs & 0x1FFF; - MEMORY_BARRIER(); - ((uint32_t *)0xA4040000)[1] = (uint32_t)dst; - MEMORY_BARRIER(); - ((uint32_t *)0xA4040000)[3] = (len - 1) & 0x0FFF; - MEMORY_BARRIER(); + __SP_DMA_wait(); + enable_interrupts(); + return; } -/** - * @brief Set RSP DMA for read block to D/IMEM from DRAM - * - * @param[in] offs - * Offset into D/IMEM (0x0000 to 0x1FFF - must be 8-byte aligned!) - * @param[in] src - * Address in DRAM of data (must be 8-byte aligned!) - * @param[in] pitch - * Number of total columns in pixels (max of 4096/bpp) - * @param[in] width - * Number of columns in pixels (max of 4096/bpp) - * @param[in] height - * Number of rows in lines (max of 256) - * @param[in] bpp - * Number of bytes per pixel (max of 4) - */ -void __rsp_blk_read( uint32_t offs, void *src, uint16_t pitch, uint16_t width, uint16_t height, uint16_t bpp ) +void load_data(void* start, unsigned long size) { - ((uint32_t *)0xA4040000)[0] = offs & 0x1FFF; - MEMORY_BARRIER(); - ((uint32_t *)0xA4040000)[1] = (uint32_t)src; - MEMORY_BARRIER(); - ((uint32_t *)0xA4040000)[2] = ((pitch-width)*bpp << 20) | ((height-1) << 12) | (width*bpp - 1); - MEMORY_BARRIER(); -} + disable_interrupts(); + __SP_DMA_wait(); -/** - * @brief Set RSP DMA for write block to DRAM from D/IMEM - * - * @param[in] offs - * Offset into D/IMEM (0x0000 to 0x1FFF - must be 8-byte aligned!) - * @param[in] dst - * Address in DRAM for data (must be 8-byte aligned!) - * @param[in] pitch - * Number of total columns in pixels (max of 4096/bpp) - * @param[in] width - * Number of columns in pixels (max of 4096/bpp) - * @param[in] height - * Number of rows in lines (max of 256) - * @param[in] bpp - * Number of bytes per pixel (max of 4) - */ -void __rsp_blk_write( uint32_t offs, void *dst, uint16_t pitch, uint16_t width, uint16_t height, uint16_t bpp ) -{ - ((uint32_t *)0xA4040000)[0] = offs & 0x1FFF; - MEMORY_BARRIER(); - ((uint32_t *)0xA4040000)[1] = (uint32_t)dst; - MEMORY_BARRIER(); - ((uint32_t *)0xA4040000)[3] = ((pitch-width)*bpp << 20) | ((height-1) << 12) | (width*bpp - 1); + SP_regs->DRAM_addr = start; MEMORY_BARRIER(); -} - -/** - * @brief Return the status bits in the RSP - * - * @return RSP status bits. - */ -uint32_t __rsp_get_status( ) -{ - return ((uint32_t *)0xA4040000)[4]; -} - -/** - * @brief Set or clear the status bits in the RSP - * - * @param[in] flags - * A set of SET and CLR status bits - */ -void __rsp_set_status( uint32_t flags ) -{ - ((uint32_t *)0xA4040000)[4] = flags; + SP_regs->RSP_addr = (void*)SP_DMA_DMEM; MEMORY_BARRIER(); -} - -/** - * @brief Set RSP PC - * - * @param[in] pc - * Function entry point in IMEM - */ -void __rsp_set_pc( uint32_t pc ) -{ - *((uint32_t *)0xA4080000) = pc; + SP_regs->rsp_read_length = size - 1; MEMORY_BARRIER(); -} - -/** - * @brief RSP interrupt handler - * - * This interrupt is called when a the RSP executes a break instruction. This - * signifies the job being executed is finished or errored out. - */ -static void __rsp_interrupt() -{ - job_t *j; - - disable_interrupts(); - - /* set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ - __rsp_set_status(0x8E); - - j = REMOVE_HEAD(&jobQueue); - if ( j ) - { - j->state = JOB_STATE_FINISHED; - /* do callback of finished job (if any) */ - if ( j->cb ) - j->cb(j); - j->state = JOB_STATE_IDLE; - } - - j = jobQueue.head; - if ( j && j->fn ) - { - memcpy((void *)(0xA4001000 - 16*4), j->args, 16*4); // copy args to stack - __rsp_set_pc(j->fn); - /* clear HALT, SSTEP, and all signals, set INTERRUPT ON BREAK */ - __rsp_set_status(0xAAAB21); - /* set running flag */ - j->state = JOB_STATE_RUNNING; - } + __SP_DMA_wait(); enable_interrupts(); + return; } - -/** - * @brief Initialize the RSP system - */ -void rsp_init( void ) +void read_ucode(void* start, unsigned long size) { - /* Set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ - __rsp_set_status(0x8E); - - /* until until all RSP DMA done */ - __rsp_wait_dma( 1 ); - - /* Clear the job queue */ - jobQueue.head = 0; - jobQueue.tail = 0; - - /* Set up interrupt for RSP BROKE */ - register_SP_handler( __rsp_interrupt ); - set_SP_interrupt( 1 ); -} - -/** - * @brief Close the RSP system - */ -void rsp_close( void ) -{ - /* Set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ - __rsp_set_status(0x8E); - - /* wait until all RSP DMA done */ - __rsp_wait_dma( 1 ); - - /* Clear the job queue */ - jobQueue.head = 0; - jobQueue.tail = 0; - - set_SP_interrupt( 0 ); - unregister_SP_handler( __rsp_interrupt ); -} - -/** - * @brief Load RSP library to D/IMEM - * - * There's no need to lock the RSP DMA here since we've halted the RSP. - * The library must be 8KB long and in DRAM on an 8 byte alignment. - * - * @param[in] lib - * Pointer to library - */ -void rsp_load_lib( uint8_t *lib ) -{ - /* Set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ - __rsp_set_status(0x8E); - - /* wait until all RSP DMA done */ - __rsp_wait_dma( 1 ); - - /* Clear the job queue */ - jobQueue.head = 0; - jobQueue.tail = 0; - - /* transfer data segment to DMEM */ - __rsp_dma_read(0x0000, &lib[0], 0x1000); - /* wait unti RSP DMA not full */ - __rsp_wait_dma( 0 ); - /* transfer text segment to IMEM */ - __rsp_dma_read(0x1000, &lib[0x1000], 0x1000); - - /* wait until all RSP DMA done */ - __rsp_wait_dma( 1 ); -} - -/** - * @brief Return the vector of the function entry point in a module - * - * @param[in] mod - * Module name string - * @param[in] fn - * Index of function in module - * - * @return Vector for function in module inside IMEM. - */ -uint32_t rsp_lib_fn( char *mod, uint32_t fn ) -{ - uint32_t *p = (uint32_t *)0xA4001000; // module table at start of IMEM - uint32_t *f; - int i = 0; - - while ( p[i] ) - { - if ( !strcmp((char *)(0xA4000000 + p[i]), mod) ) - break; // found module - i += 2; - } - if ( !p[i] ) - return 0; // couldn't find module! - - f = (uint32_t *)(0xA4000000 + p[i + 1]); - return f[fn]; // no error checking on function index -} - -/** - * @brief Queue a job for the RSP - * - * @param[in] job - * Job for execution on the RSP - */ -void rsp_queue_job( job_t *job ) -{ - uint32_t s; - job_t *j; - disable_interrupts(); + __SP_DMA_wait(); - ADD_TAIL(&jobQueue, job); - job->state = JOB_STATE_QUEUED; - - /* check if RSP running */ - s = __rsp_get_status( ); - if ( s & 3 ) - { - /* RSP not running, start first job */ - j = jobQueue.head; - if (j && j->fn) - { - memcpy((void *)(0xA4001000 - 16*4), j->args, 16*4); // copy args to stack - __rsp_set_pc(j->fn); - /* clear HALT, SSTEP, and all signals, set INTERRUPT ON BREAK */ - __rsp_set_status(0xAAAB21); - /* set running flag */ - j->state = JOB_STATE_RUNNING; - } - } + SP_regs->DRAM_addr = start; + MEMORY_BARRIER(); + SP_regs->RSP_addr = (void*)SP_DMA_IMEM; + MEMORY_BARRIER(); + SP_regs->rsp_write_length = size - 1; + MEMORY_BARRIER(); + __SP_DMA_wait(); + data_cache_hit_invalidate(start, size); enable_interrupts(); + return; } -/** - * @brief Queue a job for the RSP and wait until it's done - * - * @param[in] job - * Job for execution on the RSP - */ -void rsp_do_job( job_t *job ) -{ - rsp_queue_job( job ); - while ( job->state != JOB_STATE_IDLE ) - MEMORY_BARRIER(); -} - -/** - * @brief Wait on a queued job for the RSP - * - * @param[in] job - * Job to wait on - */ -void rsp_wait_job( job_t *job ) -{ - while ( job->state != JOB_STATE_IDLE ) - MEMORY_BARRIER(); -} -/** - * @brief Abort a queued job for the RSP - * - * @param[in] job - * Job to remove from queue - * - * The job may be running. If so, the RSP is forced to stop, the callback is - * ignored, and the next job is started. - */ -void rsp_abort_job( job_t *job ) +void read_data(void* start, unsigned long size) { - uint32_t s; - disable_interrupts(); + __SP_DMA_wait(); - s = __rsp_get_status(); - __rsp_set_status(2); /* set HALT */ - - if ( job->state == JOB_STATE_QUEUED ) - { - REMOVE_NODE(&jobQueue, job); - - /* if RSP was running, clear HALT */ - if ( (s & 3) == 0 ) - __rsp_set_status(1); - } - else if ( job->state == JOB_STATE_RUNNING ) - { - job_t *j; - - /* set HALT, clear BROKE, RSP interrupt, and INTERRUPT ON BREAK */ - __rsp_set_status(0x8E); - - j = REMOVE_HEAD(&jobQueue); - - /* start next job */ - j = jobQueue.head; - if ( j && j->fn ) - { - memcpy((void *)(0xA4001000 - 16*4), j->args, 16*4); // copy args to stack - __rsp_set_pc(j->fn); - /* clear HALT, SSTEP, and all signals, set INTERRUPT ON BREAK */ - __rsp_set_status(0xAAAB21); - /* set running flag */ - j->state = JOB_STATE_RUNNING; - } - } - else - { - /* if RSP was running, clear HALT */ - if ( (s & 3) == 0 ) - __rsp_set_status(1); - } + SP_regs->DRAM_addr = start; + MEMORY_BARRIER(); + SP_regs->RSP_addr = (void*)SP_DMA_DMEM; + MEMORY_BARRIER(); + SP_regs->rsp_write_length = size - 1; + MEMORY_BARRIER(); + __SP_DMA_wait(); + data_cache_hit_invalidate(start, size); enable_interrupts(); - - job->state = JOB_STATE_IDLE; + return; } -/** - * @brief Return a new job structure with fields filled in - * - * @param[in] fn - * Index of function in module - * @param[in] cb - * callback for the job - * @param[in] count - * number of args passed (max of 16) - * @param[in] ... - * arguments for the job (max of 16) - * - * @return New job with fields filled in, or NULL. - */ -job_t *rsp_new_job( uint32_t fn, void (*cb)(job_t *), uint32_t count, ... ) -{ - va_list opt; - job_t *j; - int i; - - j = (job_t *)malloc(sizeof(job_t)); - if ( j ) - { - memset(j, 0, sizeof(job_t)); - j->fn = fn; - j->cb = cb; - va_start(opt, count); - for ( i=0; iargs[i] = va_arg(opt, uint32_t); - va_end(opt); - } - return j; -} - -/** - * @brief Dispose of an existing job structure - * - * @param[in] job - * Job created by #rsp_new_job - * - * Job must not be currently queued or running. - */ -void rsp_dispose_job( job_t *job ) +void run_ucode() { - free(job); -} - - -/** @} */ + // set RSP program counter + *(volatile uint32_t *) 0xA4080000 = SP_DMA_IMEM; + SP_regs->status = SP_STATUS_CLEAR_HALT | SP_STATUS_SET_INTR_BREAK; + return; +} \ No newline at end of file From 558a476f68e78d8c20288b9a921d6664c0ecbdc6 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 12:47:10 +0100 Subject: [PATCH 17/37] Revert whitespace changes in system.c It makes it too difficult to see what has actually changed. --- src/system.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/system.c b/src/system.c index 4cfb0966..b6f7f020 100644 --- a/src/system.c +++ b/src/system.c @@ -17,7 +17,7 @@ #undef errno -/** +/** * @defgroup system newlib Interface Hooks * @brief System hooks to provide low level threading and filesystem functionality to newlib. * @@ -43,7 +43,7 @@ * code if the file prefix matches, allowing code to make use of your filesystyem * without being rewritten. * - * For example, your filesystem provides libdragon an interface to access a + * For example, your filesystem provides libdragon an interface to access a * homebrew SD card interface. You register a filesystem with "sd:/" as the prefix * and then attempt to open "sd://directory/file.txt". The open callback for your * filesystem will be passed the file "/directory/file.txt". The file handle returned @@ -91,20 +91,20 @@ */ char *__env[1] = { 0 }; -/** +/** * @brief Environment variables */ char **environ = __env; -/** +/** * @brief Dummy declaration of timeval */ struct timeval; /** - * @brief Master definition of errno + * @brief Definition of errno, as it's defined as extern across stdlib */ -extern int errno; +int errno; /* Externs from libdragon */ extern int __bootcic; @@ -122,7 +122,7 @@ typedef struct /** @brief Filesystem prefix * * This controls what filesystem prefix should link to this filesystem - * (eg. 'rom:/' or 'cf:/') + * (eg. 'rom:/' or 'cf:/') */ char *prefix; /** @brief Filesystem callback pointers */ @@ -139,7 +139,7 @@ typedef struct { /** @brief Index into #filesystems */ int fs_mapping; - /** @brief The handle assigned to this open file as returned by the + /** @brief The handle assigned to this open file as returned by the * filesystem code called to handle the open operation. Will * be passed to all subsequent file operations on the file. */ void *handle; @@ -312,7 +312,7 @@ static int __get_new_handle() * Structure of callbacks for various functions in the filesystem. * If the registered filesystem doesn't support an operation, it * should leave the callback null. - * + * * @retval -1 if the parameters are invalid * @retval -2 if the prefix is already in use * @retval -3 if there are no more slots for filesystems @@ -321,10 +321,10 @@ static int __get_new_handle() int attach_filesystem( const char * const prefix, filesystem_t *filesystem ) { /* Sanity checking */ - if( !prefix || !filesystem ) - { + if( !prefix || !filesystem ) + { errno = EINVAL; - return -1; + return -1; } /* Make sure prefix is valid */ @@ -395,10 +395,10 @@ int attach_filesystem( const char * const prefix, filesystem_t *filesystem ) int detach_filesystem( const char * const prefix ) { /* Sanity checking */ - if( !prefix ) - { + if( !prefix ) + { errno = EINVAL; - return -1; + return -1; } for( int i = 0; i < MAX_FILESYSTEMS; i++ ) @@ -439,7 +439,7 @@ int detach_filesystem( const char * const prefix ) * * @param[in] fileno * File handle - * + * * @return Pointer to a filesystem callback structure or null if not found. */ static filesystem_t *__get_fs_pointer_by_handle( int fileno ) @@ -862,7 +862,7 @@ int open( char *file, int flags, int mode ) errno = ENOMEM; return -1; } - + void *ptr = fs->open( file + __strlen( filesystems[mapping].prefix ), flags ); if( ptr ) @@ -957,7 +957,7 @@ int read( int file, char *ptr, int len ) * Buffer to read the link into * @param[in] bufsize * Size of the buffer - * + * * @return 0 on success or a negative value on error. */ int readlink( const char *path, char *buf, size_t bufsize ) @@ -1295,4 +1295,4 @@ int unhook_stdio_calls() return 0; } -/** @} */ +/** @} */ \ No newline at end of file From d15093d4432d23a7eca0c461e35085eb81615a48 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 13:33:07 +0100 Subject: [PATCH 18/37] correct xscale --- src/display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/display.c b/src/display.c index 569c6a4d..c0981bd8 100644 --- a/src/display.c +++ b/src/display.c @@ -299,7 +299,7 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu __registers[1] = 512; /* base offset for field 1 */ __registers[1 + REGISTER_COUNT] = 1024; /* base offset for field 2 */ //TODO: probably wrong __registers[2] = 512; /* width */ - __registers[12] = 0x00000334; /* x-scale */ //TODO: probably wrong + __registers[12] = 0x00000333; /* x-scale */ break; case RESOLUTION_640x240: /* high-res progressive */ __width = 640; @@ -307,7 +307,7 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu __registers[1] = 640; /* base offset for field 1 */ __registers[1 + REGISTER_COUNT] = 1280; /* base offset for field 2 */ //TODO: probably wrong __registers[2] = 640; /* width */ - __registers[12] = 0x00000400; /* x-scale */ //TODO: probably wrong + __registers[12] = 0x00000400; /* x-scale */ break; } if ( bit == DEPTH_16_BPP ) @@ -345,7 +345,7 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu __registers[11 + REGISTER_COUNT] = 0x000D0269; /* vburst for field 2 */ __registers[13] = 0x02000800; /* y-scale */ } - else + else //TODO: something here for high res non-interlaced (i.e.512x240) { /* lo-res non-interlaced display */ __registers[6] = 0x271; /* vsync */ @@ -371,7 +371,7 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu __registers[11 + REGISTER_COUNT] = 0x000E0204; /* vburst for field 2 */ __registers[13] = 0x02000800; /* y-scale */ } - else + else //TODO: something here for high res non-interlaced (i.e.640x240) { /* lo-res non-interlaced display */ __registers[6] = 0x20D; /* vsync */ From 3f7e9fecbc5cc2868b09a8aa1a1039645ce7605d Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 13:46:53 +0100 Subject: [PATCH 19/37] Add extra header options for convenience. --- Makefile | 2 +- azure-pipelines.yml | 8 ++++++-- headers/header | Bin 0 -> 4096 bytes headers/header-0 | Bin 0 -> 4096 bytes headers/header-6105 | Bin 0 -> 4096 bytes headers/header-6105-0 | Bin 0 -> 4096 bytes headers/header-6105-ntsc | Bin 0 -> 4096 bytes headers/header-6105-pal | Bin 0 -> 4096 bytes headers/header-ntsc | Bin 0 -> 4096 bytes headers/header-pal | Bin 0 -> 4096 bytes 10 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 headers/header create mode 100644 headers/header-0 create mode 100644 headers/header-6105 create mode 100644 headers/header-6105-0 create mode 100644 headers/header-6105-ntsc create mode 100644 headers/header-6105-pal create mode 100644 headers/header-ntsc create mode 100644 headers/header-pal diff --git a/Makefile b/Makefile index d9dd726e..f45f920a 100755 --- a/Makefile +++ b/Makefile @@ -80,7 +80,7 @@ install: libdragon.a libdragonsys.a install -m 0644 libdragonsys.a $(INSTALLDIR)/mips64-elf/lib/libdragonsys.a install -m 0644 n64.ld $(INSTALLDIR)/mips64-elf/lib/n64.ld - install -m 0644 header $(INSTALLDIR)/mips64-elf/lib/header + install -m 0644 headers/header $(INSTALLDIR)/mips64-elf/lib/header clean: rm -f *.o *.a diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 827202a2..aee0f1fb 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -66,8 +66,12 @@ jobs: mkdir -p $BUILD_ARTIFACTSTAGINGDIRECTORY/lib/ cp "$BUILD_SOURCESDIRECTORY/"*.a "$BUILD_ARTIFACTSTAGINGDIRECTORY/lib/" - cp "$BUILD_SOURCESDIRECTORY/"*.ld "$BUILD_ARTIFACTSTAGINGDIRECTORY/lib/" - cp "$BUILD_SOURCESDIRECTORY/header" "$BUILD_ARTIFACTSTAGINGDIRECTORY/lib/" + + mkdir -p $BUILD_ARTIFACTSTAGINGDIRECTORY/ldscripts/ + cp "$BUILD_SOURCESDIRECTORY/"*.ld "$BUILD_ARTIFACTSTAGINGDIRECTORY/ldscripts/" + + mkdir -p $BUILD_ARTIFACTSTAGINGDIRECTORY/headers/ + cp "$BUILD_SOURCESDIRECTORY/headers/"* "$BUILD_ARTIFACTSTAGINGDIRECTORY/headers/" displayName: 'Move Artifacts to Staging Directory' continueOnError: false diff --git a/headers/header b/headers/header new file mode 100644 index 0000000000000000000000000000000000000000..e8f7c3b8b98f221c70480755d64401acc7e8ed15 GIT binary patch literal 4096 zcmcguU2Ggz75?t*#J=ln*jab&Y@A5G>&*Bkp=g8b)hE`hVRbq zI&qT+cwxNbd+)jDp7WjGJHhRp8bCUL%^_QSYvQ?Ak3asaFLMz;rOA8L-M0;^;vrI4xek(Q_Zti zhm#^*dm8YQIXN;kI9j_CvZj&slL0uV;WHjE>-p)kn?T+3_YhC_5;dIn{5HI`N(_SNC+yAZ5<@QX(PiDp6RAUtdC5 zYpcqdUsC8?)P0|XXzAykW9Y7=j(O_%6WoP&s8dod*N29p$dxFgVk9d>O4IU|$0QzNo7UK<=@ZB~iRWAW?NAZ~pgvJ25G4VAFPe@3YQA;OL+<#qssjZ1Rm1| z=#QTnTl|jYS#*B2?kCYUGIZOp_;AT%{y7VLeYu1YnP85lqY=i$`o*eS>qgG_Y~TV) zRn}0IHB@B{Rarw-))47A<6Bd6UQ)vwiq>_o&RX2S1=2)P9?Y_KxKH1-_>|$>yg*-G zx9`wrx5OB?`2I(EV!J%r3hyv&-WhGuUPpXv%4N+P-I2eOqqOVZ(e^Khq;|!l)2^Rf zg6Pnm_}sMT4KYu5!PsSso$?^pHtqO#?bhgBKSeuEQC9$3XymVA;ZaDxqc<8kOxa?& zEDn_1bCf}S+3RJbUgyqsENv|JOr*loyT? z=TV5Ra;~G5Z3{EVcC&?YtesYz$3)GU#HIv88zC3%gvA-)BU9Ew+8PlB`>CGG! zs*$tCPR6m!80zrbC<610Vc?m&AUw-^a+&w!*LhD;efUje!{?C;Utr8%gyOy6hUYLC z*6_h_1%)ugaCjc0;Sb@5-$99Y?OnWUr+C-i%e!`(ckKh=%P2Ev9%fIa*8m1k97qy3 zYs%`I&m*HMrr)~kyY%_P$T*cMaaDn`@KDfX><*|(r@af%2v`HH#V8Q-8%X^dxOAE72p}QANJO$DW~kt zy}QWVO_;ngvdw66%V04wh~+Z<6z?_tVF8<-+Y?1AXJDUx5;jMe7g+a@*k=`vLlA3X z;A;@3?#y`b3?#Aq3yIvsz?)pZj*cTb`kRr{)H(Qmos79U%g>9rmNDfG?^>gdS#Rid z=p&kau&z8}R|dD4x8lX|rGaG(w8pRe2m|ikgks!O;(q!Gx>MMf_P0+Wk@)!K1DL1( zINrk?k9qVA88TReZX8v6*EXX5qn-k{0<`o$)HbN>$&vtDA3ydRrEV(}`}9hkRupCz5~NJ?E4 zN}jN6#|h?aHGY+pKHz28OTVYam2>h=1s{8+hjla4##I?1 zCCRqVZh4AAPOJ+i5Mhwp{A_3w;xxT(R5o%b&!c+WZm(M?SaCk^z?Mq{(wHMuvteEP z^{#J`^*%a4GitFpf{nP|Ve+78tGp$9-;R^9_hdup?%<+rq&K-6LMjySlQu_YYMyzWrf^(fwbH8sn4E zTq9ikyrK4+K0$HZ-9h7ZJMOg?i&{0fnjTDFZRx-9a6ynsUr$e8y?(WQPVOc_$MM_t zzp;}-xyiyW-BfF8#<91}|3nm+0jy$^F-ALo1|T2$q*>gDCJy&8;recKES-NUQ8&BW GpZ@@#JW8(s literal 0 HcmV?d00001 diff --git a/headers/header-0 b/headers/header-0 new file mode 100644 index 0000000000000000000000000000000000000000..e8f7c3b8b98f221c70480755d64401acc7e8ed15 GIT binary patch literal 4096 zcmcguU2Ggz75?t*#J=ln*jab&Y@A5G>&*Bkp=g8b)hE`hVRbq zI&qT+cwxNbd+)jDp7WjGJHhRp8bCUL%^_QSYvQ?Ak3asaFLMz;rOA8L-M0;^;vrI4xek(Q_Zti zhm#^*dm8YQIXN;kI9j_CvZj&slL0uV;WHjE>-p)kn?T+3_YhC_5;dIn{5HI`N(_SNC+yAZ5<@QX(PiDp6RAUtdC5 zYpcqdUsC8?)P0|XXzAykW9Y7=j(O_%6WoP&s8dod*N29p$dxFgVk9d>O4IU|$0QzNo7UK<=@ZB~iRWAW?NAZ~pgvJ25G4VAFPe@3YQA;OL+<#qssjZ1Rm1| z=#QTnTl|jYS#*B2?kCYUGIZOp_;AT%{y7VLeYu1YnP85lqY=i$`o*eS>qgG_Y~TV) zRn}0IHB@B{Rarw-))47A<6Bd6UQ)vwiq>_o&RX2S1=2)P9?Y_KxKH1-_>|$>yg*-G zx9`wrx5OB?`2I(EV!J%r3hyv&-WhGuUPpXv%4N+P-I2eOqqOVZ(e^Khq;|!l)2^Rf zg6Pnm_}sMT4KYu5!PsSso$?^pHtqO#?bhgBKSeuEQC9$3XymVA;ZaDxqc<8kOxa?& zEDn_1bCf}S+3RJbUgyqsENv|JOr*loyT? z=TV5Ra;~G5Z3{EVcC&?YtesYz$3)GU#HIv88zC3%gvA-)BU9Ew+8PlB`>CGG! zs*$tCPR6m!80zrbC<610Vc?m&AUw-^a+&w!*LhD;efUje!{?C;Utr8%gyOy6hUYLC z*6_h_1%)ugaCjc0;Sb@5-$99Y?OnWUr+C-i%e!`(ckKh=%P2Ev9%fIa*8m1k97qy3 zYs%`I&m*HMrr)~kyY%_P$T*cMaaDn`@KDfX><*|(r@af%2v`HH#V8Q-8%X^dxOAE72p}QANJO$DW~kt zy}QWVO_;ngvdw66%V04wh~+Z<6z?_tVF8<-+Y?1AXJDUx5;jMe7g+a@*k=`vLlA3X z;A;@3?#y`b3?#Aq3yIvsz?)pZj*cTb`kRr{)H(Qmos79U%g>9rmNDfG?^>gdS#Rid z=p&kau&z8}R|dD4x8lX|rGaG(w8pRe2m|ikgks!O;(q!Gx>MMf_P0+Wk@)!K1DL1( zINrk?k9qVA88TReZX8v6*EXX5qn-k{0<`o$)HbN>$&vtDA3ydRrEV(}`}9hkRupCz5~NJ?E4 zN}jN6#|h?aHGY+pKHz28OTVYam2>h=1s{8+hjla4##I?1 zCCRqVZh4AAPOJ+i5Mhwp{A_3w;xxT(R5o%b&!c+WZm(M?SaCk^z?Mq{(wHMuvteEP z^{#J`^*%a4GitFpf{nP|Ve+78tGp$9-;R^9_hdup?%<+rq&K-6LMjySlQu_YYMyzWrf^(fwbH8sn4E zTq9ikyrK4+K0$HZ-9h7ZJMOg?i&{0fnjTDFZRx-9a6ynsUr$e8y?(WQPVOc_$MM_t zzp;}-xyiyW-BfF8#<91}|3nm+0jy$^F-ALo1|T2$q*>gDCJy&8;recKES-NUQ8&BW GpZ@@#JW8(s literal 0 HcmV?d00001 diff --git a/headers/header-6105 b/headers/header-6105 new file mode 100644 index 0000000000000000000000000000000000000000..d8c93a81932be64db60abcc48297e608080385c4 GIT binary patch literal 4096 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 Sx@9=mEv&lIuAtZNYUE#wXoJK6 literal 0 HcmV?d00001 diff --git a/headers/header-6105-0 b/headers/header-6105-0 new file mode 100644 index 0000000000000000000000000000000000000000..d8c93a81932be64db60abcc48297e608080385c4 GIT binary patch literal 4096 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 Sx@9=mEv&lIuAtZNYUE#wXoJK6 literal 0 HcmV?d00001 diff --git a/headers/header-6105-ntsc b/headers/header-6105-ntsc new file mode 100644 index 0000000000000000000000000000000000000000..06e81207d6b16f9ff2e408876a0505c8c6b1662f GIT binary patch literal 4096 zcmbtW33yXg7CtxcwY;>6NlLoV7W)eCr5i#j4McdzqikU>P-#$>uopT&VO+{0Miwd3 zHVBR*$Vh;IEKSpbEQ*E5S{2z8go4nrXaR*Xj>!Jz+%#pzWxj9bn|$BRJ@?*o&-u@K zpR;|03;;SOus9ie{g7|i@p9BRX}AddY+VQQ{o7^m-NsFx+PD{-yY=ta9T>NbFHWx4 z7f*t2#Fl09rq=5d^MFm~bV?*BcN0^9EzX5*cy99|AD$bV)PUa0*T*!4)l6Fs&X)|2jI&qn@PGM?UPw(FpvVR@aKKKH!ae200i5cmoxJSK1=(rCVF!ux zkY% zDalrEFW|f~7$vn6kVc2+iU9edq+44L;1{K4h$qU88g`0ODAG+Ry+o9ZZfeg?#$7K; zdXKq853FP$#FS1*lmSAJ2?V_gEYoDr127G17S~QFYYnXUGibD+N}&6C8LV{nt-(8L z9w@%z>xhx7S4gg1@NEXRWhHQeS|2!*xbkL^xuBtUB#r}y^Ye_kDljAtcvV$7uPSu& z5V1sVF$hSbemv9DeSt$Ag{b2y2*vkMCx>!zot~m70v7_2$$(x%*>MDz7mf+ha)Uh* zr;oRAVXU_fVyH~it+8+sfi=ZJs`7bKUl16g7syi^fWv&--+*&Jcx|AOIP|j(SjJz6 zevT1c8_{oExf*pwQNA)Out^rsxI6#>n?r!0pN`YBk}7I1a3o6RF|U5NmN+(mf%+m~ zEBXO(CYH6w96I^OGK=bhGMhBWr1!|b=$J(OUT0~jCk{g3j=wlo!O3-f^38|@EQ&_48apDY3EpW;xkmmvO- zY%z~3Bx+e86YT=t<0Q2kN_mtSCW~Z}T@-2m(gL-WCE;8eU88OHy-z6*B#jeLpO@;x z9>NkQZ~?vH_myMM!oFlWr2;8|wwM^KCs_oi4QG9Xkcs&wTSbtwaM*D;ahP#9L_rID zaSK#-F(wfvaA|rTRNzP!F)qa16%xqWf|lf>KNLpiv*a`{!d@;7+*Xl{wwsWbRk6-Q zxL9REr7Ff`Ho<EA)YnMI;G3v7)-I%ER7IXnGg;-pO#f4a0hy~x0 zco$-EAr=>6aUm8LVsRlB7h-WC7L1wfLOj?*`(h8x!XBE9J=BgpbeIeAFg3toJl&0T z20-fx>jxZS$_kJN%YffVdJ%EWCr)0p%fO{{fGp^BtR>SInt@FDk42D~_C#tEJ&Tr= zTiA;Tg!4{V%(n#g@hqd9)x!J-OR$z0noCr6V@^>lR0d)>jeZK81^uA{s27D;MJZbW zY{@)eaRxd7YD8e-RpyyM5G#|k5(w=DbWU3V9Adc(OiX6dd0baRSdOgRq;i5flYgrd zW6rO|PaVuav@1)@&{m<2d@-dO1%~N&Iu#1he>e|z1Y*lGaxTit5-C4n1N)(*zdlhs0wm=ubjfij zH53Eg1C>7WkMNu4gCfKMvCfCi)PKfZ_|2m00aC0J$h`v5yaHnqd)yhMRS^4?9Hd!@ zJ=w^^Ax|T%hu9PTAP*0*UppyHbx_%5KCHD^kJ%?OpSpcd_w^k!gy}7p+MEa0f3RT3H$_V>ZywWa(D+L$+lqHbZ2I`mj^TZ#&Dp)N zD5u%9eV>oGlG?VkaNzjWvtF7ocE!Y-Q-@@_n-4so`eoPB?z^XIw_6YEAMVN?7(c7Y z+eyn_UAphmFgtW&i^Jl@RS z!@hlE)Kw;;R`=dDQ>#(uM%(fx8*7*ay{Gr6ey8fy_~RkZURj#ob>yFzkgeCZ@|J#c z#%Gas{tFIPuxRBprKXW@mqHtE1B=srP2W^buV$?z}Uxb7cqnTZ?NC zuc=u2?JKJ-kACX&NyVl12JNA7yKjxUG9py59C~@t@PAC{eRx~;oLiAq?&Ypw`QbN> z2d{*!Z1!REzDI_Hp35|d-@h|em)PmT-JG7<3u%)cyi$Df>Y2OSYOYV8A6t@XZ2sny zkxM(=55IEzvVT?gQ>pXzRD3yU|DK}r7qZ) zS}=0VhTAC-U18GM8)Jn*i}!aNzRMD`=Bq`@7WYu|-_M@>wBMvY?N$yi`0m)+rP?b? W4CQa=x@0)lFRHxSrl9BVYUH1XbA;#s literal 0 HcmV?d00001 diff --git a/headers/header-6105-pal b/headers/header-6105-pal new file mode 100644 index 0000000000000000000000000000000000000000..b4c4d6a604f6205e6ab49ad6767141f5fd79bc39 GIT binary patch literal 4096 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 W`ieKST{0c(7gb$tQ`qBoHS$k1*o5-{ literal 0 HcmV?d00001 diff --git a/headers/header-ntsc b/headers/header-ntsc new file mode 100644 index 0000000000000000000000000000000000000000..ad736002f5406498975ee7f38a3df63753f000fc GIT binary patch literal 4096 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 G`|}@+CrbYS literal 0 HcmV?d00001 From 841ac3e42be30b6261d76ca1d3cdbb9e19cd83bc Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Thu, 25 Jun 2020 23:34:21 +0100 Subject: [PATCH 20/37] Further try! --- tools/mksprite/mksprite.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/mksprite/mksprite.c b/tools/mksprite/mksprite.c index c42ffa3f..9d74a439 100644 --- a/tools/mksprite/mksprite.c +++ b/tools/mksprite/mksprite.c @@ -161,6 +161,10 @@ int read_png( char *png_file, char *spr_file, uint8_t depth, uint8_t hslices, ui } } + // Set row pointer to the png struct + png_set_rows(png_ptr, info_ptr, row_pointers); + + /* Now it's time to read the image. */ png_read_image(png_ptr, row_pointers); From dad177e563ddb63be254109e982bbaad3f3b9ff1 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 26 Jun 2020 00:48:30 +0100 Subject: [PATCH 21/37] further reverts to mksprite (whitespace/comments) --- tools/mksprite/mksprite.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/mksprite/mksprite.c b/tools/mksprite/mksprite.c index 9d74a439..c42ffa3f 100644 --- a/tools/mksprite/mksprite.c +++ b/tools/mksprite/mksprite.c @@ -161,10 +161,6 @@ int read_png( char *png_file, char *spr_file, uint8_t depth, uint8_t hslices, ui } } - // Set row pointer to the png struct - png_set_rows(png_ptr, info_ptr, row_pointers); - - /* Now it's time to read the image. */ png_read_image(png_ptr, row_pointers); From 8ecb2798021909180a29a9bc5bc9a1044ad8b2f2 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 26 Jun 2020 01:06:40 +0100 Subject: [PATCH 22/37] Try a different path... --- tools/mksprite/mksprite.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/mksprite/mksprite.c b/tools/mksprite/mksprite.c index c42ffa3f..a9f43524 100644 --- a/tools/mksprite/mksprite.c +++ b/tools/mksprite/mksprite.c @@ -155,15 +155,12 @@ int read_png( char *png_file, char *spr_file, uint8_t depth, uint8_t hslices, ui if( row_pointers[row] == NULL ) { fprintf(stderr, "Unable to allocate space for row pointers!\n"); - + err = -ENOMEM; goto exitmem; } } - /* Now it's time to read the image. */ - png_read_image(png_ptr, row_pointers); - /* Translate out to sprite format */ switch( color_type ) { From 0625d2ede58430b216e4d99ec9981b5e043fa33a Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 26 Jun 2020 01:20:21 +0100 Subject: [PATCH 23/37] Try another --- tools/mksprite/mksprite.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/mksprite/mksprite.c b/tools/mksprite/mksprite.c index a9f43524..fcc44d8a 100644 --- a/tools/mksprite/mksprite.c +++ b/tools/mksprite/mksprite.c @@ -155,12 +155,15 @@ int read_png( char *png_file, char *spr_file, uint8_t depth, uint8_t hslices, ui if( row_pointers[row] == NULL ) { fprintf(stderr, "Unable to allocate space for row pointers!\n"); - + err = -ENOMEM; goto exitmem; } } + /* Now it's time to read the image. */ + png_read_image(png_ptr, row_pointers); + /* Translate out to sprite format */ switch( color_type ) { From a9d5b6ad05ebc605aeb577ac7a491377b210b49e Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 26 Jun 2020 01:36:51 +0100 Subject: [PATCH 24/37] revert change to system.c errno --- src/system.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system.c b/src/system.c index b6f7f020..f08c93e2 100644 --- a/src/system.c +++ b/src/system.c @@ -102,9 +102,9 @@ char **environ = __env; struct timeval; /** - * @brief Definition of errno, as it's defined as extern across stdlib + * @brief Master definition of errno */ -int errno; +extern int errno; /* Externs from libdragon */ extern int __bootcic; From aadb467d1155e92a51604672325ee862048df3da Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 26 Jun 2020 13:28:59 +0100 Subject: [PATCH 25/37] Corrects header bytes in mksprite --- tools/mksprite/mksprite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksprite/mksprite.c b/tools/mksprite/mksprite.c index fcc44d8a..6f8e751d 100644 --- a/tools/mksprite/mksprite.c +++ b/tools/mksprite/mksprite.c @@ -46,7 +46,7 @@ int read_png( char *png_file, char *spr_file, uint8_t depth, uint8_t hslices, ui png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; - int wval8; + uint8_t wval8; uint16_t wval16; FILE *fp; FILE *op; From a1243d092cbcd2b728f64655f8bb33f0265ee589 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Mon, 29 Jun 2020 20:19:33 +0100 Subject: [PATCH 26/37] correct issues with newlib includes? --- src/system.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/system.c b/src/system.c index f08c93e2..1852386f 100644 --- a/src/system.c +++ b/src/system.c @@ -3,15 +3,16 @@ * @brief newlib Interface Hooks * @ingroup system */ -#include <_ansi.h> -#include <_syslist.h> +#include +#include #include #include -#include +#include <_ansi.h> //could use reent.h /stdlib.h? +#include <_syslist.h> +#include //could use reent.h /stdlib.h? #include #include -#include -#include + #include "system.h" #include "n64sys.h" @@ -40,7 +41,7 @@ * Providing relevant hooks for calls that your filesystem supports and passing * the resulting structure to #attach_filesystem will hook your filesystem into * newlib. Calls to POSIX file operations will be passed on to your filesystem - * code if the file prefix matches, allowing code to make use of your filesystyem + * code if the file prefix matches, allowing code to make use of your filesystem * without being rewritten. * * For example, your filesystem provides libdragon an interface to access a @@ -162,7 +163,7 @@ int close( int fildes ); /** * @brief Simple implementation of strlen * - * @note We can't link against regular libraries, so this is reimplemented + * @note We can't link against regular libraries, so this is re-implemented * * @param[in] str * Pointer to null-terminated string @@ -185,7 +186,7 @@ static int __strlen( const char * const str ) /** * @brief Simple implementation of memcpy * - * @note We can't link against regular libraries, so this is reimplemented + * @note We can't link against regular libraries, so this is re-implemented * * @param[out] a * Destination pointer to copy to @@ -205,7 +206,7 @@ static void __memcpy( char * const a, const char * const b, int len ) /** * @brief Simple implementation of strdup * - * @note We can't link against regular libraries, so this is reimplemented + * @note We can't link against regular libraries, so this is re-implemented * * @param[in] in * String to duplicate @@ -223,9 +224,9 @@ static char *__strdup( const char * const in ) } /** - * @brief Simple iplementation of strncmp + * @brief Simple implementation of strncmp * - * @note We can't link against regular libraries, so this is reimplemented + * @note We can't link against regular libraries, so this is re-implemented * * @param[in] a * First string to compare against From 7b90bee98ec6010218a468a142863ad94880e25c Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Mon, 29 Jun 2020 23:42:20 +0100 Subject: [PATCH 27/37] Minor spelling correction. --- src/mempak.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mempak.c b/src/mempak.c index 0a80a674..c03003af 100644 --- a/src/mempak.c +++ b/src/mempak.c @@ -373,7 +373,7 @@ static int __validate_region( uint8_t region ) case 0x55: case 0x58: case 0x59: - /* Acceptible region */ + /* Acceptable region */ return 0; } From 1827e590082f4b45e7e6da448f36b1eae3828b72 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 30 Jun 2020 01:09:08 +0100 Subject: [PATCH 28/37] correct xscale for PAL 512p --- src/display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/display.c b/src/display.c index c0981bd8..5774823f 100644 --- a/src/display.c +++ b/src/display.c @@ -6,6 +6,7 @@ #include #include #include +#include "display.h" #include "libdragon.h" /** From c56c83f8d6378d828eb4e9c713d0567b0c8ba9f7 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 30 Jun 2020 01:21:01 +0100 Subject: [PATCH 29/37] try different offset for high res... --- src/display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/display.c b/src/display.c index 5774823f..b7b0f757 100644 --- a/src/display.c +++ b/src/display.c @@ -298,7 +298,7 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu __width = 512; __height = 240; __registers[1] = 512; /* base offset for field 1 */ - __registers[1 + REGISTER_COUNT] = 1024; /* base offset for field 2 */ //TODO: probably wrong + __registers[1 + REGISTER_COUNT] = 240; /* base offset for field 2 */ //TODO: probably wrong __registers[2] = 512; /* width */ __registers[12] = 0x00000333; /* x-scale */ break; @@ -306,7 +306,7 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu __width = 640; __height = 240; __registers[1] = 640; /* base offset for field 1 */ - __registers[1 + REGISTER_COUNT] = 1280; /* base offset for field 2 */ //TODO: probably wrong + __registers[1 + REGISTER_COUNT] = 640; /* base offset for field 2 */ //TODO: probably wrong __registers[2] = 640; /* width */ __registers[12] = 0x00000400; /* x-scale */ break; From a373182a1912123a573b64007d50ed62e0c41a34 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 30 Jun 2020 01:34:12 +0100 Subject: [PATCH 30/37] Correct me... --- src/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index b7b0f757..e5e832e9 100644 --- a/src/display.c +++ b/src/display.c @@ -298,7 +298,7 @@ void display_init_ex( tvtype_t tv, resolution_t res, bitdepth_t bit, uint32_t nu __width = 512; __height = 240; __registers[1] = 512; /* base offset for field 1 */ - __registers[1 + REGISTER_COUNT] = 240; /* base offset for field 2 */ //TODO: probably wrong + __registers[1 + REGISTER_COUNT] = 512; /* base offset for field 2 */ //TODO: probably wrong __registers[2] = 512; /* width */ __registers[12] = 0x00000333; /* x-scale */ break; From 1798da1dc318cd1e3dd2634e28edf12a92eed02e Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Tue, 30 Jun 2020 02:32:51 +0100 Subject: [PATCH 31/37] remove un-necessary include. --- src/display.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/display.c b/src/display.c index e5e832e9..f51c20b6 100644 --- a/src/display.c +++ b/src/display.c @@ -6,7 +6,6 @@ #include #include #include -#include "display.h" #include "libdragon.h" /** From 631e5a8133eba53775405958bd1fcfecd047e19e Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 3 Jul 2020 20:43:35 +0100 Subject: [PATCH 32/37] Make fonts more generic --- include/font.h | 4 ++++ src/graphics.c | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/include/font.h b/include/font.h index c5adfc61..febf5f53 100644 --- a/include/font.h +++ b/include/font.h @@ -1,3 +1,5 @@ +#ifndef USE_CUSTOM_FONT + /** * @file font.h * @brief Font Data @@ -142,3 +144,5 @@ static unsigned char const __font_data[2048] = { }; #endif + +#endif diff --git a/src/graphics.c b/src/graphics.c index 1fc4de46..f3ab74f7 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -27,7 +27,7 @@ * two versions of graphics functions are available: a transparent variety and * a non-transparent variety. Code that wishes to display sprites without * transparency can get a slight performance boost by using the non-transparent - * viariety of calls since no software alpha blending needs to occur. Once + * variety of calls since no software alpha blending needs to occur. Once * code has finished drawing to the display context, it can be displayed to the * screen using #display_show. * @@ -739,6 +739,35 @@ void graphics_draw_character( display_context_t disp, int x, int y, char ch ) * The ASCII null terminated string to draw to the screen. */ void graphics_draw_text( display_context_t disp, int x, int y, const char * const msg ) +{ + graphics_draw_text_ex( disp, x, y, 8, 8, msg ); //standard size font +} + +/** + * @brief Draw a null terminated string to a display context + * + * Draw a string to the screen, following a few simple rules. Standard ASCII is supported, as well + * as \\r, \\n, space and tab. \\r and \\n will both cause the next character to be rendered one line + * lower and at the x coordinate specified in the parameters. The tab character inserts five spaces. + * + * This function does not support alpha blending, only binary transparency. If the background color is + * fully transparent, the font is drawn with no background. Otherwise, the font is drawn on a fully + * colored background. The foreground and background can be set using #graphics_set_color. + * + * @param[in] disp + * The currently active display context. + * @param[in] x + * The X coordinate to place the top left pixel of the character drawn. + * @param[in] y + * The Y coordinate to place the top left pixel of the character drawn. + * @param[in] tx_w + * The width of the character drawn. + * @param[in] tx_h + * The height of the character drawn. + * @param[in] msg + * The ASCII null terminated string to draw to the screen. + */ +void graphics_draw_text_ex( display_context_t disp, int x, int y, int tx_w, int tx_h, const char * const msg ) { if( disp == 0 ) { return; } if( msg == 0 ) { return; } @@ -753,14 +782,14 @@ void graphics_draw_text( display_context_t disp, int x, int y, const char * cons { case '\r': case '\n': - tx = x; - ty += 8; + tx = tx_w; + ty += tx_h; break; case ' ': - tx += 5; // My font + tx += tx_w; break; case '\t': - tx += 5 * 5; ; // My font + tx += tx_w * tx_w; break; case '#': highlight = !highlight; @@ -804,7 +833,7 @@ void graphics_draw_text( display_context_t disp, int x, int y, const char * cons break; default: graphics_draw_character( disp, tx, ty, *text ); - tx += 5; ; // My font + tx += tx_w; break; } From 3e50996c298b0c9138910649df467e7b5d3f6fb7 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 3 Jul 2020 20:50:43 +0100 Subject: [PATCH 33/37] add missing proto to last commit --- include/graphics.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/graphics.h b/include/graphics.h index 656a574f..20c27d63 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -69,6 +69,7 @@ void graphics_fill_screen( display_context_t disp, uint32_t c ); void graphics_set_color( uint32_t forecolor, uint32_t backcolor ); void graphics_draw_character( display_context_t disp, int x, int y, char c ); void graphics_draw_text( display_context_t disp, int x, int y, const char * const msg ); +void graphics_draw_text_ex( display_context_t disp, int x, int y, int tx_w, int tx_h, const char * const msg ); void graphics_draw_sprite( display_context_t disp, int x, int y, sprite_t *sprite ); void graphics_draw_sprite_stride( display_context_t disp, int x, int y, sprite_t *sprite, int offset ); void graphics_draw_sprite_trans( display_context_t disp, int x, int y, sprite_t *sprite ); From 062aef504b054cf0dfcfc4fdc89fe1b90399b1c1 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Fri, 3 Jul 2020 21:00:35 +0100 Subject: [PATCH 34/37] revert font.h to original --- include/font.h | 254 ++++++++++++++++++++++++------------------------- 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/include/font.h b/include/font.h index febf5f53..fe946a87 100644 --- a/include/font.h +++ b/include/font.h @@ -13,133 +13,133 @@ * @ingroup graphics */ static unsigned char const __font_data[2048] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, - 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C, - 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, - 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, - 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, - 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, - 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, - 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, - 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, - 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7C, 0x28, 0x7C, 0x28, 0x00, 0x00, - 0x00, 0x38, 0x50, 0x38, 0x14, 0x38, 0x00, 0x00, 0x20, 0x24, 0x08, 0x10, 0x24, 0x04, 0x00, 0x00, - 0x00, 0x10, 0x28, 0x10, 0x28, 0x14, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, - 0x00, 0x28, 0x10, 0x38, 0x10, 0x28, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, - 0x08, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00, - 0x18, 0x24, 0x04, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x3C, 0x04, 0x18, 0x04, 0x24, 0x18, 0x00, 0x00, - 0x08, 0x18, 0x28, 0x3C, 0x08, 0x08, 0x00, 0x00, 0x3C, 0x20, 0x38, 0x04, 0x24, 0x18, 0x00, 0x00, - 0x18, 0x20, 0x38, 0x24, 0x24, 0x18, 0x00, 0x00, 0x3C, 0x04, 0x08, 0x08, 0x10, 0x10, 0x00, 0x00, - 0x18, 0x24, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x18, 0x24, 0x24, 0x1C, 0x04, 0x18, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x10, 0x20, 0x00, - 0x00, 0x04, 0x08, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x08, 0x04, 0x08, 0x10, 0x00, 0x00, 0x08, 0x14, 0x04, 0x08, 0x00, 0x08, 0x00, 0x00, - 0x30, 0x48, 0x58, 0x58, 0x40, 0x30, 0x00, 0x00, 0x30, 0x48, 0x48, 0x78, 0x48, 0x48, 0x00, 0x00, - 0x70, 0x48, 0x70, 0x48, 0x48, 0x70, 0x00, 0x00, 0x30, 0x48, 0x40, 0x40, 0x48, 0x30, 0x00, 0x00, - 0x70, 0x48, 0x48, 0x48, 0x48, 0x70, 0x00, 0x00, 0x78, 0x40, 0x70, 0x40, 0x40, 0x78, 0x00, 0x00, - 0x78, 0x40, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00, 0x30, 0x48, 0x40, 0x58, 0x48, 0x38, 0x00, 0x00, - 0x48, 0x48, 0x78, 0x48, 0x48, 0x48, 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, - 0x08, 0x08, 0x08, 0x08, 0x48, 0x30, 0x00, 0x00, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x00, 0x00, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00, 0x00, 0x48, 0x78, 0x78, 0x48, 0x48, 0x48, 0x00, 0x00, - 0x48, 0x68, 0x68, 0x58, 0x58, 0x48, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, - 0x70, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x68, 0x30, 0x08, 0x00, - 0x70, 0x48, 0x48, 0x70, 0x50, 0x48, 0x00, 0x00, 0x30, 0x48, 0x20, 0x10, 0x48, 0x30, 0x00, 0x00, - 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x48, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, - 0x48, 0x48, 0x48, 0x48, 0x30, 0x30, 0x00, 0x00, 0x48, 0x48, 0x48, 0x78, 0x78, 0x48, 0x00, 0x00, - 0x48, 0x48, 0x30, 0x30, 0x48, 0x48, 0x00, 0x00, 0x28, 0x28, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00, - 0x78, 0x08, 0x10, 0x20, 0x40, 0x78, 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, - 0x00, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, - 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, - 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x2C, 0x14, 0x00, 0x00, - 0x20, 0x20, 0x38, 0x24, 0x24, 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, 0x18, 0x00, 0x00, - 0x04, 0x04, 0x1C, 0x24, 0x24, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2C, 0x30, 0x18, 0x00, 0x00, - 0x08, 0x14, 0x10, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x18, 0x20, 0x1C, 0x00, - 0x20, 0x20, 0x38, 0x24, 0x24, 0x24, 0x00, 0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x1C, 0x00, 0x00, - 0x04, 0x00, 0x04, 0x04, 0x04, 0x14, 0x08, 0x00, 0x20, 0x20, 0x28, 0x30, 0x28, 0x24, 0x00, 0x00, - 0x18, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x3C, 0x24, 0x24, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x24, 0x24, 0x38, 0x20, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x24, 0x1C, 0x04, 0x00, - 0x00, 0x00, 0x38, 0x24, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x30, 0x0C, 0x38, 0x00, 0x00, - 0x10, 0x10, 0x38, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x1C, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x3C, 0x3C, 0x00, 0x00, - 0x00, 0x00, 0x24, 0x18, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x14, 0x08, 0x10, 0x00, - 0x00, 0x00, 0x3C, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x04, 0x08, 0x18, 0x08, 0x08, 0x04, 0x00, 0x00, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x10, 0x08, 0x0C, 0x08, 0x08, 0x10, 0x00, 0x00, - 0x14, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x99, 0xA1, 0xA1, 0x99, 0x42, 0x3C, - 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, - 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, - 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, - 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, - 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, - 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, - 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, - 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, - 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, - 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, - 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30, - 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, - 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00, 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, - 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, - 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, - 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, - 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, - 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, - 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, - 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, - 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, - 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, - 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, - 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, - 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, - 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, - 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, - 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, - 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, - 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, - 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, + 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C, + 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, + 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, + 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, + 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, + 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, + 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, + 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, + 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, + 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, + 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, + 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, + 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, + 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, + 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, + 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00, + 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, + 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, + 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00, + 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, + 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00, + 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, + 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, + 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, + 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, + 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, + 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, + 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, + 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, + 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, + 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30, + 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, + 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00, 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, + 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, + 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, + 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, + 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, + 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, + 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, + 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, + 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, + 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, + 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; From 697bc24ae691f583047bd70af7a256cbaab1a13f Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Sat, 4 Jul 2020 00:28:44 +0100 Subject: [PATCH 35/37] revert last commit for the moment (it doesnt work as it is already built) --- include/font.h | 254 ++++++++++++++++++++++++------------------------- 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/include/font.h b/include/font.h index fe946a87..febf5f53 100644 --- a/include/font.h +++ b/include/font.h @@ -13,133 +13,133 @@ * @ingroup graphics */ static unsigned char const __font_data[2048] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, - 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C, - 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, - 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, - 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, - 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, - 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, - 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, - 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, - 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, - 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, - 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, - 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, - 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, - 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, - 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, - 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, - 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, - 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, - 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, - 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, - 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, - 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00, - 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, - 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, - 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, - 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, - 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00, - 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, - 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, - 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, - 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, - 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, - 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, - 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, - 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, - 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, - 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00, - 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, - 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, - 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, - 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, - 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, - 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, - 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, - 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, - 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, - 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, - 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, - 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, - 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, - 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, - 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, - 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, - 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, - 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, - 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30, - 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, - 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, - 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00, 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, - 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, - 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, - 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, - 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, - 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, - 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, - 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, - 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, - 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, - 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, - 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, - 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, - 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, - 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, - 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, - 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, - 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, - 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, + 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C, + 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, + 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, + 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, + 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, + 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7C, 0x28, 0x7C, 0x28, 0x00, 0x00, + 0x00, 0x38, 0x50, 0x38, 0x14, 0x38, 0x00, 0x00, 0x20, 0x24, 0x08, 0x10, 0x24, 0x04, 0x00, 0x00, + 0x00, 0x10, 0x28, 0x10, 0x28, 0x14, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, + 0x00, 0x28, 0x10, 0x38, 0x10, 0x28, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, + 0x08, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00, + 0x18, 0x24, 0x04, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x3C, 0x04, 0x18, 0x04, 0x24, 0x18, 0x00, 0x00, + 0x08, 0x18, 0x28, 0x3C, 0x08, 0x08, 0x00, 0x00, 0x3C, 0x20, 0x38, 0x04, 0x24, 0x18, 0x00, 0x00, + 0x18, 0x20, 0x38, 0x24, 0x24, 0x18, 0x00, 0x00, 0x3C, 0x04, 0x08, 0x08, 0x10, 0x10, 0x00, 0x00, + 0x18, 0x24, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x18, 0x24, 0x24, 0x1C, 0x04, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x10, 0x20, 0x00, + 0x00, 0x04, 0x08, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x08, 0x04, 0x08, 0x10, 0x00, 0x00, 0x08, 0x14, 0x04, 0x08, 0x00, 0x08, 0x00, 0x00, + 0x30, 0x48, 0x58, 0x58, 0x40, 0x30, 0x00, 0x00, 0x30, 0x48, 0x48, 0x78, 0x48, 0x48, 0x00, 0x00, + 0x70, 0x48, 0x70, 0x48, 0x48, 0x70, 0x00, 0x00, 0x30, 0x48, 0x40, 0x40, 0x48, 0x30, 0x00, 0x00, + 0x70, 0x48, 0x48, 0x48, 0x48, 0x70, 0x00, 0x00, 0x78, 0x40, 0x70, 0x40, 0x40, 0x78, 0x00, 0x00, + 0x78, 0x40, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00, 0x30, 0x48, 0x40, 0x58, 0x48, 0x38, 0x00, 0x00, + 0x48, 0x48, 0x78, 0x48, 0x48, 0x48, 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x48, 0x30, 0x00, 0x00, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x00, 0x00, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00, 0x00, 0x48, 0x78, 0x78, 0x48, 0x48, 0x48, 0x00, 0x00, + 0x48, 0x68, 0x68, 0x58, 0x58, 0x48, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, + 0x70, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x68, 0x30, 0x08, 0x00, + 0x70, 0x48, 0x48, 0x70, 0x50, 0x48, 0x00, 0x00, 0x30, 0x48, 0x20, 0x10, 0x48, 0x30, 0x00, 0x00, + 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x48, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, + 0x48, 0x48, 0x48, 0x48, 0x30, 0x30, 0x00, 0x00, 0x48, 0x48, 0x48, 0x78, 0x78, 0x48, 0x00, 0x00, + 0x48, 0x48, 0x30, 0x30, 0x48, 0x48, 0x00, 0x00, 0x28, 0x28, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00, + 0x78, 0x08, 0x10, 0x20, 0x40, 0x78, 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, + 0x00, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, + 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x2C, 0x14, 0x00, 0x00, + 0x20, 0x20, 0x38, 0x24, 0x24, 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, 0x18, 0x00, 0x00, + 0x04, 0x04, 0x1C, 0x24, 0x24, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2C, 0x30, 0x18, 0x00, 0x00, + 0x08, 0x14, 0x10, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x18, 0x20, 0x1C, 0x00, + 0x20, 0x20, 0x38, 0x24, 0x24, 0x24, 0x00, 0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x1C, 0x00, 0x00, + 0x04, 0x00, 0x04, 0x04, 0x04, 0x14, 0x08, 0x00, 0x20, 0x20, 0x28, 0x30, 0x28, 0x24, 0x00, 0x00, + 0x18, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x3C, 0x24, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x24, 0x24, 0x38, 0x20, 0x00, 0x00, 0x00, 0x1C, 0x24, 0x24, 0x1C, 0x04, 0x00, + 0x00, 0x00, 0x38, 0x24, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x30, 0x0C, 0x38, 0x00, 0x00, + 0x10, 0x10, 0x38, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x1C, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x18, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x14, 0x08, 0x10, 0x00, + 0x00, 0x00, 0x3C, 0x08, 0x10, 0x3C, 0x00, 0x00, 0x04, 0x08, 0x18, 0x08, 0x08, 0x04, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x10, 0x08, 0x0C, 0x08, 0x08, 0x10, 0x00, 0x00, + 0x14, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x99, 0xA1, 0xA1, 0x99, 0x42, 0x3C, + 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, + 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, + 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, + 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, + 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, + 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30, + 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, + 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00, 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, + 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, + 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, + 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, + 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, + 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, + 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, + 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, + 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, + 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, + 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; From c3026c8147fb6f8308496619519e860dc2ad3909 Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Wed, 5 Aug 2020 17:48:07 +0100 Subject: [PATCH 36/37] Fix some whitespace issues --- tools/mksprite/mksprite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mksprite/mksprite.c b/tools/mksprite/mksprite.c index 6f8e751d..b441a457 100644 --- a/tools/mksprite/mksprite.c +++ b/tools/mksprite/mksprite.c @@ -155,7 +155,7 @@ int read_png( char *png_file, char *spr_file, uint8_t depth, uint8_t hslices, ui if( row_pointers[row] == NULL ) { fprintf(stderr, "Unable to allocate space for row pointers!\n"); - + err = -ENOMEM; goto exitmem; } From 7f15d92134eb013634e0b079e5dd6e88ebca71dd Mon Sep 17 00:00:00 2001 From: Robin Jones Date: Wed, 5 Aug 2020 18:08:20 +0100 Subject: [PATCH 37/37] Further whitespace changes --- .travis.yml | 3 ++- CHANGELOG.md | 2 +- build.sh | 2 +- examples/dfsdemo/dfsdemo.c | 1 - examples/ucodetest/Makefile | 2 +- examples/ucodetest/basic.S | 2 +- examples/ucodetest/loader.S | 2 +- include/rsp.h | 2 +- n64.ld | 2 +- src/inthandler.S | 1 - src/rsp.c | 2 +- src/system.c | 2 +- src/tpak.c | 2 +- tools/mkdfs/mkdfs.c | 2 +- 14 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9f64d8f5..0fb0cf85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,5 @@ install: script: - docker pull anacierdem/libdragon:toolchain - docker run --name=libdragon -d --mount type=bind,source=$(pwd),target=/libdragon -w=/libdragon anacierdem/libdragon:toolchain tail -f /dev/null - - docker exec libdragon /bin/bash ./build.sh \ No newline at end of file + - docker exec libdragon /bin/bash ./build.sh + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 831f8ae6..a1e4a737 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,4 +13,4 @@ ## [1.3.9] - 2019-27-10 ### Added -- Add texture mirroring. https://github.com/DragonMinded/libdragon/commit/00a6cc8e6d136cf2578a50320f6ff0814dfb6657 \ No newline at end of file +- Add texture mirroring. https://github.com/DragonMinded/libdragon/commit/00a6cc8e6d136cf2578a50320f6ff0814dfb6657 diff --git a/build.sh b/build.sh index d7dc63a7..9f8961f1 100755 --- a/build.sh +++ b/build.sh @@ -11,4 +11,4 @@ make -j8 && \ make install && \ popd && \ rm -rf /tmp/libmikmod && \ -make -j8 examples \ No newline at end of file +make -j8 examples diff --git a/examples/dfsdemo/dfsdemo.c b/examples/dfsdemo/dfsdemo.c index 83057c79..29b85892 100644 --- a/examples/dfsdemo/dfsdemo.c +++ b/examples/dfsdemo/dfsdemo.c @@ -411,4 +411,3 @@ int main(void) return 0; } - diff --git a/examples/ucodetest/Makefile b/examples/ucodetest/Makefile index 78c9fd6c..ae9a3174 100755 --- a/examples/ucodetest/Makefile +++ b/examples/ucodetest/Makefile @@ -48,4 +48,4 @@ basic.o: loader.S text.section.bin data.section.bin clean: rm -f *.v64 *.z64 *.elf *.o *.bin -.PHONY : clean \ No newline at end of file +.PHONY : clean diff --git a/examples/ucodetest/basic.S b/examples/ucodetest/basic.S index 8bfe1c12..3b35f88b 100644 --- a/examples/ucodetest/basic.S +++ b/examples/ucodetest/basic.S @@ -15,4 +15,4 @@ deadloop: .data var1: .word 0xDEADBEEF -var2: .word 0xBEEFF00D \ No newline at end of file +var2: .word 0xBEEFF00D diff --git a/examples/ucodetest/loader.S b/examples/ucodetest/loader.S index 43694db4..0e059ab7 100644 --- a/examples/ucodetest/loader.S +++ b/examples/ucodetest/loader.S @@ -14,4 +14,4 @@ __basic_ucode_start: .balign 8 .global __basic_ucode_end -__basic_ucode_end: \ No newline at end of file +__basic_ucode_end: diff --git a/include/rsp.h b/include/rsp.h index b1026502..29dfebc1 100644 --- a/include/rsp.h +++ b/include/rsp.h @@ -21,4 +21,4 @@ void run_ucode(); } #endif -#endif \ No newline at end of file +#endif diff --git a/n64.ld b/n64.ld index e458adc4..ab58e38a 100644 --- a/n64.ld +++ b/n64.ld @@ -148,4 +148,4 @@ SECTIONS { . = ALIGN(8); end = .; -} \ No newline at end of file +} diff --git a/src/inthandler.S b/src/inthandler.S index 36fb715b..8b6d184c 100644 --- a/src/inthandler.S +++ b/src/inthandler.S @@ -312,4 +312,3 @@ endint: .lcomm saveFR30, 8 .lcomm saveFR31, 8 .lcomm exception_stack, 65*1024 - diff --git a/src/rsp.c b/src/rsp.c index cf44bae5..37ecb3b6 100644 --- a/src/rsp.c +++ b/src/rsp.c @@ -143,4 +143,4 @@ void run_ucode() *(volatile uint32_t *) 0xA4080000 = SP_DMA_IMEM; SP_regs->status = SP_STATUS_CLEAR_HALT | SP_STATUS_SET_INTR_BREAK; return; -} \ No newline at end of file +} diff --git a/src/system.c b/src/system.c index 1852386f..e1693e70 100644 --- a/src/system.c +++ b/src/system.c @@ -1296,4 +1296,4 @@ int unhook_stdio_calls() return 0; } -/** @} */ \ No newline at end of file +/** @} */ diff --git a/src/tpak.c b/src/tpak.c index ec4ef8c7..4ffcd4db 100755 --- a/src/tpak.c +++ b/src/tpak.c @@ -309,4 +309,4 @@ bool tpak_check_header(struct gameboy_cartridge_header* header) } return sum == header->header_checksum; -} \ No newline at end of file +} diff --git a/tools/mkdfs/mkdfs.c b/tools/mkdfs/mkdfs.c index 21b6aab2..f3d3c98b 100644 --- a/tools/mkdfs/mkdfs.c +++ b/tools/mkdfs/mkdfs.c @@ -336,4 +336,4 @@ int main(int argc, char *argv[]) kill_fs(); return 0; -} \ No newline at end of file +}