// For compiling this OS, you need to temporarily remove
// -T "$DIRNAME/../system/ldscript" 
// from nspire-ld

#include <stdint.h>

#define KEY_MAP ((unsigned char *)0x900E0000)
// Bare-metal definition.
#define KEY_ESC_PRESSED (!((*(volatile short*)(KEY_MAP + 0x1C)) & 0x080))

int main(void) {
    void * ptr;
    uint8_t color;
    volatile uint32_t i;

    // Change display memory addr
    //ptr = (void *)0xA4000100;
    ptr = (void *)0x10100000;
    *((void **)0xC0000010) = ptr;
    // Change LCD controller settings:
    //                                                    controller enable, 8 bpp, monochrome, STN, 8-bit interface, single panel
    //                                            RGB, little-endian words, big-endian bytes, LCD power enable
    //*((uint32_t *)0xC000001C) = 0b00000000000000000000110101010111;
    //                                                    controller enable, 4 bpp, monochrome, STN, 8-bit interface, single panel
    //                                            RGB, little-endian words, big-endian bytes, LCD power enable
    //*((uint32_t *)0xC000001C) = 0b00000000000000000000110101010101;
    *((uint32_t *)0xC000001C) |= ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 11)); // 8 bpp

    while (1) {
        for (color = 0; color < 0xFF; color++) {
            __builtin_memset(ptr, color, 320*240);

            for (i = 0; i < 0x1FFFFF; i++);

            if (KEY_ESC_PRESSED) {
                *((uint32_t *)0x900A0008) = 2;
            }
        }
        

        for (color = 0xFF; color > 0; color--) {
            __builtin_memset(ptr, color, 320*240);

            for (i = 0; i < 0x1FFFFF; i++);

            if (KEY_ESC_PRESSED) {
                *((uint32_t *)0x900A0008) = 2;
            }
        }
    }

    __builtin_unreachable();
}
