Add SD card menu
This commit is contained in:
+267
-224
@@ -46,6 +46,7 @@
|
||||
#include <hardware/dma.h>
|
||||
#include <hardware/spi.h>
|
||||
#include <hardware/sync.h>
|
||||
#include <hardware/flash.h>
|
||||
#include <hardware/timer.h>
|
||||
#include <hardware/vreg.h>
|
||||
#include <pico/bootrom.h>
|
||||
@@ -81,27 +82,29 @@
|
||||
#define GPIO_LED 22
|
||||
|
||||
#if ENABLE_SOUND
|
||||
// Global variables for audio task
|
||||
// stream contains N=AUDIO_SAMPLES samples
|
||||
// each sample is 32 bits
|
||||
// (16 bits for the left channel + 16 bits for the right channel in stereo interleaved format)
|
||||
// This is intended to be played at AUDIO_SAMPLE_RATE Hz
|
||||
uint16_t *stream;
|
||||
/**
|
||||
* Global variables for audio task
|
||||
* stream contains N=AUDIO_SAMPLES samples
|
||||
* each sample is 32 bits
|
||||
* 16 bits for the left channel + 16 bits for the right channel in stereo interleaved format)
|
||||
* This is intended to be played at AUDIO_SAMPLE_RATE Hz
|
||||
*/
|
||||
uint16_t *stream;
|
||||
#endif
|
||||
|
||||
/* DMA channel for LCD communication. */
|
||||
static uint dma_lcd;
|
||||
/* Definition of ROM data variable. Must be declared like:
|
||||
* #include <pico/platform.h>
|
||||
* const unsigned char __in_flash("rom") rom[] = {
|
||||
* ...
|
||||
* };
|
||||
/** Definition of ROM data
|
||||
* We're going to erase and reprogram a region 1Mb from the start of the flash
|
||||
* Once done, we can access this at XIP_BASE + 1Mb.
|
||||
* Game Boy DMG ROM size ranges from 32768 bytes (e.g. Tetris) to 1,048,576 bytes (e.g. Pokemod Red)
|
||||
*/
|
||||
extern const unsigned char rom[];
|
||||
unsigned char rom_bank0[16384];
|
||||
#define FLASH_TARGET_OFFSET (1024 * 1024)
|
||||
const uint8_t *rom = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET);
|
||||
static unsigned char rom_bank0[65536];
|
||||
|
||||
static uint8_t ram[32768];
|
||||
static int lcd_line_busy = 0;
|
||||
static palette_t palette; // Colour palette
|
||||
static uint8_t manual_palette_selected=0;
|
||||
|
||||
static struct
|
||||
{
|
||||
@@ -134,12 +137,6 @@ union core_cmd {
|
||||
uint32_t full;
|
||||
};
|
||||
|
||||
struct gb_priv {
|
||||
uint32_t lcd_line_hashes[LCD_HEIGHT];
|
||||
uint dma_pixel_buffer_chan;
|
||||
};
|
||||
static struct gb_priv gb_priv = { 0 };
|
||||
|
||||
/* Pixel data is stored in here. */
|
||||
static uint8_t pixels_buffer[LCD_WIDTH];
|
||||
|
||||
@@ -223,95 +220,35 @@ void gb_error(struct gb_s *gb, const enum gb_error_e gb_err, const uint16_t addr
|
||||
#endif
|
||||
}
|
||||
|
||||
void core1_irq_dma_lcd_end_transfer(void)
|
||||
{
|
||||
mk_ili9225_write_pixels_end();
|
||||
__atomic_store_n(&lcd_line_busy, 0, __ATOMIC_SEQ_CST);
|
||||
dma_channel_acknowledge_irq0(dma_lcd);
|
||||
}
|
||||
|
||||
#if ENABLE_LCD
|
||||
void core1_lcd_draw_line(const uint_fast8_t line)
|
||||
{
|
||||
static uint16_t fb[LCD_WIDTH];
|
||||
|
||||
//dma_channel_wait_for_finish_blocking(dma_lcd);
|
||||
for(unsigned int x = 0; x < LCD_WIDTH; x++)
|
||||
{
|
||||
fb[x] = palette[(pixels_buffer[x] & LCD_PALETTE_ALL) >> 4]
|
||||
[pixels_buffer[x] & 3];
|
||||
}
|
||||
|
||||
//mk_ili9225_set_address(line + 16, LCD_WIDTH + 30);
|
||||
mk_ili9225_set_x(line + 16);
|
||||
|
||||
#if USE_DMA
|
||||
mk_ili9225_write_pixels_start();
|
||||
dma_channel_transfer_from_buffer_now(dma_lcd, &fb[0], LCD_WIDTH);
|
||||
do {
|
||||
__wfi();
|
||||
} while (dma_channel_is_busy(dma_lcd));
|
||||
__compiler_memory_barrier();
|
||||
#else
|
||||
mk_ili9225_write_pixels(fb, LCD_WIDTH);
|
||||
__atomic_store_n(&lcd_line_busy, 0, __ATOMIC_SEQ_CST);
|
||||
#endif
|
||||
}
|
||||
|
||||
_Noreturn
|
||||
void main_core1(void)
|
||||
{
|
||||
static dma_channel_config c2;
|
||||
uint16_t clear_screen_colour = palette[2][3];
|
||||
union core_cmd cmd;
|
||||
|
||||
/* Initialise and control LCD on core 1. */
|
||||
mk_ili9225_init();
|
||||
|
||||
/* Initilise DMA transfer for clearing the LCD screen. */
|
||||
dma_lcd = dma_claim_unused_channel(true);
|
||||
c2 = dma_channel_get_default_config(dma_lcd);
|
||||
channel_config_set_transfer_data_size(&c2, DMA_SIZE_16);
|
||||
channel_config_set_dreq(&c2,DREQ_SPI0_TX);
|
||||
channel_config_set_read_increment(&c2, false);
|
||||
channel_config_set_write_increment(&c2, false);
|
||||
channel_config_set_ring(&c2, false, 0);
|
||||
|
||||
/* Enable IRQ for wake on interrupt functionality. */
|
||||
/* Use DMA_IRQ_1, DMA_IRQ_0 is already used by the SD Card reader */
|
||||
irq_set_exclusive_handler(DMA_IRQ_1, core1_irq_dma_lcd_end_transfer);
|
||||
dma_channel_set_irq1_enabled(dma_lcd, true);
|
||||
irq_set_enabled(DMA_IRQ_1, true);
|
||||
|
||||
/* Clear LCD screen. */
|
||||
mk_ili9225_write_pixels_start();
|
||||
dma_channel_configure(dma_lcd, &c2, &spi_get_hw(spi0)->dr, &clear_screen_colour,
|
||||
SCREEN_SIZE_X*SCREEN_SIZE_Y+16, true);
|
||||
do {
|
||||
__wfi();
|
||||
} while (dma_channel_is_busy(dma_lcd));
|
||||
__compiler_memory_barrier();
|
||||
|
||||
/* Set DMA transfer to be the length of a DMG line. */
|
||||
dma_channel_set_trans_count(dma_lcd, LCD_WIDTH, false);
|
||||
channel_config_set_read_increment(&c2, true);
|
||||
//dma_sniffer_enable(dma_lcd, 0, true);
|
||||
mk_ili9225_fill(0x0000);
|
||||
|
||||
/* Set LCD window to DMG size. */
|
||||
mk_ili9225_set_window(16, LCD_HEIGHT + 15,
|
||||
31, LCD_WIDTH + 30);
|
||||
mk_ili9225_set_address(16, LCD_WIDTH + 30);
|
||||
//mk_ili9225_set_x(15);
|
||||
|
||||
#if 0
|
||||
/* Clear GB Screen window. */
|
||||
mk_ili9225_write_pixels_start();
|
||||
dma_channel_set_trans_count(dma_lcd, LCD_HEIGHT*LCD_WIDTH+16, false);
|
||||
dma_channel_set_read_addr(dma_lcd, &green, true);
|
||||
/* TODO: Add sleeping wait. */
|
||||
dma_channel_wait_for_finish_blocking(dma_lcd);
|
||||
mk_ili9225_write_pixels_end();
|
||||
#endif
|
||||
mk_ili9225_fill_rect(31,16,LCD_WIDTH,LCD_HEIGHT,0x0000);
|
||||
|
||||
// Sleep used for debugging LCD window.
|
||||
//sleep_ms(1000);
|
||||
@@ -350,18 +287,8 @@ void lcd_draw_line(struct gb_s *gb, const uint8_t pixels[LCD_WIDTH],
|
||||
while(__atomic_load_n(&lcd_line_busy, __ATOMIC_SEQ_CST))
|
||||
tight_loop_contents();
|
||||
|
||||
//memcpy(pixels_buffer, pixels, LCD_WIDTH);
|
||||
dma_hw->sniff_data = 0;
|
||||
//line_to_copy = line;
|
||||
dma_channel_set_read_addr(gb_priv.dma_pixel_buffer_chan, pixels, false);
|
||||
dma_channel_set_write_addr(gb_priv.dma_pixel_buffer_chan, pixels_buffer, true);
|
||||
dma_channel_wait_for_finish_blocking(gb_priv.dma_pixel_buffer_chan);
|
||||
|
||||
if(gb_priv.lcd_line_hashes[line] == dma_hw->sniff_data)
|
||||
return;
|
||||
|
||||
gb_priv.lcd_line_hashes[line] = dma_hw->sniff_data;
|
||||
|
||||
memcpy(pixels_buffer, pixels, LCD_WIDTH);
|
||||
|
||||
/* Populate command. */
|
||||
cmd.cmd = CORE_CMD_LCD_LINE;
|
||||
cmd.data = line;
|
||||
@@ -372,11 +299,13 @@ void lcd_draw_line(struct gb_s *gb, const uint8_t pixels[LCD_WIDTH],
|
||||
#endif
|
||||
|
||||
#if ENABLE_SDCARD
|
||||
/**
|
||||
* Load a save file from the SD card
|
||||
*/
|
||||
void read_cart_ram_file(struct gb_s *gb) {
|
||||
/* Load Save File. */
|
||||
char filename[16];
|
||||
uint_fast32_t save_size;
|
||||
UINT bw;
|
||||
UINT br;
|
||||
|
||||
gb_get_rom_name(gb,filename);
|
||||
save_size=gb_get_save_size(gb);
|
||||
@@ -391,7 +320,7 @@ void read_cart_ram_file(struct gb_s *gb) {
|
||||
FIL fil;
|
||||
fr=f_open(&fil,filename,FA_READ);
|
||||
if (fr==FR_OK) {
|
||||
f_read(&fil,ram,save_size,&bw);
|
||||
f_read(&fil,ram,f_size(&fil),&br);
|
||||
} else {
|
||||
printf("f_open(%s) error: %s (%d)\n",filename,FRESULT_str(fr),fr);
|
||||
}
|
||||
@@ -402,25 +331,12 @@ void read_cart_ram_file(struct gb_s *gb) {
|
||||
}
|
||||
f_unmount(pSD->pcName);
|
||||
}
|
||||
|
||||
/** Set the RTC of the game cartridge. Only used by games that support it.
|
||||
* You could potentially force the game to allow the player to
|
||||
* reset the time by setting the RTC to invalid values.
|
||||
*
|
||||
* Using memset(&gb->cart_rtc, 0xFF, sizeof(gb->cart_rtc)) for
|
||||
* example causes Pokemon Gold/Silver to say "TIME NOT SET",
|
||||
* allowing the player to set the time without having some dumb
|
||||
* password.
|
||||
*
|
||||
* The memset has to be done directly to gb->cart_rtc because
|
||||
* gb_set_rtc() processes the input values, which may cause
|
||||
* games to not detect invalid values.
|
||||
*/
|
||||
memset(gb->cart_rtc, 0xFF, sizeof(gb->cart_rtc));
|
||||
|
||||
printf("read_cart_ram_file(%s) COMPLETE (%lu bytes)\n",filename,save_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a save file to the SD card
|
||||
*/
|
||||
void write_cart_ram_file(struct gb_s *gb) {
|
||||
char filename[16];
|
||||
uint_fast32_t save_size;
|
||||
@@ -452,6 +368,179 @@ void write_cart_ram_file(struct gb_s *gb) {
|
||||
}
|
||||
printf("write_cart_ram_file(%s) COMPLETE (%lu bytes)\n",filename,save_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a .gb rom file in flash from the SD card
|
||||
*/
|
||||
void load_cart_rom_file(char *filename) {
|
||||
UINT br;
|
||||
uint8_t buffer[FLASH_SECTOR_SIZE];
|
||||
sd_card_t *pSD=sd_get_by_num(0);
|
||||
FRESULT fr=f_mount(&pSD->fatfs,pSD->pcName,1);
|
||||
if (FR_OK!=fr) {
|
||||
printf("f_mount error: %s (%d)\n",FRESULT_str(fr),fr);
|
||||
return;
|
||||
}
|
||||
FIL fil;
|
||||
fr=f_open(&fil,filename,FA_READ);
|
||||
if (fr==FR_OK) {
|
||||
uint32_t flash_target_offset=FLASH_TARGET_OFFSET;
|
||||
for(;;) {
|
||||
f_read(&fil,buffer,sizeof buffer,&br);
|
||||
if(br==0) break; /* end of file */
|
||||
|
||||
printf("\nErasing target region...\n");
|
||||
flash_range_erase(flash_target_offset,FLASH_SECTOR_SIZE);
|
||||
printf("\nProgramming target region...\n");
|
||||
flash_range_program(flash_target_offset,buffer,FLASH_SECTOR_SIZE);
|
||||
flash_target_offset+=FLASH_SECTOR_SIZE;
|
||||
}
|
||||
} else {
|
||||
printf("f_open(%s) error: %s (%d)\n",filename,FRESULT_str(fr),fr);
|
||||
}
|
||||
|
||||
fr=f_close(&fil);
|
||||
if(fr!=FR_OK) {
|
||||
printf("f_close error: %s (%d)\n", FRESULT_str(fr), fr);
|
||||
}
|
||||
f_unmount(pSD->pcName);
|
||||
|
||||
printf("load_cart_rom_file(%s) COMPLETE (%lu bytes)\n",filename,br);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used by the rom file selector to display one page of .gb rom files
|
||||
*/
|
||||
uint16_t rom_file_selector_display_page(char filename[22][256],uint16_t num_page) {
|
||||
sd_card_t *pSD=sd_get_by_num(0);
|
||||
DIR dj;
|
||||
FILINFO fno;
|
||||
FRESULT fr;
|
||||
|
||||
fr=f_mount(&pSD->fatfs,pSD->pcName,1);
|
||||
if (FR_OK!=fr) {
|
||||
printf("f_mount error: %s (%d)\n",FRESULT_str(fr),fr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clear the filenames array */
|
||||
for(uint8_t ifile=0;ifile<22;ifile++) {
|
||||
strcpy(filename[ifile],"");
|
||||
}
|
||||
|
||||
/* search *.gb files */
|
||||
uint16_t num_file=0;
|
||||
fr=f_findfirst(&dj, &fno, "", "*.gb");
|
||||
|
||||
/* skip the first N pages */
|
||||
if(num_page>0) {
|
||||
while(num_file<num_page*22 && fr == FR_OK && fno.fname[0]) {
|
||||
num_file++;
|
||||
fr=f_findnext(&dj, &fno);
|
||||
}
|
||||
}
|
||||
|
||||
/* store the filenames of this page */
|
||||
num_file=0;
|
||||
while(num_file<22 && fr == FR_OK && fno.fname[0]) {
|
||||
strcpy(filename[num_file],fno.fname);
|
||||
num_file++;
|
||||
fr=f_findnext(&dj, &fno);
|
||||
}
|
||||
f_closedir(&dj);
|
||||
f_unmount(pSD->pcName);
|
||||
|
||||
/* display *.gb rom files on screen */
|
||||
mk_ili9225_fill(0x0000);
|
||||
for(uint8_t ifile=0;ifile<num_file;ifile++) {
|
||||
mk_ili9225_text(filename[ifile],0,ifile*8,0xFFFF,0x0000);
|
||||
}
|
||||
return num_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ROM selector displays pages of up to 22 rom files
|
||||
* allowing the user to select which rom file to start
|
||||
* Copy your *.gb rom files to the root directory of the SD card
|
||||
*/
|
||||
void rom_file_selector() {
|
||||
uint16_t num_page;
|
||||
char filename[22][256];
|
||||
uint16_t num_file;
|
||||
|
||||
/* display the first page with up to 22 rom files */
|
||||
num_file=rom_file_selector_display_page(filename,num_page);
|
||||
|
||||
/* select the first rom */
|
||||
uint8_t selected=0;
|
||||
mk_ili9225_text(filename[selected],0,selected*8,0xFFFF,0xF800);
|
||||
|
||||
/* get user's input */
|
||||
bool up,down,left,right,a,b,select,start;
|
||||
while(true) {
|
||||
up=gpio_get(GPIO_UP);
|
||||
down=gpio_get(GPIO_DOWN);
|
||||
left=gpio_get(GPIO_LEFT);
|
||||
right=gpio_get(GPIO_RIGHT);
|
||||
a=gpio_get(GPIO_A);
|
||||
b=gpio_get(GPIO_B);
|
||||
select=gpio_get(GPIO_SELECT);
|
||||
start=gpio_get(GPIO_START);
|
||||
if(!start) {
|
||||
/* re-start the last game (no need to reprogram flash) */
|
||||
break;
|
||||
}
|
||||
if(!a | !b) {
|
||||
/* copy the rom from the SD card to flash and start the game */
|
||||
load_cart_rom_file(filename[selected]);
|
||||
break;
|
||||
}
|
||||
if(!down) {
|
||||
/* select the next rom */
|
||||
mk_ili9225_text(filename[selected],0,selected*8,0xFFFF,0x0000);
|
||||
selected++;
|
||||
if(selected>=num_file) selected=0;
|
||||
mk_ili9225_text(filename[selected],0,selected*8,0xFFFF,0xF800);
|
||||
sleep_ms(150);
|
||||
}
|
||||
if(!up) {
|
||||
/* select the previous rom */
|
||||
mk_ili9225_text(filename[selected],0,selected*8,0xFFFF,0x0000);
|
||||
if(selected==0) {
|
||||
selected=num_file-1;
|
||||
} else {
|
||||
selected--;
|
||||
}
|
||||
mk_ili9225_text(filename[selected],0,selected*8,0xFFFF,0xF800);
|
||||
sleep_ms(150);
|
||||
}
|
||||
if(!right) {
|
||||
/* select the next page */
|
||||
num_page++;
|
||||
num_file=rom_file_selector_display_page(filename,num_page);
|
||||
if(num_file==0) {
|
||||
/* no files in this page, go to the previous page */
|
||||
num_page--;
|
||||
num_file=rom_file_selector_display_page(filename,num_page);
|
||||
}
|
||||
/* select the first file */
|
||||
selected=0;
|
||||
mk_ili9225_text(filename[selected],0,selected*8,0xFFFF,0xF800);
|
||||
sleep_ms(150);
|
||||
}
|
||||
if((!left) && num_page>0) {
|
||||
/* select the previous page */
|
||||
num_page--;
|
||||
num_file=rom_file_selector_display_page(filename,num_page);
|
||||
/* select the first file */
|
||||
selected=0;
|
||||
mk_ili9225_text(filename[selected],0,selected*8,0xFFFF,0xF800);
|
||||
sleep_ms(150);
|
||||
}
|
||||
tight_loop_contents();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
@@ -523,106 +612,9 @@ int main(void)
|
||||
spi_init(spi0, 30*1000*1000);
|
||||
spi_set_format(spi0, 16, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
|
||||
|
||||
/* Initialise GB context. */
|
||||
memcpy(rom_bank0, rom, sizeof(rom_bank0));
|
||||
|
||||
ret = gb_init(&gb, &gb_rom_read, &gb_cart_ram_read,
|
||||
&gb_cart_ram_write, &gb_error, &gb_priv);
|
||||
putstdio("GB ");
|
||||
|
||||
if(ret != GB_INIT_NO_ERROR)
|
||||
{
|
||||
printf("Error: %d\n", ret);
|
||||
goto sleep;
|
||||
}
|
||||
|
||||
#if ENABLE_SDCARD
|
||||
/* Load Save File. */
|
||||
read_cart_ram_file(&gb);
|
||||
#endif
|
||||
|
||||
/* Update buttons state */
|
||||
gb.direct.joypad_bits.up=gpio_get(GPIO_UP);
|
||||
gb.direct.joypad_bits.down=gpio_get(GPIO_DOWN);
|
||||
gb.direct.joypad_bits.left=gpio_get(GPIO_LEFT);
|
||||
gb.direct.joypad_bits.right=gpio_get(GPIO_RIGHT);
|
||||
gb.direct.joypad_bits.a=gpio_get(GPIO_A);
|
||||
gb.direct.joypad_bits.b=gpio_get(GPIO_B);
|
||||
gb.direct.joypad_bits.select=gpio_get(GPIO_SELECT);
|
||||
gb.direct.joypad_bits.start=gpio_get(GPIO_START);
|
||||
|
||||
/* manually assign a palette with button combo */
|
||||
|
||||
if(!gb.direct.joypad_bits.a && !gb.direct.joypad_bits.up) {
|
||||
get_colour_palette(palette,0x10,0x05); /* A + Up */
|
||||
} else if(!gb.direct.joypad_bits.a && !gb.direct.joypad_bits.down) {
|
||||
get_colour_palette(palette,0x07,0x00); /* A + Down */
|
||||
} else if(!gb.direct.joypad_bits.a && !gb.direct.joypad_bits.right) {
|
||||
get_colour_palette(palette,0x1C,0x03); /* A + Right */
|
||||
} else if(!gb.direct.joypad_bits.a && !gb.direct.joypad_bits.left) {
|
||||
get_colour_palette(palette,0x0D,0x05); /* A + Left */
|
||||
} else if(!gb.direct.joypad_bits.b && !gb.direct.joypad_bits.up) {
|
||||
get_colour_palette(palette,0x19,0x03); /* B + Up */
|
||||
} else if(!gb.direct.joypad_bits.b && !gb.direct.joypad_bits.down) {
|
||||
get_colour_palette(palette,0x1A,0x05); /* B + Down */
|
||||
} else if(!gb.direct.joypad_bits.b && !gb.direct.joypad_bits.right) {
|
||||
get_colour_palette(palette,0x13,0x00); /* B + Right */
|
||||
} else if(!gb.direct.joypad_bits.b && !gb.direct.joypad_bits.left) {
|
||||
get_colour_palette(palette,0x16,0x00); /* B + Left (Game Boy Pocket Palette, shades of gray) */
|
||||
} else if(!gb.direct.joypad_bits.up) {
|
||||
get_colour_palette(palette,0x12,0x00); /* Up */
|
||||
} else if(!gb.direct.joypad_bits.down) {
|
||||
get_colour_palette(palette,0x17,0x00); /* Down */
|
||||
} else if(!gb.direct.joypad_bits.right) {
|
||||
get_colour_palette(palette,0x05,0x00); /* Right */
|
||||
} else if(!gb.direct.joypad_bits.left) {
|
||||
get_colour_palette(palette,0x18,0x05); /* Left */
|
||||
} else if(!gb.direct.joypad_bits.a && !gb.direct.joypad_bits.b) {
|
||||
get_colour_palette(palette,0xFF,0xFF); /* A + B */
|
||||
} else {
|
||||
/* Automatically assign a colour palette to the game */
|
||||
char rom_title[16];
|
||||
auto_assign_palette(palette, gb_colour_hash(&gb),gb_get_rom_name(&gb,rom_title));
|
||||
}
|
||||
|
||||
#if ENABLE_LCD
|
||||
gb_init_lcd(&gb, &lcd_draw_line);
|
||||
{
|
||||
/* Start Core1, which processes requests to the LCD. */
|
||||
putstdio("CORE1 ");
|
||||
multicore_launch_core1(main_core1);
|
||||
|
||||
/* initialise pixel buffer copy DMA. */
|
||||
static dma_channel_config dma_config;
|
||||
gb_priv.dma_pixel_buffer_chan = dma_claim_unused_channel(true);
|
||||
dma_config = dma_channel_get_default_config(gb_priv.dma_pixel_buffer_chan);
|
||||
channel_config_set_transfer_data_size(&dma_config, DMA_SIZE_32);
|
||||
channel_config_set_read_increment(&dma_config, true);
|
||||
channel_config_set_write_increment(&dma_config, true);
|
||||
dma_sniffer_enable(gb_priv.dma_pixel_buffer_chan, 0x0, true);
|
||||
channel_config_set_sniff_enable(&dma_config, true);
|
||||
|
||||
#if 0
|
||||
irq_set_exclusive_handler(DMA_IRQ_1, core0_irq_dma_lcd_line_copy);
|
||||
dma_channel_set_irq1_enabled(gb_priv.dma_pixel_buffer_chan, true);
|
||||
irq_set_enabled(DMA_IRQ_1, true);
|
||||
#endif
|
||||
|
||||
dma_channel_configure(
|
||||
gb_priv.dma_pixel_buffer_chan,
|
||||
&dma_config,
|
||||
pixels_buffer,
|
||||
0, /* We don't have a pointer to the pixel buffer here. */
|
||||
LCD_WIDTH/sizeof(uint32_t),
|
||||
false
|
||||
);
|
||||
}
|
||||
putstdio("LCD ");
|
||||
//gb.direct.interlace = 1;
|
||||
#endif
|
||||
#if ENABLE_SOUND
|
||||
// Allocate memory for the stream buffer
|
||||
stream=malloc(AUDIO_BUFFER_SIZE_BYTES);
|
||||
stream=malloc(AUDIO_BUFFER_SIZE_BYTES);
|
||||
assert(stream!=NULL);
|
||||
memset(stream,0,AUDIO_BUFFER_SIZE_BYTES); // Zero out the stream buffer
|
||||
|
||||
@@ -632,7 +624,51 @@ int main(void)
|
||||
i2s_config.dma_trans_count =AUDIO_SAMPLES;
|
||||
i2s_volume(&i2s_config,2);
|
||||
i2s_init(&i2s_config);
|
||||
#endif
|
||||
|
||||
while(true)
|
||||
{
|
||||
#if ENABLE_LCD
|
||||
#if ENABLE_SDCARD
|
||||
/* ROM File selector */
|
||||
mk_ili9225_init();
|
||||
mk_ili9225_fill(0x0000);
|
||||
rom_file_selector();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Initialise GB context. */
|
||||
memcpy(rom_bank0, rom, sizeof(rom_bank0));
|
||||
ret = gb_init(&gb, &gb_rom_read, &gb_cart_ram_read,
|
||||
&gb_cart_ram_write, &gb_error, NULL);
|
||||
putstdio("GB ");
|
||||
|
||||
if(ret != GB_INIT_NO_ERROR)
|
||||
{
|
||||
printf("Error: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if ENABLE_SDCARD
|
||||
/* Load Save File. */
|
||||
read_cart_ram_file(&gb);
|
||||
#endif
|
||||
|
||||
/* Automatically assign a colour palette to the game */
|
||||
char rom_title[16];
|
||||
auto_assign_palette(palette, gb_colour_hash(&gb),gb_get_rom_name(&gb,rom_title));
|
||||
|
||||
#if ENABLE_LCD
|
||||
gb_init_lcd(&gb, &lcd_draw_line);
|
||||
|
||||
/* Start Core1, which processes requests to the LCD. */
|
||||
putstdio("CORE1 ");
|
||||
multicore_launch_core1(main_core1);
|
||||
|
||||
putstdio("LCD ");
|
||||
#endif
|
||||
|
||||
#if ENABLE_SOUND
|
||||
// Initialize audio emulation
|
||||
audio_init();
|
||||
|
||||
@@ -689,11 +725,25 @@ int main(void)
|
||||
i2s_decrease_volume(&i2s_config);
|
||||
}
|
||||
#endif
|
||||
if(!gb.direct.joypad_bits.right && prev_joypad_bits.right) {
|
||||
/* select + right */
|
||||
if(manual_palette_selected<12) {
|
||||
manual_palette_selected++;
|
||||
manual_assign_palette(palette,manual_palette_selected);
|
||||
}
|
||||
}
|
||||
if(!gb.direct.joypad_bits.left && prev_joypad_bits.left) {
|
||||
/* select + left */
|
||||
if(manual_palette_selected>0) {
|
||||
manual_palette_selected--;
|
||||
manual_assign_palette(palette,manual_palette_selected);
|
||||
}
|
||||
}
|
||||
if(!gb.direct.joypad_bits.start && prev_joypad_bits.start) {
|
||||
#if ENABLE_SDCARD
|
||||
write_cart_ram_file(&gb);
|
||||
#endif
|
||||
gb_reset(&gb);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -819,17 +869,10 @@ int main(void)
|
||||
}
|
||||
}
|
||||
out:
|
||||
|
||||
puts("\nEmulation Ended");
|
||||
/* stop lcd task running on core 1 */
|
||||
multicore_reset_core1();
|
||||
|
||||
}
|
||||
|
||||
mk_ili9225_set_rst(true);
|
||||
reset_usb_boot(0, 0);
|
||||
|
||||
/* Sleep forever. */
|
||||
sleep:
|
||||
stdio_flush();
|
||||
while(1)
|
||||
__wfi();
|
||||
|
||||
HEDLEY_UNREACHABLE();
|
||||
}
|
||||
|
||||
+738
-1
@@ -392,7 +392,7 @@ unsigned mk_ili9225_init(void)
|
||||
{ MK_ILI9225_REG_LCD_AC_DRIVING_CTRL, 0x0100 },
|
||||
/* Increment vertical and horizontal address.
|
||||
* Use vertical image. */
|
||||
{ MK_ILI9225_REG_ENTRY_MODE, 0x1008 },
|
||||
{ MK_ILI9225_REG_ENTRY_MODE, 0x1018 },
|
||||
/* Turn off all display outputs. */
|
||||
{ MK_ILI9225_REG_DISPLAY_CTRL, 0x0000 },
|
||||
/* Set porches to 8 lines. */
|
||||
@@ -558,3 +558,740 @@ void mk_ili9225_set_drive_freq(uint16_t f)
|
||||
void mk_ili9225_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void mk_ili9225_fill_rect(uint8_t x,uint8_t y,uint8_t w,uint8_t h,uint16_t color)
|
||||
{
|
||||
set_register(MK_ILI9225_REG_ENTRY_MODE,0x1018);
|
||||
set_register(MK_ILI9225_REG_HORI_WIN_ADDR1, y+h-1); // y_max
|
||||
set_register(MK_ILI9225_REG_HORI_WIN_ADDR2, y); // y_min
|
||||
set_register(MK_ILI9225_REG_VERT_WIN_ADDR1, 219-x); // x_max
|
||||
set_register(MK_ILI9225_REG_VERT_WIN_ADDR2, 219-(x+w-1)); // x_min
|
||||
set_register(MK_ILI9225_REG_RAM_ADDR_SET1,y);
|
||||
set_register(MK_ILI9225_REG_RAM_ADDR_SET2,219-x);
|
||||
write_register(MK_ILI9225_REG_GRAM_RW);
|
||||
mk_ili9225_set_rs(1);
|
||||
mk_ili9225_set_cs(0);
|
||||
for(uint16_t i=0;i<w*h;i++) {
|
||||
mk_ili9225_spi_write16(&color,1);
|
||||
}
|
||||
mk_ili9225_set_cs(1);
|
||||
}
|
||||
|
||||
void mk_ili9225_fill(uint16_t color)
|
||||
{
|
||||
mk_ili9225_fill_rect(0,0,220,176,color);
|
||||
}
|
||||
|
||||
void mk_ili9225_pixel(uint8_t x,uint8_t y,uint16_t color)
|
||||
{
|
||||
set_register(MK_ILI9225_REG_RAM_ADDR_SET1,y);
|
||||
set_register(MK_ILI9225_REG_RAM_ADDR_SET2,219-x);
|
||||
set_register(MK_ILI9225_REG_GRAM_RW,color);
|
||||
}
|
||||
|
||||
void mk_ili9225_blit(uint16_t *fbuf,uint8_t x,uint8_t y,uint8_t w,uint8_t h) {
|
||||
set_register(MK_ILI9225_REG_ENTRY_MODE,0x1018);
|
||||
set_register(MK_ILI9225_REG_HORI_WIN_ADDR1, y+h-1); // y_max
|
||||
set_register(MK_ILI9225_REG_HORI_WIN_ADDR2, y); // y_min
|
||||
set_register(MK_ILI9225_REG_VERT_WIN_ADDR1, 219-x); // x_max
|
||||
set_register(MK_ILI9225_REG_VERT_WIN_ADDR2, 219-(x+w-1)); // x_min
|
||||
set_register(MK_ILI9225_REG_RAM_ADDR_SET1,y);
|
||||
set_register(MK_ILI9225_REG_RAM_ADDR_SET2,219-x);
|
||||
write_register(MK_ILI9225_REG_GRAM_RW);
|
||||
mk_ili9225_set_rs(1);
|
||||
mk_ili9225_set_cs(0);
|
||||
mk_ili9225_spi_write16(fbuf,w*h);
|
||||
mk_ili9225_set_cs(1);
|
||||
}
|
||||
|
||||
void mk_ili9225_get_letter(uint16_t *fbuf,char l,uint16_t color,uint16_t bgcolor) {
|
||||
uint8_t letter[8];
|
||||
uint8_t row;
|
||||
|
||||
switch(l)
|
||||
{
|
||||
case 'a':
|
||||
case 'A':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01111110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'b':
|
||||
case 'B':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00011110,
|
||||
0b00110000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b00110000,
|
||||
0b00011110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111000,
|
||||
0b01101100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01101100,
|
||||
0b01111000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111110,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01111000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01111110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111110,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01111000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b01100000,
|
||||
0b01101110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'h':
|
||||
case 'H':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01111110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'i':
|
||||
case 'I':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'j':
|
||||
case 'J':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00000110,
|
||||
0b00000110,
|
||||
0b00000110,
|
||||
0b00000110,
|
||||
0b00000110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
{
|
||||
const uint8_t letter_[8]={0b11000110,
|
||||
0b11001100,
|
||||
0b11011000,
|
||||
0b11110000,
|
||||
0b11011000,
|
||||
0b11001100,
|
||||
0b11000110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'l':
|
||||
case 'L':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01100000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01111110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
{
|
||||
const uint8_t letter_[8]={0b11000110,
|
||||
0b11101110,
|
||||
0b11111110,
|
||||
0b11010110,
|
||||
0b11000110,
|
||||
0b11000110,
|
||||
0b11000110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'n':
|
||||
case 'N':
|
||||
{
|
||||
const uint8_t letter_[8]={0b11000110,
|
||||
0b11100110,
|
||||
0b11110110,
|
||||
0b11011110,
|
||||
0b11001110,
|
||||
0b11000110,
|
||||
0b11000110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'o':
|
||||
case 'O':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
case 'P':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01111100,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b01100000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
case 'Q':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111000,
|
||||
0b11001100,
|
||||
0b11001100,
|
||||
0b11001100,
|
||||
0b11001100,
|
||||
0b11011100,
|
||||
0b01111110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'r':
|
||||
case 'R':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01111100,
|
||||
0b01101100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b01110000,
|
||||
0b00111100,
|
||||
0b00001110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111110,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00111100,
|
||||
0b00011000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'w':
|
||||
case 'W':
|
||||
{
|
||||
const uint8_t letter_[8]={0b11000110,
|
||||
0b11000110,
|
||||
0b11000110,
|
||||
0b11010110,
|
||||
0b11111110,
|
||||
0b11101110,
|
||||
0b11000110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
{
|
||||
const uint8_t letter_[8]={0b11000011,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00011000,
|
||||
0b00111100,
|
||||
0b01100110,
|
||||
0b11000011,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'y':
|
||||
case 'Y':
|
||||
{
|
||||
const uint8_t letter_[8]={0b11000011,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'z':
|
||||
case 'Z':
|
||||
{
|
||||
const uint8_t letter_[8]={0b11111110,
|
||||
0b00001100,
|
||||
0b00011000,
|
||||
0b00110000,
|
||||
0b01100000,
|
||||
0b11000000,
|
||||
0b11111110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '-':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b01111110,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00001100,
|
||||
0b00011000,
|
||||
0b00110000,
|
||||
0b00110000,
|
||||
0b00110000,
|
||||
0b00011000,
|
||||
0b00001100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00110000,
|
||||
0b00011000,
|
||||
0b00001100,
|
||||
0b00001100,
|
||||
0b00001100,
|
||||
0b00011000,
|
||||
0b00110000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case ',':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00110000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '.':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '!':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00000000,
|
||||
0b00011000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '&':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111000,
|
||||
0b01101100,
|
||||
0b01101000,
|
||||
0b01110110,
|
||||
0b11011100,
|
||||
0b11001110,
|
||||
0b01111011,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '\'':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00011000,
|
||||
0b00011000,
|
||||
0b00110000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '0':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b01101110,
|
||||
0b01111110,
|
||||
0b01110110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '1':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00011000,
|
||||
0b00111000,
|
||||
0b01111000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '2':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b00000110,
|
||||
0b00001100,
|
||||
0b00011000,
|
||||
0b00110000,
|
||||
0b01111110,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '3':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b00000110,
|
||||
0b00011100,
|
||||
0b00000110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '4':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00011100,
|
||||
0b00111100,
|
||||
0b01101100,
|
||||
0b11001100,
|
||||
0b11111110,
|
||||
0b00001100,
|
||||
0b00001100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '5':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111110,
|
||||
0b01100000,
|
||||
0b01111100,
|
||||
0b00000110,
|
||||
0b00000110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '6':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00011100,
|
||||
0b00110000,
|
||||
0b01100000,
|
||||
0b01111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '7':
|
||||
{
|
||||
const uint8_t letter_[8]={0b01111110,
|
||||
0b00000110,
|
||||
0b00000110,
|
||||
0b00001100,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00011000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '8':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111100,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
case '9':
|
||||
{
|
||||
const uint8_t letter_[8]={0b00111100,
|
||||
0b01100110,
|
||||
0b01100110,
|
||||
0b00111110,
|
||||
0b00000110,
|
||||
0b00001100,
|
||||
0b00111000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
const uint8_t letter_[8]={0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000,
|
||||
0b00000000};
|
||||
memcpy(letter,letter_,8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint8_t y=0;y<8;y++) {
|
||||
row=letter[y];
|
||||
for(uint8_t x=0;x<8;x++) {
|
||||
if(row & 128) {
|
||||
fbuf[y*8+x]=color;
|
||||
} else {
|
||||
fbuf[y*8+x]=bgcolor;
|
||||
}
|
||||
row=row<<1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mk_ili9225_text(char *s,uint8_t x,uint8_t y,uint16_t color,uint16_t bgcolor) {
|
||||
uint16_t fbuf[8*8];
|
||||
for(uint8_t i=0;i<strlen(s);i++) {
|
||||
mk_ili9225_get_letter(fbuf,s[i],color,bgcolor);
|
||||
mk_ili9225_blit(fbuf,x,y,8,8);
|
||||
x+=8;
|
||||
if(x>27*8) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user