123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /*
- * Copyright (C) 2018 Tom Li <tomli at tomli.me>.
- *
- * This software is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option) any
- * later version.
- *
- * This software is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * See COPYING for terms and conditions.
- *
- * GPL or LGPL does __not__ require attribution beyond preserving and
- * following the license, but if you find my code is useful or inspirational
- * to your own project, I'd be thankful if you attribute my name.
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <string.h>
- #include "syscalls.h"
- #define VARNAME "TESTVAR"
- #define VARSIZE 35970
- void demo(void);
- __at(0xA5F4) static uint16_t fillrect_color;
- __at(0x4000) static uint8_t bank1[16384];
- int main(void) {
- /* toggle 15 MHz CPU frequency */
- uint8_t orig_cpu = cpuclk_get();
- cpuclk_set(CPUCLK_FULL);
- /* cleanup the screen and reset the cursor */
- clear_screen();
- cursor_row = 0;
- cursor_col = 0;
- /*
- * First example: Hello, world.
- *
- * On different machines, the methods for inputs and outputs are
- * different. SDCC's solution to this problem is defining a prototype
- * for "putchar()", etc, and requiring a user's to supply their own
- * implementation in order to make "printf()", etc, useful.
- *
- * My implementation of "putchar()" can be found in "syscalls.c".
- *
- * NOTE: stdio library is HUGE. This program is less than 900 bytes,
- * but stdio makes it compile to 4000+ bytes! If size and speed matters,
- * don't use stdio library. But for most programs doing simple calculations,
- * it doesn't, feel free to use them.
- */
- printf("Hello, world.\n\n");
- printf("...(press a key)...\n");
- getkey();
- /* second demo */
- demo();
- exit:
- /* wait for a keypress before exit */
- getkey();
- clear_screen();
- /* restore the original CPU frequency */
- cpuclk_set(orig_cpu);
- return 0;
- }
- void demo(void) {
- uint16_t page;
- uint16_t addr;
- /* looking for the Flash page and offset for our APPVAR */
- if (findsym(FINDSYM_APPVAR, VARNAME, &page, &addr) != 0) {
- printf("error:\n");
- printf("cannot find data variable.\n");
- return;
- }
- else {
- /* TODO: add a magic header for sanity check */
- }
- /*
- * Save the original page number in Bank1, and map our page to
- * Bank1 instead.
- */
- uint16_t orig_page = bank1_get();
- bank1_swap(page);
- /* initial x, y position, and maximum x position */
- uint16_t x = 30;
- uint16_t y = 50;
- uint16_t x_max = 255 + x;
- uint16_t idx = addr;
- for (uint16_t i = 0; i < VARSIZE / 3; i++) {
- uint8_t length = bank1[idx];
- idx++;
- if (idx == 0x4000U) {
- page++;
- bank1_swap(page);
- idx = 0;
- }
- uint16_t color = bank1[idx];
- idx++;
- if (idx == 0x4000U) {
- page++;
- bank1_swap(page);
- idx = 0;
- }
- color |= ((bank1[idx]) << 8);
- idx++;
- if (idx == 0x4000U) {
- page++;
- bank1_swap(page);
- idx = 0;
- }
- /*
- * This converts BGR to RGB by swapping the first/last five bits.
- * For the last five bits, we extract and bitshift it to the beginning,
- * and for the first five bits, we extract and bitstift it to the end.
- * Then, we clear the original first and last five bits, and apply the
- * bitshifted version on it to swap them.
- */
- uint16_t tmp = (color & 0x001FU) << 11;
- tmp |= (color & 0xF800U) >> 11;
- color &= 0xFFE0U & 0x07FFU;
- color |= tmp;
- fillrect_color = color;
- uint16_t x_end = x + length;
- if (x_end < x_max) {
- fillrect(x, x_end, y, y + 1);
- x = x_end;
- }
- else if (x_end == x_max) {
- fillrect(x, x_end, y, y + 1);
- x = 30;
- y++;
- }
- else {
- fillrect(x, x_max, y, y + 1);
- x_end -= 255;
- y++;
- fillrect(30, x_end, y, y + 1);
- x = x_end;
- }
- }
- bank1_swap(orig_page);
- }
|