cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

banks_nonintrinsic.c (3080B)


      1#include <gbdk/platform.h>
      2#include <stdint.h>
      3#include <stdio.h>
      4
      5// force bank switching macro
      6uint8_t __dummy_variable;
      7#define switch_to(x) (__dummy_variable = (char)((x)[0]), (void *)(x))
      8
      9uint8_t _current_ram_bank = 0;
     10#define SWITCH_RAM_BANK(x) (_current_ram_bank = (SWITCH_RAM(x), (x)))
     11
     12// constant in base ROM
     13const char const hello0[] = "hello from CODE\n";
     14// variable in base RAM
     15char data[20] = "DATA";
     16int  addendum0 = 1;
     17
     18// constants in ROM banks
     19
     20void set_ROM_bank1(void) NONBANKED { SWITCH_ROM(1); }
     21void set_ROM_bank2(void) NONBANKED { SWITCH_ROM(2); }
     22
     23__addressmod set_ROM_bank1 const CODE_1;
     24__addressmod set_ROM_bank2 const CODE_2;
     25
     26CODE_1 const char hello1[] = "hello from CODE_1\n";
     27CODE_2 const char hello2[] = "hello from CODE_2\n";
     28
     29// variables in RAM banks
     30
     31void set_RAM_bank1(void) NONBANKED { SWITCH_RAM_BANK(0); }
     32void set_RAM_bank2(void) NONBANKED { SWITCH_RAM_BANK(1); }
     33
     34__addressmod set_RAM_bank1 DATA_0;
     35__addressmod set_RAM_bank2 DATA_1;
     36
     37DATA_0 char hello1_ram[20];
     38DATA_0 int  addendum1_ram;
     39DATA_1 char hello2_ram[20];
     40DATA_1 int  addendum2_ram;
     41DATA_1 int  addendum3_ram;
     42
     43// define array of pointers in RAM2 to the variables that are RAM2
     44// there is a flaw in compiler that disallows pointers into banks to be in the other banks
     45// details: https://sourceforge.net/p/sdcc/bugs/2995/
     46DATA_0 int * const CODE_1 addendum_ptr[2] = {&addendum2_ram, &addendum3_ram};
     47
     48void main() {
     49    ENABLE_RAM;
     50
     51    addendum1_ram = 2;
     52    addendum2_ram = 4;
     53    addendum3_ram = 8;
     54
     55    // say hello
     56    for (int8_t i = 0; (hello0[i]); i++) putchar(hello0[i]);  
     57    for (int8_t i = 0; (hello1[i]); i++) putchar(hello1[i]);
     58    for (int8_t i = 0; (hello2[i]); i++) putchar(hello2[i]);
     59
     60    // prepare and say hello from rom bank1 to ram bank0
     61    for (int8_t i = 0; (i < sizeof(hello1)); i++) hello1_ram[i] = hello1[i];
     62    for (int8_t i = 0; (i < 4); i++) hello1_ram[i + 11] = data[i];
     63    for (int8_t i = 0; (hello1_ram[i]); i++) putchar(hello1_ram[i]);
     64
     65    // prepare and say hello from rom bank1 to ram bank1
     66    for (int8_t i = 0; (i < sizeof(hello2)); i++) hello2_ram[i] = hello2[i];
     67    for (int8_t i = 0; (i < 4); i++) hello2_ram[i + 11] = data[i];
     68    for (int8_t i = 0; (hello2_ram[i]); i++) putchar(hello2_ram[i]);
     69
     70    printf("once more...\n");
     71    // hello again; if we access we just access, don't care
     72    for (int8_t i = 0; (hello0[i]); i++) putchar(hello0[i]);  
     73    for (int8_t i = 0; (hello1[i]); i++) putchar(hello1[i]);
     74    for (int8_t i = 0; (hello2[i]); i++) putchar(hello2[i]);
     75    for (int8_t i = 0; (hello1_ram[i]); i++) putchar(hello1_ram[i]);
     76    for (int8_t i = 0; (hello2_ram[i]); i++) putchar(hello2_ram[i]);
     77
     78    printf("once more...\n");
     79    // if we need an address, then we use a macro switch_to()
     80    printf("%s", hello0);
     81    printf("%s", switch_to(hello1));    
     82    printf("%s", switch_to(hello2));
     83    printf("%s", switch_to(hello1_ram));
     84    printf("%s", switch_to(hello2_ram));
     85
     86    printf("1+2+4+8=0x%x", (int)(addendum0 + addendum1_ram + (*addendum_ptr[0]) + (*addendum_ptr[1])));
     87
     88    // stop
     89    while(1);
     90}