diff --git a/MCUME_pico/CMakeLists.txt b/MCUME_pico/CMakeLists.txt index ede7792..cac7477 100644 --- a/MCUME_pico/CMakeLists.txt +++ b/MCUME_pico/CMakeLists.txt @@ -16,7 +16,9 @@ pico_sdk_init() add_subdirectory(FatFs_SPI build) +include_directories(config) include_directories(vga_t4) +include_directories(tft_t) set(PICO81_SOURCES @@ -216,7 +218,10 @@ set(PICOSND_SOURCES set(VGA_T4_SOURCES vga_t4/VGA_t4.cpp vga_t4/scanvideo.c -# vga_t4/vga_modes.c + ) + +set(TFT_T_SOURCES + tft_t/tft_t_dma.cpp ) set(GFXENGINE_SOURCES @@ -232,13 +237,18 @@ set(TESTVGA_SOURCES testvga/testvga.cpp ) +set(TESTTFT_SOURCES + testtft/testtft.cpp + testtft/emuapi.cpp + ) + add_executable(mcume - ${GFXENGINE_SOURCES} +# ${GFXENGINE_SOURCES} # ${PICO81_SOURCES} +# ${PICOSPECCY_SOURCES} # ${PICO800_SOURCES} # ${PICO5200_SOURCES} -# ${PICOSPECCY_SOURCES} -# ${PICO64_SOURCES} + ${PICO64_SOURCES} # ${PICOCOLEM_SOURCES} # ${PICOO2EM_SOURCES} # ${PICOVCS_SOURCES} @@ -246,7 +256,9 @@ add_executable(mcume # ${PICOSND_SOURCES} # ${TESTIO_SOURCES} # ${TESTVGA_SOURCES} +# ${TESTTFT_SOURCES} ${VGA_T4_SOURCES} + ${TFT_T_SOURCES} ) pico_generate_pio_header(mcume ${CMAKE_CURRENT_LIST_DIR}/vga_t4/timing.pio) @@ -272,6 +284,6 @@ target_compile_definitions(mcume PUBLIC DEBUG N_SD_CARDS=${N_SD_CARDS}) #pico_enable_stdio_uart(mcume 0) -#pico_enable_stdio_usb(mcume 1) +pico_enable_stdio_usb(mcume 1) pico_add_extra_outputs(mcume) diff --git a/MCUME_pico/FatFs_SPI/.DS_Store b/MCUME_pico/FatFs_SPI/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/MCUME_pico/FatFs_SPI/.DS_Store and /dev/null differ diff --git a/MCUME_pico/FatFs_SPI/sd_driver/hw_config.c b/MCUME_pico/FatFs_SPI/sd_driver/hw_config.c index 1868f8c..c1620d0 100755 --- a/MCUME_pico/FatFs_SPI/sd_driver/hw_config.c +++ b/MCUME_pico/FatFs_SPI/sd_driver/hw_config.c @@ -26,6 +26,8 @@ socket, which SPI it is driven by, and how it is wired. // #include "my_debug.h" // +#include "iopins.h" + #include "hw_config.h" void spi0_dma_isr(); @@ -35,10 +37,10 @@ void spi0_dma_isr(); // selects. static spi_t spis[] = { // One for each SPI. { - .hw_inst = spi0, // SPI component - .miso_gpio = 16, - .mosi_gpio = 19, - .sck_gpio = 18, + .hw_inst = SD_SPIREG, // SPI component + .miso_gpio = SD_MISO, + .mosi_gpio = SD_MOSI, + .sck_gpio = SD_SCLK, /* The choice of SD card matters! SanDisk runs at the highest speed. PNY can only mangage 5 MHz. Those are all I've tried. */ .baud_rate = 1000 * 1000, @@ -56,8 +58,8 @@ static sd_card_t sd_cards[] = { // One for each SD card { .pcName = "0:", // Name used to mount device .spi = &spis[0], // Pointer to the SPI driving this card - .ss_gpio = 17, // The SPI slave select GPIO for this SD card - .card_detect_gpio = 22, // Card detect + .ss_gpio = SD_CS, // The SPI slave select GPIO for this SD card + .card_detect_gpio = SD_DETECT, // Card detect .card_detected_true = 1, // What the GPIO read returns when a card is // present. Use -1 if there is no card detect. // Following attributes are dynamically assigned diff --git a/MCUME_pico/bin/mcume_gfxengine.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_gfxengine.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_gfxengine.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_gfxengine.uf2 diff --git a/MCUME_pico/bin/mcume_pico5200.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_pico5200.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_pico5200.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_pico5200.uf2 diff --git a/MCUME_pico/bin/mcume_pico64.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_pico64.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_pico64.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_pico64.uf2 diff --git a/MCUME_pico/bin/mcume_pico800.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_pico800.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_pico800.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_pico800.uf2 diff --git a/MCUME_pico/bin/mcume_pico81.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_pico81.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_pico81.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_pico81.uf2 diff --git a/MCUME_pico/bin/mcume_picocolem.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_picocolem.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_picocolem.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_picocolem.uf2 diff --git a/MCUME_pico/bin/mcume_picoo2em.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_picoo2em.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_picoo2em.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_picoo2em.uf2 diff --git a/MCUME_pico/bin/mcume_picosnd.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_picosnd.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_picosnd.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_picosnd.uf2 diff --git a/MCUME_pico/bin/mcume_picospeccy.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_picospeccy.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_picospeccy.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_picospeccy.uf2 diff --git a/MCUME_pico/bin/mcume_picovcs.uf2 b/MCUME_pico/bin/MCUME_REV1/mcume_picovcs.uf2 similarity index 100% rename from MCUME_pico/bin/mcume_picovcs.uf2 rename to MCUME_pico/bin/MCUME_REV1/mcume_picovcs.uf2 diff --git a/MCUME_pico/bin/PICOMPUTER/mcume_pico64.uf2 b/MCUME_pico/bin/PICOMPUTER/mcume_pico64.uf2 new file mode 100644 index 0000000..4ff2702 Binary files /dev/null and b/MCUME_pico/bin/PICOMPUTER/mcume_pico64.uf2 differ diff --git a/MCUME_pico/bin/PICOMPUTER/mcume_pico800.uf2 b/MCUME_pico/bin/PICOMPUTER/mcume_pico800.uf2 new file mode 100644 index 0000000..8191333 Binary files /dev/null and b/MCUME_pico/bin/PICOMPUTER/mcume_pico800.uf2 differ diff --git a/MCUME_pico/bin/PICOMPUTER/mcume_pico81.uf2 b/MCUME_pico/bin/PICOMPUTER/mcume_pico81.uf2 new file mode 100644 index 0000000..66466bd Binary files /dev/null and b/MCUME_pico/bin/PICOMPUTER/mcume_pico81.uf2 differ diff --git a/MCUME_pico/bin/PICOMPUTER/mcume_picocolem.uf2 b/MCUME_pico/bin/PICOMPUTER/mcume_picocolem.uf2 new file mode 100644 index 0000000..2be4fb7 Binary files /dev/null and b/MCUME_pico/bin/PICOMPUTER/mcume_picocolem.uf2 differ diff --git a/MCUME_pico/bin/PICOMPUTER/mcume_picoo2em.uf2 b/MCUME_pico/bin/PICOMPUTER/mcume_picoo2em.uf2 new file mode 100644 index 0000000..0d284e4 Binary files /dev/null and b/MCUME_pico/bin/PICOMPUTER/mcume_picoo2em.uf2 differ diff --git a/MCUME_pico/bin/PICOMPUTER/mcume_picospeccy.uf2 b/MCUME_pico/bin/PICOMPUTER/mcume_picospeccy.uf2 new file mode 100644 index 0000000..66f41ca Binary files /dev/null and b/MCUME_pico/bin/PICOMPUTER/mcume_picospeccy.uf2 differ diff --git a/MCUME_pico/bin/PICOMPUTER/mcume_picovcs.uf2 b/MCUME_pico/bin/PICOMPUTER/mcume_picovcs.uf2 new file mode 100644 index 0000000..5f6ff76 Binary files /dev/null and b/MCUME_pico/bin/PICOMPUTER/mcume_picovcs.uf2 differ diff --git a/MCUME_pico/config/iopins.h b/MCUME_pico/config/iopins.h new file mode 100644 index 0000000..1898fdc --- /dev/null +++ b/MCUME_pico/config/iopins.h @@ -0,0 +1,109 @@ +#ifndef IOPINS_H +#define IOPINS_H + +#include "platform_config.h" + + +#ifdef MCUME_REV1 + +// Speaker +#define AUDIO_PIN 28 + +// VGA +/* +2-9 RRRGGGBB +10-11 VSYNC and HSYNC +*/ +#define VGA_COLORBASE 2 +#define VGA_SYNCBASE 10 + +// TFT +#define TFT_SPIREG spi1 +#define TFT_SPIDREQ DREQ_SPI1_TX +#define TFT_SCLK 14 +#define TFT_MOSI 15 +#define TFT_MISO 12 +#define TFT_DC 28 +#define TFT_CS 13 // 255 for LORES ST7789 (NO CS) +#define TFT_RST 255 // 255 for ILI/ST if connected to 3.3V + +// SD (see SPI0 in code!!!) +#define SD_SPIREG spi0 +#define SD_SCLK 18 +#define SD_MOSI 19 +#define SD_MISO 16 +#define SD_CS 17 +#define SD_DETECT 255 // 22 + +// Analog joystick (primary) for JOY2 and 3 extra buttons +#define PIN_JOY2_A1X 26 +#define PIN_JOY2_A2Y 27 +#define PIN_JOY2_BTN 22 +#define PIN_KEY_USER1 20 +#define PIN_KEY_USER2 21 + +// I2C keyboard (Not available on PICO) +/* +#define I2C_SCL_IO 15? +#define I2C_SDA_IO 14? +*/ + +#else + +// Speaker +#define AUDIO_PIN 0 //28 + +// VGA +/* +2-9 RRRGGGBB +10-11 VSYNC and HSYNC +*/ +#define VGA_COLORBASE 2 +#define VGA_SYNCBASE 14 + +// TFT +#define TFT_SPIREG spi0 +#define TFT_SPIDREQ DREQ_SPI0_TX +#define TFT_SCLK 18 +#define TFT_MOSI 19 +#define TFT_MISO 255 // Not required, used for DC... +#define TFT_DC 16 //28 +#define TFT_CS 255 //17 // 255 for LORES ST7789 (NO CS) +#define TFT_RST 21 //255 // 255 for ILI/ST if connected to 3.3V, required by 256x256 ST + +// SD (see SPI0 in code!!!) +#define SD_SPIREG spi1 +#define SD_SCLK 10 //14 +#define SD_MOSI 11 //15 +#define SD_MISO 12 +#define SD_CS 13 +#define SD_DETECT 255 // 22 + +#ifdef PICOMPUTER +// Keyboard matrix + +//Cols (out) +//1,2,3,4,5,14 +//Rows (in) +//6,9,15,8,7,22 + +#else +// Analog joystick (primary) for JOY2 and 3 extra buttons +#define PIN_JOY2_A1X 26 +#define PIN_JOY2_A2Y 27 +#define PIN_JOY2_BTN 22 +#define PIN_KEY_USER1 20 +#define PIN_KEY_USER2 21 + +#endif + +#endif + +// Second joystick (Not available on PICO) +//#define PIN_JOY1_BTN 2 +//#define PIN_JOY1_1 14 // UP +//#define PIN_JOY1_2 7 // DOWN +//#define PIN_JOY1_3 6 // RIGHT +//#define PIN_JOY1_4 5 // LEFT + +#endif diff --git a/MCUME_pico/config/platform_config.h b/MCUME_pico/config/platform_config.h new file mode 100644 index 0000000..989a0f2 --- /dev/null +++ b/MCUME_pico/config/platform_config.h @@ -0,0 +1,48 @@ +#ifndef _PLATFORM_CONFIG_H_ +#define _PLATFORM_CONFIG_H_ + +// MCUME_REV2 is new layout with VGA+TFT+AnalogJoy+3buttons+Sound +// MCUME_REV1 had only support for VGA+AnalogJoy+3buttons+Sound +// PICOMPUTER has support for TFT+keymatrix+Sound + + +//#define PICOMPUTER 1 +#define MCUME_REV1 1 +//#define MCUME_REV2 1 + + +#ifdef PICOMPUTER +#define ST7789 1 +#define LOHRES 1 +#define FLIP_SCREEN 1 +#define INVX 1 +#define HAS_SND 1 +#endif + +#ifdef MCUME_REV1 +#define USE_VGA 1 +#define INVX 1 +#define HAS_SND 1 +#endif + +#ifdef MCUME_REV2 +#define USE_VGA 1 +//#define ILI9341 1 +#define INVX 1 +#define HAS_SND 1 +#endif + +//#define HAS_SND 1 +//#define INVY 1 +//#define HAS_USBKEY 1 +//#define USE_VGA 1 +//#define ILI9341 1 +//#define ST7789 1 +//#define SWAP_JOYSTICK 1 +//#define LOHRES 1 +//#define ROTATE_SCREEN 1 +//#define FLIP_SCREEN 1 +//#define HAS_PSRAM 1 + + +#endif diff --git a/MCUME_pico/pico5200/.DS_Store b/MCUME_pico/pico5200/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/MCUME_pico/pico5200/.DS_Store and /dev/null differ diff --git a/MCUME_pico/pico5200/emuapi.cpp b/MCUME_pico/pico5200/emuapi.cpp index fd63999..dd8583f 100644 --- a/MCUME_pico/pico5200/emuapi.cpp +++ b/MCUME_pico/pico5200/emuapi.cpp @@ -13,12 +13,12 @@ extern "C" { #include "iopins.h" } - +#ifdef USE_VGA #include "vga_t_dma.h" -const uint16_t deflogo[] = { - 0,0 -}; -static const uint16_t * logo = deflogo; +#else +#include "tft_t_dma.h" +#endif + #define MAX_FILES 64 #define MAX_FILENAME_SIZE 24 @@ -49,10 +49,14 @@ static char selection[MAX_FILENAME_SIZE+1]=""; static char files[MAX_FILES][MAX_FILENAME_SIZE]; static bool menuRedraw=true; -static bool i2cKeyboardPresent = false; -static unsigned short * keys; static int keyMap; - +#ifdef PICOMPUTER +static unsigned short * keys; +static unsigned char keymatrix[6]; +static int keymatrix_hitrow=-1; +static bool key_fn=false; +#endif + static int keypadval=0; static bool joySwapped = false; static uint16_t bLastState; @@ -138,12 +142,8 @@ void emu_Free(void * pt) int emu_ReadAnalogJoyX(int min, int max) { -#ifdef PIN_JOY2_A1X adc_select_input(0); int val = adc_read(); -#else - int val = 0; -#endif #if INVX val = 4095 - val; #endif @@ -156,12 +156,8 @@ int emu_ReadAnalogJoyX(int min, int max) int emu_ReadAnalogJoyY(int min, int max) { -#ifdef PIN_JOY2_A2Y adc_select_input(1); int val = adc_read(); -#else - int val = 0; -#endif #if INVY val = 4095 - val; #endif @@ -178,7 +174,7 @@ int emu_ReadAnalogJoyY(int min, int max) static uint16_t readAnalogJoystick(void) { uint16_t joysval = 0; - +#ifdef PIN_JOY2_A1X int xReading = emu_ReadAnalogJoyX(0,256); if (xReading > 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -186,10 +182,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -276,6 +273,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -297,7 +347,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i - +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; int main(void) { stdio_init_all(); +#ifdef USE_VGA +// tft.begin(VGA_MODE_400x240); tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -49,11 +59,13 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -178,10 +180,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -268,6 +271,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -289,7 +345,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i - +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; bool repeating_timer_callback(struct repeating_timer *t) { @@ -32,13 +36,15 @@ int main(void) { // set_sys_clock_khz(200000, true); // set_sys_clock_khz(225000, true); set_sys_clock_khz(250000, true); - stdio_init_all(); - - tft.begin(VGA_MODE_400x240); -// tft.begin(VGA_MODE_320x240); +#ifdef USE_VGA +// tft.begin(VGA_MODE_400x240); + tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); - while (true) { + while (true) { if (menuActive()) { uint16_t bClick = emu_DebounceLocalKeys(); int action = handleMenu(bClick); @@ -59,6 +65,7 @@ int main(void) { //emu_Input(bClick); emu_Step(); } + //int c = getchar_timeout_us(0); //switch (c) { // case ' ': @@ -69,45 +76,60 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index @@ -57,35 +58,26 @@ #define PALETTE(r,g,b) (RGBVAL16(r,g,b)) //(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)) #include "vic_palette.h" + + +#define BORDER (240-200)/2 +#define SCREEN_HEIGHT (200+2*BORDER) +#define SCREEN_WIDTH 320 +//#define LINE_MEM_WIDTH 320 +#define FIRSTDISPLAYLINE ( 51 - BORDER ) +#define LASTDISPLAYLINE ( 250 + BORDER ) +#define BORDER_LEFT (400-320)/2 +#define BORDER_RIGHT 0 + +#ifdef USE_VGA typedef uint8_t tpixel; +#else +typedef uint16_t tpixel; +#endif -static tpixel * SCREENMEM=NULL; -static int LINE_MEM_WIDTH=0; -static int REAL_XRES=0; -static int REAL_YRES=0; - -#define SCREEN_WIDTH (320) - -/* -static int BORDER=0; -static int SCREEN_HEIGHT=0; -static int FIRSTDISPLAYLINE=0; -static int LASTDISPLAYLINE=0; -static int BORDER_LEFT=0; -static int BORDER_RIGHT=0; -*/ - -#define BORDER ((REAL_YRES-200)/2) -#define SCREEN_HEIGHT (200+2*BORDER) -#define FIRSTDISPLAYLINE ( 51 - BORDER ) -#define LASTDISPLAYLINE ( 250 + BORDER ) -#define BORDER_LEFT ((REAL_XRES-320)/2) -#define BORDER_RIGHT ((REAL_XRES-320)/2) - -#define MAXCYCLESSPRITES0_2 3 -#define MAXCYCLESSPRITES3_7 5 -#define MAXCYCLESSPRITES (MAXCYCLESSPRITES0_2 + MAXCYCLESSPRITES3_7) - +#define MAXCYCLESSPRITES0_2 3 +#define MAXCYCLESSPRITES3_7 5 +#define MAXCYCLESSPRITES (MAXCYCLESSPRITES0_2 + MAXCYCLESSPRITES3_7) /*****************************************************************************************************/ @@ -1283,6 +1275,8 @@ typedef void (*modes_t)( tpixel *p, const tpixel *pe, uint16_t *spl, const uint1 const modes_t modes[8] = {mode0, mode1, mode2, mode3, mode4, mode5, mode6, mode7}; +//static tpixel linebuffer[SCREEN_WIDTH]; + void vic_do(void) { uint16_t vc; @@ -1301,7 +1295,6 @@ void vic_do(void) { */ if ( cpu.vic.rasterLine >= LINECNT ) { - //reSID sound needs much time - too much to keep everything in sync and with stable refreshrate //but it is not called very often, so most of the time, we have more time than needed. //We can measure the time needed for a frame and calc a correction factor to speed things up. @@ -1313,14 +1306,14 @@ void vic_do(void) { cpu.vic.rasterLine = 0; cpu.vic.vcbase = 0; cpu.vic.denLatch = 0; - emu_DrawVsync(); + //if (cpu.vic.rasterLine == LINECNT) { + emu_DrawVsync(); + //} } else cpu.vic.rasterLine++; int r = cpu.vic.rasterLine; -// if ( (r >= LASTDISPLAYLINE) && (emu_oskbActive()) ) return; - if (r == cpu.vic.intRasterLine )//Set Rasterline-Interrupt cpu.vic.R[0x19] |= 1 | ((cpu.vic.R[0x1a] & 1) << 7); @@ -1403,61 +1396,18 @@ void vic_do(void) { } //max_x = (!cpu.vic.CSEL) ? 40:38; - p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH; - - - uint16_t col; -//#if !VGA -if(REAL_XRES == SCREEN_WIDTH) { + //p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH; + //p = &linebuffer[0]; //tft.getLineBuffer((r - FIRSTDISPLAYLINE)); + p = (tpixel*)emu_LineBuffer((r - FIRSTDISPLAYLINE)); pe = p + SCREEN_WIDTH; //Left Screenborder: Cycle 10 spl = &cpu.vic.spriteLine[24]; cpu_clock(6); -} -else { - pe = p + SCREEN_WIDTH + BORDER_LEFT; - col = cpu.vic.colors[0]; - - //Left Screenborder: Cycle 10 - for (int i = 0; i <2; i++) { - cpu_clock(1); - *p++ = col;*p++ = col;*p++ = col;*p++ = col; - *p++ = col;*p++ = col;*p++ = col;*p++ = col; - } - - //Left Screenborder: Cycle 13 -#if 0 //mit Sprites - spl = &cpu.vic.spriteLine[0]; - uint16_t sprite; - for (int i=0; i<3; i++) { - cpu_clock(1); - SPRITEORFIXEDCOLOR(); - SPRITEORFIXEDCOLOR(); - SPRITEORFIXEDCOLOR(); - SPRITEORFIXEDCOLOR(); - SPRITEORFIXEDCOLOR(); - SPRITEORFIXEDCOLOR(); - SPRITEORFIXEDCOLOR(); - SPRITEORFIXEDCOLOR(); - } -#else //ohne sprites - spl = &cpu.vic.spriteLine[24]; - for (int i=0; i<3; i++) { - cpu_clock(1); - *p++ = col;*p++ = col;*p++ = col;*p++ = col; - *p++ = col;*p++ = col;*p++ = col;*p++ = col; - } -#endif -} if (cpu.vic.borderFlag) { -//#if !VGA - if(REAL_XRES == SCREEN_WIDTH) { - cpu_clock(5); - } - if ( (!emu_oskbActive()) ) - fastFillLineNoSprites(p, pe + BORDER_RIGHT, cpu.vic.colors[0]); + cpu_clock(5); + fastFillLineNoSprites(p, pe + BORDER_RIGHT, cpu.vic.colors[0]); goto noDisplayIncRC ; } @@ -1612,7 +1562,9 @@ g-Zugriff cpu_clock(1); uint16_t col = cpu.vic.colors[0]; //p = &screen[r - FIRSTDISPLAYLINE][0]; - p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + BORDER_LEFT; + //p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + BORDER_LEFT; + //p = &linebuffer[0]; // tft.getLineBuffer((r - FIRSTDISPLAYLINE)); + p = (tpixel*)emu_LineBuffer((r - FIRSTDISPLAYLINE)) + BORDER_LEFT; #if 0 // Sprites im Rand uint16_t sprite; @@ -1635,8 +1587,10 @@ g-Zugriff //Rand rechts: //p = &screen[r - FIRSTDISPLAYLINE][SCREEN_WIDTH - 9]; - p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + SCREEN_WIDTH - 9 + BORDER_LEFT; - pe = p + 9; + //p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + SCREEN_WIDTH - 9 + BORDER_LEFT; + //p = &linebuffer[SCREEN_WIDTH - 9 + BORDER_LEFT]; //tft.getLineBuffer((r - FIRSTDISPLAYLINE)) + SCREEN_WIDTH - 9 + BORDER_LEFT; + p = (tpixel*)emu_LineBuffer((r - FIRSTDISPLAYLINE)) + SCREEN_WIDTH - 9 + BORDER_LEFT; + pe = p + 9; #if 0 // Sprites im Rand @@ -1646,32 +1600,20 @@ g-Zugriff } #else //keine Sprites im Rand - while (p < pe) { - *p++ = col; - } + //while (p < pe) { + // *p++ = col; + //} #endif + + } +// emu_DrawLine8(&linebuffer[0], SCREEN_WIDTH, SCREEN_HEIGHT, (r - FIRSTDISPLAYLINE)); + //Rechter Rand nach CSEL, im Textbereich cpu_clock(5); -//#if VGA -if(REAL_XRES != SCREEN_WIDTH) { - p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + SCREEN_WIDTH + BORDER_LEFT; - pe += BORDER_RIGHT; -#if 0 - // Sprites im Rand - while (p < pe) { - SPRITEORFIXEDCOLOR(); - } -#else - //keine Sprites im Rand - while (p < pe) { - *p++ = col; - } -#endif -} noDisplayIncRC: @@ -1953,7 +1895,7 @@ if ( cpu.vic.rasterLine >= LINECNT ) { cpu.vic.rasterLine = 0; cpu.vic.vcbase = 0; cpu.vic.denLatch = 0; - emu_DrawVsync(); + } else { cpu.vic.rasterLine++; cpu_clock(1); @@ -1961,8 +1903,6 @@ if ( cpu.vic.rasterLine >= LINECNT ) { } int r = cpu.vic.rasterLine; - -// if ( (r >= LASTDISPLAYLINE) && (emu_oskbActive()) ) return; if (r == cpu.vic.intRasterLine )//Set Rasterline-Interrupt cpu.vic.R[0x19] |= 1 | ((cpu.vic.R[0x1a] & 1) << 7); @@ -2028,6 +1968,16 @@ if ( cpu.vic.rasterLine >= LINECNT ) { } + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + +void installPalette(void) { + memcpy(cpu.vic.palette, (void*)palette, sizeof(cpu.vic.palette)); +} + + /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ @@ -2056,17 +2006,17 @@ void vic_write(uint32_t address, uint8_t value) { switch (address) { case 0x11 : - cpu.vic.R[address] = value; + cpu.vic.R[address] = value; cpu.vic.intRasterLine = (cpu.vic.intRasterLine & 0xff) | ((((uint16_t) value) << 1) & 0x100); if (cpu.vic.rasterLine == 0x30 ) cpu.vic.denLatch |= value & 0x10; cpu.vic.badline = (cpu.vic.denLatch && (cpu.vic.rasterLine >= 0x30) && (cpu.vic.rasterLine <= 0xf7) && ( (cpu.vic.rasterLine & 0x07) == (value & 0x07))); - if (cpu.vic.badline) { - cpu.vic.idle = 0; - } + if (cpu.vic.badline) { + cpu.vic.idle = 0; + } - vic_adrchange(); + vic_adrchange(); break; case 0x12 : @@ -2163,40 +2113,7 @@ uint8_t vic_read(uint32_t address) { /*****************************************************************************************************/ /*****************************************************************************************************/ -void installPalette(void) { - memcpy(cpu.vic.palette, (void*)palette, sizeof(cpu.vic.palette)); -} - - -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ -#define XOFFSET 4 -#define YOFFSET 16 - - void resetVic(void) { - LINE_MEM_WIDTH = tft.get_frame_buffer_size(&REAL_XRES,&REAL_YRES); - SCREENMEM=(tpixel*)emu_LineBuffer(0); - /* - if (REAL_XRES == SCREEN_WIDTH) { - BORDER = (REAL_YRES-200)/2; - SCREEN_HEIGHT = (200+2*BORDER); - FIRSTDISPLAYLINE = ( 51 - BORDER ); - LASTDISPLAYLINE = ( 250 + BORDER ); - BORDER_LEFT = 0; - BORDER_RIGHT = 0; - } - else { - BORDER = (REAL_YRES-200)/2; - SCREEN_HEIGHT = (200+2*BORDER); - FIRSTDISPLAYLINE = ( 51 - BORDER ); - LASTDISPLAYLINE = ( 250 + BORDER ); - BORDER_LEFT = (REAL_XRES-320)/2; - BORDER_RIGHT = (REAL_XRES-320)/2; - } - */ - enableCycleCounter(); cpu.vic.intRasterLine = 0; @@ -2204,6 +2121,8 @@ void resetVic(void) { cpu.vic.lineHasSprites = 0; memset(&cpu.RAM[0x400], 0, 1000); memset(&cpu.vic, 0, sizeof(cpu.vic)); + + installPalette(); diff --git a/MCUME_pico/pico64/vic.cpp_old b/MCUME_pico/pico64/vic.cpp_new old mode 100644 new mode 100755 similarity index 95% rename from MCUME_pico/pico64/vic.cpp_old rename to MCUME_pico/pico64/vic.cpp_new index eea3065..96cadf8 --- a/MCUME_pico/pico64/vic.cpp_old +++ b/MCUME_pico/pico64/vic.cpp_new @@ -45,7 +45,6 @@ - optimize more */ - #include "Teensy64.h" #include "vic.h" #include @@ -58,22 +57,40 @@ #define PALETTE(r,g,b) (RGBVAL16(r,g,b)) //(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)) #include "vic_palette.h" - - -#define BORDER (240-200)/2 -#define SCREEN_HEIGHT (200+2*BORDER) -#define SCREEN_WIDTH 320 -//#define LINE_MEM_WIDTH 320 -#define FIRSTDISPLAYLINE ( 51 - BORDER ) -#define LASTDISPLAYLINE ( 250 + BORDER ) -#define BORDER_LEFT (400-320)/2 -#define BORDER_RIGHT 0 - +#ifdef USE_VGA typedef uint8_t tpixel; +#else +typedef uint16_t tpixel; +#endif + + +static tpixel * SCREENMEM=NULL; +static int LINE_MEM_WIDTH=0; +static int REAL_XRES=0; +static int REAL_YRES=0; + +#define SCREEN_WIDTH (320) + +/* +static int BORDER=0; +static int SCREEN_HEIGHT=0; +static int FIRSTDISPLAYLINE=0; +static int LASTDISPLAYLINE=0; +static int BORDER_LEFT=0; +static int BORDER_RIGHT=0; +*/ + +#define BORDER ((REAL_YRES-200)/2) +#define SCREEN_HEIGHT (200+2*BORDER) +#define FIRSTDISPLAYLINE ( 51 - BORDER ) +#define LASTDISPLAYLINE ( 250 + BORDER ) +#define BORDER_LEFT ((REAL_XRES-320)/2) +#define BORDER_RIGHT ((REAL_XRES-320)/2) + +#define MAXCYCLESSPRITES0_2 3 +#define MAXCYCLESSPRITES3_7 5 +#define MAXCYCLESSPRITES (MAXCYCLESSPRITES0_2 + MAXCYCLESSPRITES3_7) -#define MAXCYCLESSPRITES0_2 3 -#define MAXCYCLESSPRITES3_7 5 -#define MAXCYCLESSPRITES (MAXCYCLESSPRITES0_2 + MAXCYCLESSPRITES3_7) /*****************************************************************************************************/ @@ -1271,8 +1288,6 @@ typedef void (*modes_t)( tpixel *p, const tpixel *pe, uint16_t *spl, const uint1 const modes_t modes[8] = {mode0, mode1, mode2, mode3, mode4, mode5, mode6, mode7}; -//static tpixel linebuffer[SCREEN_WIDTH]; - void vic_do(void) { uint16_t vc; @@ -1291,6 +1306,7 @@ void vic_do(void) { */ if ( cpu.vic.rasterLine >= LINECNT ) { + //reSID sound needs much time - too much to keep everything in sync and with stable refreshrate //but it is not called very often, so most of the time, we have more time than needed. //We can measure the time needed for a frame and calc a correction factor to speed things up. @@ -1302,14 +1318,14 @@ void vic_do(void) { cpu.vic.rasterLine = 0; cpu.vic.vcbase = 0; cpu.vic.denLatch = 0; - //if (cpu.vic.rasterLine == LINECNT) { - emu_DrawVsync(); - //} + emu_DrawVsync(); } else cpu.vic.rasterLine++; int r = cpu.vic.rasterLine; +// if ( (r >= LASTDISPLAYLINE) && (emu_oskbActive()) ) return; + if (r == cpu.vic.intRasterLine )//Set Rasterline-Interrupt cpu.vic.R[0x19] |= 1 | ((cpu.vic.R[0x1a] & 1) << 7); @@ -1392,18 +1408,61 @@ void vic_do(void) { } //max_x = (!cpu.vic.CSEL) ? 40:38; - //p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH; - //p = &linebuffer[0]; //tft.getLineBuffer((r - FIRSTDISPLAYLINE)); - p = (tpixel*)emu_LineBuffer((r - FIRSTDISPLAYLINE)); + p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH; + + + uint16_t col; +//#if !VGA +if(REAL_XRES == SCREEN_WIDTH) { pe = p + SCREEN_WIDTH; //Left Screenborder: Cycle 10 spl = &cpu.vic.spriteLine[24]; cpu_clock(6); +} +else { + pe = p + SCREEN_WIDTH + BORDER_LEFT; + col = cpu.vic.colors[0]; + + //Left Screenborder: Cycle 10 + for (int i = 0; i <2; i++) { + cpu_clock(1); + *p++ = col;*p++ = col;*p++ = col;*p++ = col; + *p++ = col;*p++ = col;*p++ = col;*p++ = col; + } + + //Left Screenborder: Cycle 13 +#if 0 //mit Sprites + spl = &cpu.vic.spriteLine[0]; + uint16_t sprite; + for (int i=0; i<3; i++) { + cpu_clock(1); + SPRITEORFIXEDCOLOR(); + SPRITEORFIXEDCOLOR(); + SPRITEORFIXEDCOLOR(); + SPRITEORFIXEDCOLOR(); + SPRITEORFIXEDCOLOR(); + SPRITEORFIXEDCOLOR(); + SPRITEORFIXEDCOLOR(); + SPRITEORFIXEDCOLOR(); + } +#else //ohne sprites + spl = &cpu.vic.spriteLine[24]; + for (int i=0; i<3; i++) { + cpu_clock(1); + *p++ = col;*p++ = col;*p++ = col;*p++ = col; + *p++ = col;*p++ = col;*p++ = col;*p++ = col; + } +#endif +} if (cpu.vic.borderFlag) { - cpu_clock(5); - fastFillLineNoSprites(p, pe + BORDER_RIGHT, cpu.vic.colors[0]); +//#if !VGA + if(REAL_XRES == SCREEN_WIDTH) { + cpu_clock(5); + } + if ( (!emu_oskbActive()) ) + fastFillLineNoSprites(p, pe + BORDER_RIGHT, cpu.vic.colors[0]); goto noDisplayIncRC ; } @@ -1558,9 +1617,7 @@ g-Zugriff cpu_clock(1); uint16_t col = cpu.vic.colors[0]; //p = &screen[r - FIRSTDISPLAYLINE][0]; - //p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + BORDER_LEFT; - //p = &linebuffer[0]; // tft.getLineBuffer((r - FIRSTDISPLAYLINE)); - p = (tpixel*)emu_LineBuffer((r - FIRSTDISPLAYLINE)) + BORDER_LEFT; + p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + BORDER_LEFT; #if 0 // Sprites im Rand uint16_t sprite; @@ -1583,10 +1640,8 @@ g-Zugriff //Rand rechts: //p = &screen[r - FIRSTDISPLAYLINE][SCREEN_WIDTH - 9]; - //p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + SCREEN_WIDTH - 9 + BORDER_LEFT; - //p = &linebuffer[SCREEN_WIDTH - 9 + BORDER_LEFT]; //tft.getLineBuffer((r - FIRSTDISPLAYLINE)) + SCREEN_WIDTH - 9 + BORDER_LEFT; - p = (tpixel*)emu_LineBuffer((r - FIRSTDISPLAYLINE)) + SCREEN_WIDTH - 9 + BORDER_LEFT; - pe = p + 9; + p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + SCREEN_WIDTH - 9 + BORDER_LEFT; + pe = p + 9; #if 0 // Sprites im Rand @@ -1596,20 +1651,32 @@ g-Zugriff } #else //keine Sprites im Rand - //while (p < pe) { - // *p++ = col; - //} + while (p < pe) { + *p++ = col; + } #endif - - } -// emu_DrawLine8(&linebuffer[0], SCREEN_WIDTH, SCREEN_HEIGHT, (r - FIRSTDISPLAYLINE)); - //Rechter Rand nach CSEL, im Textbereich cpu_clock(5); +//#if VGA +if(REAL_XRES != SCREEN_WIDTH) { + p = SCREENMEM + (r - FIRSTDISPLAYLINE) * LINE_MEM_WIDTH + SCREEN_WIDTH + BORDER_LEFT; + pe += BORDER_RIGHT; +#if 0 + // Sprites im Rand + while (p < pe) { + SPRITEORFIXEDCOLOR(); + } +#else + //keine Sprites im Rand + while (p < pe) { + *p++ = col; + } +#endif +} noDisplayIncRC: @@ -1891,7 +1958,7 @@ if ( cpu.vic.rasterLine >= LINECNT ) { cpu.vic.rasterLine = 0; cpu.vic.vcbase = 0; cpu.vic.denLatch = 0; - + emu_DrawVsync(); } else { cpu.vic.rasterLine++; cpu_clock(1); @@ -1899,6 +1966,8 @@ if ( cpu.vic.rasterLine >= LINECNT ) { } int r = cpu.vic.rasterLine; + +// if ( (r >= LASTDISPLAYLINE) && (emu_oskbActive()) ) return; if (r == cpu.vic.intRasterLine )//Set Rasterline-Interrupt cpu.vic.R[0x19] |= 1 | ((cpu.vic.R[0x1a] & 1) << 7); @@ -1964,16 +2033,6 @@ if ( cpu.vic.rasterLine >= LINECNT ) { } - -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ - -void installPalette(void) { - memcpy(cpu.vic.palette, (void*)palette, sizeof(cpu.vic.palette)); -} - - /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ @@ -2002,17 +2061,17 @@ void vic_write(uint32_t address, uint8_t value) { switch (address) { case 0x11 : - cpu.vic.R[address] = value; + cpu.vic.R[address] = value; cpu.vic.intRasterLine = (cpu.vic.intRasterLine & 0xff) | ((((uint16_t) value) << 1) & 0x100); if (cpu.vic.rasterLine == 0x30 ) cpu.vic.denLatch |= value & 0x10; cpu.vic.badline = (cpu.vic.denLatch && (cpu.vic.rasterLine >= 0x30) && (cpu.vic.rasterLine <= 0xf7) && ( (cpu.vic.rasterLine & 0x07) == (value & 0x07))); - if (cpu.vic.badline) { - cpu.vic.idle = 0; - } + if (cpu.vic.badline) { + cpu.vic.idle = 0; + } - vic_adrchange(); + vic_adrchange(); break; case 0x12 : @@ -2109,7 +2168,40 @@ uint8_t vic_read(uint32_t address) { /*****************************************************************************************************/ /*****************************************************************************************************/ +void installPalette(void) { + memcpy(cpu.vic.palette, (void*)palette, sizeof(cpu.vic.palette)); +} + + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +#define XOFFSET 4 +#define YOFFSET 16 + + void resetVic(void) { + LINE_MEM_WIDTH = tft.get_frame_buffer_size(&REAL_XRES,&REAL_YRES); + SCREENMEM=(tpixel*)emu_LineBuffer(0); + /* + if (REAL_XRES == SCREEN_WIDTH) { + BORDER = (REAL_YRES-200)/2; + SCREEN_HEIGHT = (200+2*BORDER); + FIRSTDISPLAYLINE = ( 51 - BORDER ); + LASTDISPLAYLINE = ( 250 + BORDER ); + BORDER_LEFT = 0; + BORDER_RIGHT = 0; + } + else { + BORDER = (REAL_YRES-200)/2; + SCREEN_HEIGHT = (200+2*BORDER); + FIRSTDISPLAYLINE = ( 51 - BORDER ); + LASTDISPLAYLINE = ( 250 + BORDER ); + BORDER_LEFT = (REAL_XRES-320)/2; + BORDER_RIGHT = (REAL_XRES-320)/2; + } + */ + enableCycleCounter(); cpu.vic.intRasterLine = 0; @@ -2117,8 +2209,6 @@ void resetVic(void) { cpu.vic.lineHasSprites = 0; memset(&cpu.RAM[0x400], 0, 1000); memset(&cpu.vic, 0, sizeof(cpu.vic)); - - installPalette(); diff --git a/MCUME_pico/pico800/.DS_Store b/MCUME_pico/pico800/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/MCUME_pico/pico800/.DS_Store and /dev/null differ diff --git a/MCUME_pico/pico800/emuapi.cpp b/MCUME_pico/pico800/emuapi.cpp index 2020f1d..a8aa6cd 100644 --- a/MCUME_pico/pico800/emuapi.cpp +++ b/MCUME_pico/pico800/emuapi.cpp @@ -13,12 +13,12 @@ extern "C" { #include "iopins.h" } - +#ifdef USE_VGA #include "vga_t_dma.h" -const uint16_t deflogo[] = { - 0,0 -}; -static const uint16_t * logo = deflogo; +#else +#include "tft_t_dma.h" +#endif + #define MAX_FILES 64 #define MAX_FILENAME_SIZE 24 @@ -49,9 +49,13 @@ static char selection[MAX_FILENAME_SIZE+1]=""; static char files[MAX_FILES][MAX_FILENAME_SIZE]; static bool menuRedraw=true; -static bool i2cKeyboardPresent = false; -static unsigned short * keys; static int keyMap; +#ifdef PICOMPUTER +static unsigned short * keys; +static unsigned char keymatrix[6]; +static int keymatrix_hitrow=-1; +static bool key_fn=false; +#endif static int keypadval=0; static bool joySwapped = false; @@ -135,15 +139,10 @@ void emu_Free(void * pt) - int emu_ReadAnalogJoyX(int min, int max) { -#ifdef PIN_JOY2_A1X adc_select_input(0); int val = adc_read(); -#else - int val = 0; -#endif #if INVX val = 4095 - val; #endif @@ -156,12 +155,8 @@ int emu_ReadAnalogJoyX(int min, int max) int emu_ReadAnalogJoyY(int min, int max) { -#ifdef PIN_JOY2_A2Y adc_select_input(1); int val = adc_read(); -#else - int val = 0; -#endif #if INVY val = 4095 - val; #endif @@ -178,7 +173,7 @@ int emu_ReadAnalogJoyY(int min, int max) static uint16_t readAnalogJoystick(void) { uint16_t joysval = 0; - +#ifdef PIN_JOY2_A1X int xReading = emu_ReadAnalogJoyX(0,256); if (xReading > 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -186,10 +181,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -276,6 +272,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -297,7 +346,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i, 0x0F+1==, 0x0E+1=-, 0x06+1=+ + 0, 0,0,0,0,0,0,0,0,0, + 0,0,0,0 + }; + +const unsigned short matkeys[] = { + 0x020,0x120,0x220,0x320,0x420,0x408,0x308,0x208,0x108,0x008,0x520, // row 1 + 0x510,0x010,0x110,0x210,0x310,0x410,0x401,0x301,0x201,0x101,0x001, // row 2 + /*0x002*/ 0xfff,0x102,0x202,0x302,0x402,0x404,0x304,0x204,0x104,0x004, // row 3 + 0x508,0x501,0x502,0x504 }; // cursor keys +#endif #endif +/* Pokey code +KEY_A = 63 +KEY_S = 62 +KEY_G = 61 +KEY_Cap = 60 +KEY_D = 58 +KEY_H = 57 +KEY_F = 56 +KEY_Great = 55 +KEY_Less = 54 +KEY_8 = 53 +KEY_BSp = 52 +KEY_7 = 51 +KEY_0 = 50 +KEY_9 = 48 +KEY_Q = 47 +KEY_W = 46 +KEY_T = 45 +KEY_Tab = 44 +KEY_Y = 43 +KEY_E = 42 +KEY_R = 40 +KEY_Inv = 39 +KEY_Slash = 38 +KEY_M = 37 +KEY_N = 35 +KEY_Dot = 34 +KEY_Spa = 33 +KEY_Comma = 32 +KEY_1 = 31 +KEY_2 = 30 +KEY_5 = 29 +KEY_Esc = 28 +KEY_6 = 27 +KEY_3 = 26 +KEY_4 = 24 +KEY_Z = 23 +KEY_X = 22 +KEY_B = 21 +KEY_F4 = 20 +KEY_F3 = 19 +KEY_C = 18 +KEY_Hlp = 17 +KEY_V = 16 +KEY_Equal = 15 +KEY_Minus = 14 +KEY_I = 13 +KEY_Ret = 12 +KEY_U = 11 +KEY_P = 10 +KEY_O = 8 +KEY_Aster = 7 +KEY_plus = 6 +KEY_K = 5 +KEY_F2 = 4 +KEY_F1 = 3 +KEY_Semi = 2 +KEY_J = 1 +KEY_L = 0 +*/ + #define MASK_JOY2_RIGHT 0x0001 #define MASK_JOY2_LEFT 0x0002 #define MASK_JOY2_UP 0x0004 diff --git a/MCUME_pico/pico800/iopins.h b/MCUME_pico/pico800/iopins.h deleted file mode 100644 index a636576..0000000 --- a/MCUME_pico/pico800/iopins.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef IOPINS_H -#define IOPINS_H - -#include "platform_config.h" - - -// VGA (see in code!!!) -/* -2-9 RRRGGGBB -10-11 VSYNC and HSYNC -*/ - -// SD (see SPI0 in code!!!) -/* -#define SD_SCLK 18 -#define SD_MOSI 19 -#define SD_MISO 16 -#define SD_CS 17 -*/ - -// I2C keyboard (not used) -/* -#define I2C_SCL_IO 15? -#define I2C_SDA_IO 14? -*/ - -// Analog joystick (primary) for JOY2 and 3 extra buttons -#define PIN_JOY2_A1X 26 -#define PIN_JOY2_A2Y 27 -#define PIN_JOY2_BTN 22 -#define PIN_KEY_USER1 20 -#define PIN_KEY_USER2 21 - -// Second joystick -//#define PIN_JOY1_BTN 2 -//#define PIN_JOY1_1 14 // UP -//#define PIN_JOY1_2 7 // DOWN -//#define PIN_JOY1_3 6 // RIGHT -//#define PIN_JOY1_4 5 // LEFT - - -#endif diff --git a/MCUME_pico/pico800/pico800.cpp b/MCUME_pico/pico800/pico800.cpp index 37daeb5..d802229 100644 --- a/MCUME_pico/pico800/pico800.cpp +++ b/MCUME_pico/pico800/pico800.cpp @@ -6,19 +6,40 @@ extern "C" { #include "emuapi.h" } #include "keyboard_osd.h" -#include "vga_t_dma.h" + extern "C" { #include "atari800.h" } #include +#include "hardware/clocks.h" +#include "hardware/vreg.h" +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; int main(void) { +// vreg_set_voltage(VREG_VOLTAGE_1_05); +// set_sys_clock_khz(125000, true); +// set_sys_clock_khz(150000, true); +// set_sys_clock_khz(133000, true); +// set_sys_clock_khz(200000, true); +// set_sys_clock_khz(225000, true); +// set_sys_clock_khz(250000, true); + stdio_init_all(); +#ifdef USE_VGA +// tft.begin(VGA_MODE_400x240); tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -49,11 +70,13 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -179,10 +182,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -269,6 +273,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -290,7 +347,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i - +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; int main(void) { stdio_init_all(); +#ifdef USE_VGA tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -49,11 +58,13 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -186,10 +180,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -276,6 +271,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -297,7 +345,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i - +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; int main(void) { stdio_init_all(); +#ifdef USE_VGA tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -49,11 +58,13 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; int main(void) { stdio_init_all(); +#ifdef USE_VGA +// tft.begin(VGA_MODE_400x240); tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -49,11 +60,13 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -186,10 +178,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -276,6 +269,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -297,7 +343,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i - +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; int main(void) { stdio_init_all(); +#ifdef USE_VGA +// tft.begin(VGA_MODE_400x240); tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -49,11 +59,13 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -178,10 +180,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -268,6 +271,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -289,7 +345,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i -TFT_T_DMA tft; static int skip=0; bool repeating_timer_callback(struct repeating_timer *t) { @@ -27,7 +33,11 @@ int main(void) { //set_sys_clock_khz(133000, true); //set_sys_clock_khz(48000, true); //set_sys_clock_khz(270000, true); +#ifdef USE_VGA tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -78,7 +88,9 @@ void emu_DrawVsync(void) void emu_DrawLine(unsigned char * VBuf, int width, int height, int line) { if (skip == 0) { - tft.writeLine(width,height,line, VBuf, palette8); +#ifdef USE_VGA + tft.writeLine(width,height,line, VBuf, palette8); +#endif } } @@ -86,21 +98,27 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line) void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line) { if (skip == 0) { +#ifdef USE_VGA tft.writeLine(width,height,line, VBuf); +#endif } } void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line) { if (skip == 0) { +#ifdef USE_VGA tft.writeLine16(width,height,line, VBuf); +#endif } } void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride) { if (skip == 0) { +#ifdef USE_VGA tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8); +#endif } } diff --git a/MCUME_pico/picosnd/platform_config.h b/MCUME_pico/picosnd/platform_config.h deleted file mode 100644 index 51ea353..0000000 --- a/MCUME_pico/picosnd/platform_config.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _PLATFORM_CONFIG_H_ -#define _PLATFORM_CONFIG_H_ - - -#define INVX 1 -//#define INVY 1 -#define HAS_SND 1 -//#define HAS_USBKEY 1 -//#define HAS_I2CKBD 1 - -//#define ILI9341 1 -//#define ST7789 1 -//#define SWAP_JOYSTICK 1 -//#define LOHRES 1 -//#define ROTATE_SCREEN 1 -//#define EXTERNAL_SD 1 - -//#define HAS_PSRAM 1 - -//#define USE_SDFAT 1 -//#define SD_FAT_TYPE 1 -//#define USE_SDFS 1 -//#define SDFSDEV "1:" - -#endif diff --git a/MCUME_pico/picosnd/sndplay.cpp b/MCUME_pico/picosnd/sndplay.cpp index 218fe05..180c4c5 100644 --- a/MCUME_pico/picosnd/sndplay.cpp +++ b/MCUME_pico/picosnd/sndplay.cpp @@ -48,7 +48,9 @@ static YMMUSIC *ymDecoder; void snd_Init(void) { - emu_sndInit(); +#ifdef HAS_SND + emu_sndInit(); +#endif switch (mustype) { case C64Dmp: playSID.begin(); diff --git a/MCUME_pico/picospeccy/.DS_Store b/MCUME_pico/picospeccy/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/MCUME_pico/picospeccy/.DS_Store and /dev/null differ diff --git a/MCUME_pico/picospeccy/emuapi.cpp b/MCUME_pico/picospeccy/emuapi.cpp index 75f32fd..22efbb9 100644 --- a/MCUME_pico/picospeccy/emuapi.cpp +++ b/MCUME_pico/picospeccy/emuapi.cpp @@ -13,12 +13,12 @@ extern "C" { #include "iopins.h" } - +#ifdef USE_VGA #include "vga_t_dma.h" -const uint16_t deflogo[] = { - 0,0 -}; -static const uint16_t * logo = deflogo; +#else +#include "tft_t_dma.h" +#endif + #define MAX_FILES 64 #define MAX_FILENAME_SIZE 24 @@ -49,9 +49,13 @@ static char selection[MAX_FILENAME_SIZE+1]=""; static char files[MAX_FILES][MAX_FILENAME_SIZE]; static bool menuRedraw=true; -static bool i2cKeyboardPresent = false; -static unsigned short * keys; static int keyMap; +#ifdef PICOMPUTER +static unsigned short * keys; +static unsigned char keymatrix[6]; +static int keymatrix_hitrow=-1; +static bool key_fn=false; +#endif static int keypadval=0; static bool joySwapped = false; @@ -134,16 +138,10 @@ void emu_Free(void * pt) - - int emu_ReadAnalogJoyX(int min, int max) { -#ifdef PIN_JOY2_A1X adc_select_input(0); int val = adc_read(); -#else - int val = 0; -#endif #if INVX val = 4095 - val; #endif @@ -156,12 +154,8 @@ int emu_ReadAnalogJoyX(int min, int max) int emu_ReadAnalogJoyY(int min, int max) { -#ifdef PIN_JOY2_A2Y adc_select_input(1); int val = adc_read(); -#else - int val = 0; -#endif #if INVY val = 4095 - val; #endif @@ -178,7 +172,7 @@ int emu_ReadAnalogJoyY(int min, int max) static uint16_t readAnalogJoystick(void) { uint16_t joysval = 0; - +#ifdef PIN_JOY2_A1X int xReading = emu_ReadAnalogJoyX(0,256); if (xReading > 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -186,10 +180,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -276,6 +271,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -297,7 +345,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i {10, 9, 7,22, 4}, // gfdsa @@ -59,23 +47,28 @@ const unsigned short keysw[] = { {11,13,14,15,40}, // hjkl { 5,17,16,225,44}, // bnm */ - + const unsigned short key_map1[] = { - 30,31,32,33,34,35,36,37,38,39, - 0, 20,26, 8,21,23,28,25,12,18,19, - 0, 4, 9, 7,22, 4,11,13,14,15,40, - 25, 6,27,29,224,5,17,16,225,44 + 20,26,8,21,23,28,25,12,18,19,'0', + 0, 4, 9, 7,22, 4,11,13,14,15,40, + 0,6,27,29,224,5,17,16,225,44, + 0,0,0,0 }; -#ifdef HAS_I2CKBD -const unsigned short i2ckeys[] = { - 0X0080,0X0008,0X0180,0X0108,0X0280,0X0208,0X0380,0X0308,0X0480,0X0408, - 0, 0X0040,0X0004,0X0140,0X0104,0X0240,0X0204,0X0340,0X0304,0X0440,0X0404, - 0, 0X0020,0X0002,0X0120,0X0102,0X0220,0X0202,0X0320,0X0302,0X0420,0X0402, - 0X0010,0X0001,0X0110,0X0101,0X0210,0X0201,0X0310,0X0301,0X0410,0X0401, - }; +const unsigned short key_map2[] = { + 30,31,32,33,34,35,36,37,38,39,0, + 0,0,0,0,0,0,0,0,0,0,0, + 0, 0,0,0,0,0,0,0,0,0, + 0,0,0,0 + }; + +const unsigned short matkeys[] = { + 0x020,0x120,0x220,0x320,0x420,0x408,0x308,0x208,0x108,0x008,0x520, // row 1 + 0x510,0x010,0x110,0x210,0x310,0x410,0x401,0x301,0x201,0x101,0x001, // row 2 + /*0x002*/ 0xfff,0x102,0x202,0x302,0x402,0x404,0x304,0x204,0x104,0x004, // row 3 + 0x508,0x501,0x502,0x504 }; // cursor keys + #endif - #endif diff --git a/MCUME_pico/picospeccy/iopins.h b/MCUME_pico/picospeccy/iopins.h deleted file mode 100644 index a636576..0000000 --- a/MCUME_pico/picospeccy/iopins.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef IOPINS_H -#define IOPINS_H - -#include "platform_config.h" - - -// VGA (see in code!!!) -/* -2-9 RRRGGGBB -10-11 VSYNC and HSYNC -*/ - -// SD (see SPI0 in code!!!) -/* -#define SD_SCLK 18 -#define SD_MOSI 19 -#define SD_MISO 16 -#define SD_CS 17 -*/ - -// I2C keyboard (not used) -/* -#define I2C_SCL_IO 15? -#define I2C_SDA_IO 14? -*/ - -// Analog joystick (primary) for JOY2 and 3 extra buttons -#define PIN_JOY2_A1X 26 -#define PIN_JOY2_A2Y 27 -#define PIN_JOY2_BTN 22 -#define PIN_KEY_USER1 20 -#define PIN_KEY_USER2 21 - -// Second joystick -//#define PIN_JOY1_BTN 2 -//#define PIN_JOY1_1 14 // UP -//#define PIN_JOY1_2 7 // DOWN -//#define PIN_JOY1_3 6 // RIGHT -//#define PIN_JOY1_4 5 // LEFT - - -#endif diff --git a/MCUME_pico/picospeccy/picospeccy.cpp b/MCUME_pico/picospeccy/picospeccy.cpp index 9c95100..87c37aa 100644 --- a/MCUME_pico/picospeccy/picospeccy.cpp +++ b/MCUME_pico/picospeccy/picospeccy.cpp @@ -6,19 +6,28 @@ extern "C" { #include "emuapi.h" } #include "keyboard_osd.h" -#include "vga_t_dma.h" + extern "C" { #include "spec.h" } #include - +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; int main(void) { stdio_init_all(); +#ifdef USE_VGA tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -49,11 +58,13 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index 128) joysval |= MASK_JOY2_LEFT; else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; @@ -186,10 +181,11 @@ static uint16_t readAnalogJoystick(void) int yReading = emu_ReadAnalogJoyY(0,256); if (yReading < 128) joysval |= MASK_JOY2_UP; else if (yReading > 128) joysval |= MASK_JOY2_DOWN; - +#endif #ifdef PIN_JOY2_BTN joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); #endif + return (joysval); } @@ -276,6 +272,59 @@ int emu_ReadKeys(void) if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; #endif +#ifdef PICOMPUTER + keymatrix_hitrow = -1; + unsigned char row; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + + gpio_put(cols[i], 0); + row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } + + //6,9,15,8,7,22 +#if INVX + if ( row & 0x2 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x1 ) retval |= MASK_JOY2_RIGHT; +#else + if ( row & 0x1 ) retval |= MASK_JOY2_LEFT; + if ( row & 0x2 ) retval |= MASK_JOY2_RIGHT; +#endif +#if INVY + if ( row & 0x8 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x4 ) retval |= MASK_JOY2_UP; +#else + if ( row & 0x4 ) retval |= MASK_JOY2_DOWN; + if ( row & 0x8 ) retval |= MASK_JOY2_UP; +#endif + if ( row & 0x10 ) retval |= MASK_JOY2_BTN; + if ( row & 0x20 ) retval |= MASK_KEY_USER1; +#endif + //Serial.println(retval,HEX); if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) @@ -297,7 +346,26 @@ unsigned short emu_DebounceLocalKeys(void) int emu_ReadI2CKeyboard(void) { int retval=0; - +#ifdef PICOMPUTER + if ( keymatrix[0] & 0x02 ) { + key_fn = true; + } + if (key_fn) { + keys = (unsigned short *)key_map2; + } + else { + keys = (unsigned short *)key_map1; + } + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i - +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif TFT_T_DMA tft; + static int skip=0; int main(void) { stdio_init_all(); +#ifdef USE_VGA +// tft.begin(VGA_MODE_400x240); tft.begin(VGA_MODE_320x240); +#else + tft.begin(); +#endif emu_init(); while (true) { if (menuActive()) { @@ -49,11 +59,13 @@ int main(void) { } static unsigned char palette8[PALETTE_SIZE]; +static unsigned short palette16[PALETTE_SIZE]; void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index) { if (index +#include + +extern "C" { + #include "emuapi.h" + #include "iopins.h" +} + + +static unsigned short * keys; +static int keyMap; + +static int keypadval=0; +static bool joySwapped = false; +static uint16_t bLastState; +static int xRef; +static int yRef; +static uint8_t usbnavpad=0; + +#ifdef PICOMPUTER +static unsigned char keymatrix[6]; +static int keymatrix_hitrow = -1; +#endif + + +void emu_printf(char * text) +{ + printf("%s\n",text); +} + +void emu_printf(int val) +{ + printf("%d\n",val); +} + +void emu_printi(int val) +{ + printf("%d\n",val); +} + +void emu_printh(int val) +{ + printf("0x%.8\n",val); +} + + + + + + + +int emu_ReadAnalogJoyX(int min, int max) +{ + adc_select_input(0); + int val = adc_read(); +#if INVX + val = 4095 - val; +#endif + val = val-xRef; + val = ((val*140)/100); + if ( (val > -512) && (val < 512) ) val = 0; + val = val+2048; + return (val*(max-min))/4096; +} + +int emu_ReadAnalogJoyY(int min, int max) +{ + adc_select_input(1); + int val = adc_read(); +#if INVY + val = 4095 - val; +#endif + val = val-yRef; + val = ((val*120)/100); + if ( (val > -512) && (val < 512) ) val = 0; + //val = (val*(max-min))/4096; + val = val+2048; + //return val+(max-min)/2; + return (val*(max-min))/4096; +} + + +static uint16_t readAnalogJoystick(void) +{ + uint16_t joysval = 0; +#ifdef PIN_JOY2_A1X + int xReading = emu_ReadAnalogJoyX(0,256); + if (xReading > 128) joysval |= MASK_JOY2_LEFT; + else if (xReading < 128) joysval |= MASK_JOY2_RIGHT; + + int yReading = emu_ReadAnalogJoyY(0,256); + if (yReading < 128) joysval |= MASK_JOY2_UP; + else if (yReading > 128) joysval |= MASK_JOY2_DOWN; +#endif +#ifdef PIN_JOY2_BTN + joysval |= (gpio_get(PIN_JOY2_BTN) ? 0 : MASK_JOY2_BTN); +#endif + + return (joysval); +} + + +int emu_SwapJoysticks(int statusOnly) { + if (!statusOnly) { + if (joySwapped) { + joySwapped = false; + } + else { + joySwapped = true; + } + } + return(joySwapped?1:0); +} + +int emu_GetPad(void) +{ + return(keypadval/*|((joySwapped?1:0)<<7)*/); +} + +int emu_ReadKeys(void) +{ + uint16_t retval; + uint16_t j1 = readAnalogJoystick(); + uint16_t j2 = 0; + + // Second joystick +#if INVY +#ifdef PIN_JOY1_1 + if ( !gpio_get(PIN_JOY1_1) ) j2 |= MASK_JOY2_DOWN; +#endif +#ifdef PIN_JOY1_2 + if ( !gpio_get(PIN_JOY1_2) ) j2 |= MASK_JOY2_UP; +#endif +#else +#ifdef PIN_JOY1_1 + if ( !gpio_get(PIN_JOY1_1) ) j2 |= MASK_JOY2_UP; +#endif +#ifdef PIN_JOY1_2 + if ( !gpio_get(PIN_JOY1_2) ) j2 |= MASK_JOY2_DOWN; +#endif +#endif +#if INVX +#ifdef PIN_JOY1_3 + if ( !gpio_get(PIN_JOY1_3) ) j2 |= MASK_JOY2_LEFT; +#endif +#ifdef PIN_JOY1_4 + if ( !gpio_get(PIN_JOY1_4) ) j2 |= MASK_JOY2_RIGHT; +#endif +#else +#ifdef PIN_JOY1_3 + if ( !gpio_get(PIN_JOY1_3) ) j2 |= MASK_JOY2_RIGHT; +#endif +#ifdef PIN_JOY1_4 + if ( !gpio_get(PIN_JOY1_4) ) j2 |= MASK_JOY2_LEFT; +#endif +#endif +#ifdef PIN_JOY1_BTN + if ( !gpio_get(PIN_JOY1_BTN) ) j2 |= MASK_JOY2_BTN; +#endif + if (joySwapped) { + retval = ((j1 << 8) | j2); + } + else { + retval = ((j2 << 8) | j1); + } + + if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP; + if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN; + if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT; + if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT; + if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN; +#ifdef PIN_KEY_USER1 + if ( !gpio_get(PIN_KEY_USER1) ) retval |= MASK_KEY_USER1; +#endif +#ifdef PIN_KEY_USER2 + if ( !gpio_get(PIN_KEY_USER2) ) retval |= MASK_KEY_USER2; +#endif +#ifdef PIN_KEY_USER3 + if ( !gpio_get(PIN_KEY_USER3) ) retval |= MASK_KEY_USER3; +#endif +#ifdef PIN_KEY_USER4 + if ( !gpio_get(PIN_KEY_USER4) ) retval |= MASK_KEY_USER4; +#endif + +#ifdef PICOMPUTER + gpio_put(14, 0); + + //6,9,15,8,7,22 + if ( !gpio_get(9) ) retval |= MASK_JOY2_LEFT; + if ( !gpio_get(9) ) retval |= MASK_JOY2_LEFT; + if ( !gpio_get(9) ) retval |= MASK_JOY2_LEFT; + if ( !gpio_get(8) ) retval |= MASK_JOY2_RIGHT; + if ( !gpio_get(6) ) retval |= MASK_JOY2_DOWN; + if ( !gpio_get(15) ) retval |= MASK_JOY2_UP; + if ( !gpio_get(7) ) retval |= MASK_JOY2_BTN; + if ( !gpio_get(22) ) retval |= MASK_KEY_USER1; + + gpio_put(14, 1); + + keymatrix_hitrow = -1; + unsigned short cols[6]={1,2,3,4,5,14}; + for (int i=0;i<6;i++){ + gpio_put(cols[i], 0); + unsigned char row=0; + + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(9) ? 0 : 0x01); + row |= (gpio_get(8) ? 0 : 0x02); + row |= (gpio_get(6) ? 0 : 0x04); + row |= (gpio_get(15) ? 0 : 0x08); + row |= (gpio_get(7) ? 0 : 0x10); + row |= (gpio_get(22) ? 0 : 0x20); + /* + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(9) ) row |= 0x01; + if ( !gpio_get(8) ) row |= 0x02; + if ( !gpio_get(6) ) row |= 0x04; + if ( !gpio_get(15) ) row |= 0x08; + if ( !gpio_get(7) ) row |= 0x10; + if ( !gpio_get(22) ) row |= 0x20; + */ + keymatrix[i]=row; + if (row) keymatrix_hitrow=i; + gpio_put(cols[i], 1); + } +#endif + + //Serial.println(retval,HEX); + + if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) + || (retval & MASK_KEY_USER4 ) ) + { + } + + return (retval); +} + +unsigned short emu_DebounceLocalKeys(void) +{ + uint16_t bCurState = emu_ReadKeys(); + uint16_t bClick = bCurState & ~bLastState; + bLastState = bCurState; + + return (bClick); +} + +unsigned char emu_ReadI2CKeyboard2(int row) { + int retval=0; +#ifdef PICOMPUTER + retval = keymatrix[row]; +#endif + return retval; +} + +int emu_ReadI2CKeyboard(void) { + int retval=0; +#ifdef PICOMPUTER + if (keymatrix_hitrow >=0 ) { + unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow]; + for (int i=0; i + +#ifdef USE_VGA +#include "vga_t_dma.h" +#else +#include "tft_t_dma.h" +#endif + +extern "C" { + #include "iopins.h" + #include "emuapi.h" +} + +TFT_T_DMA tft; + +#define BLUE RGBVAL16(0, 0, 170) +#define LIGHT_BLUE RGBVAL16(0, 136, 255) + +static int fb_width, fb_height; + + +#include "hardware/clocks.h" +#include "hardware/vreg.h" + +static const char * digits = "0123456789ABCDEF"; + +int main(void) { + vreg_set_voltage(VREG_VOLTAGE_1_05); +// set_sys_clock_khz(125000, true); +// set_sys_clock_khz(150000, true); +// set_sys_clock_khz(133000, true); +// set_sys_clock_khz(200000, true); +// set_sys_clock_khz(225000, true); + set_sys_clock_khz(250000, true); + + stdio_init_all(); + + printf("start\n"); + tft.begin(); + emu_init(); + emu_start(); + tft.startDMA(); + tft.fillScreen(LIGHT_BLUE); + tft.get_frame_buffer_size(&fb_width, &fb_height); + tft.drawRect((fb_width-320)/2,(fb_height-200)/2, 320,200, BLUE); + tft.drawText((fb_width-320)/2,(fb_height-200)/2+1*8," **** COMMODORE 64 BASIC V2 **** ",LIGHT_BLUE,BLUE,false); + tft.drawText((fb_width-320)/2,(fb_height-200)/2+3*8," 64K RAM SYSTEM 38911 BASIC BYTES FREE ",LIGHT_BLUE,BLUE,false); + tft.drawText((fb_width-320)/2,(fb_height-200)/2+5*8,"READY.",LIGHT_BLUE,BLUE,false); + + char buf[4] = {32,32,32,0}; + uint sys_clk = clock_get_hz(clk_sys)/1000000; + uint r1 = sys_clk/100; + uint r = sys_clk - r1*100; + uint r2 = r/10; + r = sys_clk - r1*100 - r2*10; + uint r3 = r; + buf[0] = digits[r1]; + buf[1] = digits[r2]; + buf[2] = digits[r3]; + tft.drawText(4*8,0,buf,BLUE,LIGHT_BLUE,false); + + while (true) { + uint16_t bClick = emu_ReadKeys(); + char buf[5] = {0,0,0,0,0}; + buf[0] = digits[(bClick>>12)&0xf]; + buf[1] = digits[(bClick>>8)&0xf]; + buf[2] = digits[(bClick>>4)&0xf]; + buf[3] = digits[bClick&0xf]; + tft.drawText(4*8,16,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); + buf[3] = 0; + int key = emu_ReadI2CKeyboard(); + buf[0] = digits[(key>>8)&0xf]; + buf[1] = digits[(key>>4)&0xf]; + buf[2] = digits[key&0xf]; + tft.drawText(4*8,16*2,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); + /* + buf[2] = 0; + uint8_t key = emu_ReadI2CKeyboard2(0); + buf[0] = digits[(key>>4)&0xf]; + buf[1] = digits[key&0xf]; + tft.drawText(4*8,16*2,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); + key = emu_ReadI2CKeyboard2(1); + buf[0] = digits[(key>>4)&0xf]; + buf[1] = digits[key&0xf]; + tft.drawText(4*8,16*3,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); + key = emu_ReadI2CKeyboard2(2); + buf[0] = digits[(key>>4)&0xf]; + buf[1] = digits[key&0xf]; + tft.drawText(4*8,16*4,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); + key = emu_ReadI2CKeyboard2(3); + buf[0] = digits[(key>>4)&0xf]; + buf[1] = digits[key&0xf]; + tft.drawText(4*8,16*5,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); + key = emu_ReadI2CKeyboard2(4); + buf[0] = digits[(key>>4)&0xf]; + buf[1] = digits[key&0xf]; + tft.drawText(4*8,16*6,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); + key = emu_ReadI2CKeyboard2(5); + buf[0] = digits[(key>>4)&0xf]; + buf[1] = digits[key&0xf]; + tft.drawText(4*8,16*7,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); + */ + sleep_ms(20); + +/* + sleep_ms(2000); + tft.stopDMA(); + tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); + sleep_ms(2000); + tft.startDMA(); + tft.fillScreen(LIGHT_BLUE); +*/ + + //tft.waitSync(); + //tft.drawText((fb_width-320)/2,(fb_height-200)/2+6*8," ",BLUE,LIGHT_BLUE,false); + //sleep_ms(500); + //tft.waitSync(); + //tft.drawText((fb_width-320)/2,(fb_height-200)/2+6*8," ",BLUE,BLUE,false); + //sleep_ms(500); + } +} + + + + + + diff --git a/MCUME_pico/testvga/testvga.cpp b/MCUME_pico/testvga/testvga.cpp index 8572893..36e635d 100644 --- a/MCUME_pico/testvga/testvga.cpp +++ b/MCUME_pico/testvga/testvga.cpp @@ -31,6 +31,7 @@ int main(void) { stdio_init_all(); printf("start\n"); +// vga.begin(VGA_MODE_400x240); vga.begin(VGA_MODE_320x240); //tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); vga.clear(LIGHT_BLUE); @@ -50,7 +51,7 @@ int main(void) { buf[0] = digits[r1]; buf[1] = digits[r2]; buf[2] = digits[r3]; - vga.drawText(0,0,buf,BLUE,LIGHT_BLUE,false); + vga.drawText(4*8,0,buf,BLUE,LIGHT_BLUE,false); while (true) { diff --git a/MCUME_pico/tft_t/tft_font8x8.h b/MCUME_pico/tft_t/tft_font8x8.h new file mode 100644 index 0000000..bab272e --- /dev/null +++ b/MCUME_pico/tft_t/tft_font8x8.h @@ -0,0 +1,136 @@ + +// Font: c64_lower.64c + +const unsigned char font8x8[128][8] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (//) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; + + diff --git a/MCUME_pico/tft_t/tft_t_dma.cpp b/MCUME_pico/tft_t/tft_t_dma.cpp new file mode 100644 index 0000000..90b033c --- /dev/null +++ b/MCUME_pico/tft_t/tft_t_dma.cpp @@ -0,0 +1,1151 @@ + +#include "TFT_T_DMA.h" + +#include "tft_font8x8.h" +#include "pico/stdlib.h" +#include "pico/multicore.h" +#include "hardware/spi.h" +#include "hardware/dma.h" +#include "hardware/irq.h" +#include + +#ifndef USE_VGA + +#define digitalWrite(pin, val) gpio_put(pin, val) + +#define SPICLOCK 60000000 +#ifdef ST7789 +#define SPI_MODE SPI_CPOL_1 +#endif +#ifdef ILI9341 +#define SPI_MODE SPI_CPOL_0 +#endif + +#ifdef TFT_STATICFB +static uint16_t fb0[LINES_PER_BLOCK*TFT_WIDTH]; //__attribute__ ((aligned(2048))); +static uint16_t fb1[LINES_PER_BLOCK*TFT_WIDTH]; //__attribute__ ((aligned(2048))); +static uint16_t fb2[LINES_PER_BLOCK*TFT_WIDTH]; //__attribute__ ((aligned(2048))); +static uint16_t fb3[(TFT_HEIGHT-3*LINES_PER_BLOCK)*TFT_WIDTH];// __attribute__ ((aligned(2048))); +static uint16_t * blocks[NR_OF_BLOCK]={fb0,fb1,fb2,fb3}; +static uint16_t blocklens[NR_OF_BLOCK]; +#else +static uint16_t * blocks[NR_OF_BLOCK]; +static uint16_t blocklens[NR_OF_BLOCK]; +#endif + + +static dma_channel_config dmaconfig; +const uint dma_tx = dma_claim_unused_channel(true); +static volatile uint8_t rstop = 0; +static volatile bool cancelled = false; +static volatile uint8_t curTransfer = 0; +static uint8_t nbTransfer = 0; + + +static void SPItransfer(uint8_t val) +{ + uint8_t dat8=val; + spi_write_blocking(TFT_SPIREG, &dat8, 1); +} + +static void SPItransfer16(uint16_t val) +{ + uint8_t dat8[2]; + dat8[0] = val>>8; + dat8[1] = val&0xff; + spi_write_blocking(TFT_SPIREG, dat8, 2); +} + +static const uint8_t init_commands[] = { +#ifdef ILI9341 + 4, 0xEF, 0x03, 0x80, 0x02, + 4, 0xCF, 0x00, 0XC1, 0X30, + 5, 0xED, 0x64, 0x03, 0X12, 0X81, + 4, 0xE8, 0x85, 0x00, 0x78, + 6, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02, + 2, 0xF7, 0x20, + 3, 0xEA, 0x00, 0x00, + 2, ILI9341_PWCTR1, 0x23, // Power control + 2, ILI9341_PWCTR2, 0x10, // Power control + 3, ILI9341_VMCTR1, 0x3e, 0x28, // VCM control + 2, ILI9341_VMCTR2, 0x86, // VCM control2 + 2, ILI9341_MADCTL, 0x48, // Memory Access Control + 2, ILI9341_PIXFMT, 0x55, + 3, ILI9341_FRMCTR1, 0x00, 0x18, + 4, ILI9341_DFUNCTR, 0x08, 0x82, 0x27, // Display Function Control + 2, 0xF2, 0x00, // Gamma Function Disable + 2, ILI9341_GAMMASET, 0x01, // Gamma curve selected + 16, ILI9341_GMCTRP1, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, + 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, // Set Gamma + 16, ILI9341_GMCTRN1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, + 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, // Set Gamma +// 3, 0xb1, 0x00, 0x1f, // FrameRate Control 61Hz + 3, 0xb1, 0x00, 0x10, // FrameRate Control 119Hz + 2, ILI9341_MADCTL, ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR, + 0 +#endif +#ifdef ST7789 +#define DELAY 0x80 + 9, // 9 commands in list: + ST7735_SWRESET, DELAY, // 1: Software reset, no args, w/delay + 150, // 150 ms delay + ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, no args, w/delay + 255, // 255 = 500 ms delay + ST7735_COLMOD , 1+DELAY, // 3: Set color mode, 1 arg + delay: + 0x55, // 16-bit color + 10, // 10 ms delay + ST7735_MADCTL , 1 , // 4: Memory access ctrl (directions), 1 arg: + 0x08, // Row addr/col addr, bottom to top refresh + ST7735_CASET , 4 , // 5: Column addr set, 4 args, no delay: + 0x00, + 0x00, // XSTART = 0 + 0x00, + 240, // XEND = 240 + ST7735_RASET , 4 , // 6: Row addr set, 4 args, no delay: + 0x00, + 0x00, // YSTART = 0 + 320>>8, + 320 & 0xFF, // YEND = 320 + ST7735_INVON , DELAY, // 7: hack + 10, + ST7735_NORON , DELAY, // 8: Normal display on, no args, w/delay + 10, // 10 ms delay + ST7735_DISPON , DELAY, // 9: Main screen turn on, no args, w/delay + 255 +#endif +}; + +static void dma_isr() { + irq_clear(DMA_IRQ_0); + dma_hw->ints0 = 1u << dma_tx; + curTransfer++; + if (curTransfer >= nbTransfer) { + curTransfer = 0; + } + if (cancelled) { + rstop = 1; + } + else + { + dma_channel_transfer_from_buffer_now ( dma_tx, blocks[curTransfer], blocklens[curTransfer]); + } +} + +static void setDmaStruct() { + uint32_t remaining = TFT_HEIGHT*TFT_WIDTH*2; + int i=0; + nbTransfer = 0; + uint16_t col=RGBVAL16(0x00,0x00,0x00);; + while (remaining > 0) { + uint16_t * fb = blocks[i]; + int32_t len = (remaining >= (LINES_PER_BLOCK*TFT_WIDTH*2)?LINES_PER_BLOCK*TFT_WIDTH*2:remaining); +#ifdef TFT_DEBUG + printf("%d\n",(unsigned long)blocks[i]); + printf("%d\n",remaining); +#endif + switch (i) { + case 0: + if (fb == 0) fb = (uint16_t*)((int)malloc(len+64)&0xffffffe0); + //fb=&fb0[0]; +#ifdef TFT_DEBUG + col = RGBVAL16(0x00,0xff,0x00); +#endif + break; + case 1: + if (fb == 0) fb = (uint16_t*)((int)malloc(len+64)&0xffffffe0); + //fb=&fb1[0]; +#ifdef TFT_DEBUG + col = RGBVAL16(0x00,0xff,0xff); +#endif + break; + case 2: + if (fb == 0) fb = (uint16_t*)((int)malloc(len+64)&0xffffffe0); + //fb=&fb2[0]; +#ifdef TFT_DEBUG + col = RGBVAL16(0x00,0x00,0xff); +#endif + break; + case 3: + if (fb == 0) fb = (uint16_t*)((int)malloc(len+64)&0xffffffe0); + //fb=&fb3[0]; +#ifdef TFT_DEBUG + col = RGBVAL16(0xff,0x00,0xff); +#endif + break; + } + blocks[i] = fb; + blocklens[i] = len/2; + if (blocks[i] == 0) { + printf("LI9341 allocaltion failed for block %d\n",i); + sleep_ms(10000); + } + nbTransfer++; + remaining -= len; + i++; + } + + + // Setup the control channel + dmaconfig = dma_channel_get_default_config(dma_tx); + channel_config_set_transfer_data_size(&dmaconfig, DMA_SIZE_16); + channel_config_set_dreq(&dmaconfig, TFT_SPIDREQ); + //channel_config_set_read_increment(&dmaconfig, true); // read incrementing + //channel_config_set_write_increment(&dmaconfig, false); // no write incrementing + + dma_channel_configure( + dma_tx, + &dmaconfig, + &spi_get_hw(TFT_SPIREG)->dr, // write address + blocks[0], + blocklens[0], + false + ); + + irq_set_exclusive_handler(DMA_IRQ_0, dma_isr); + dma_channel_set_irq0_enabled(dma_tx, true); + irq_set_enabled(DMA_IRQ_0, true); + dma_hw->ints0 = 1u << dma_tx; +} + +TFT_T_DMA::TFT_T_DMA() +{ + _cs = TFT_CS; + _dc = TFT_DC; + _rst = TFT_RST; + _mosi = TFT_MOSI; + _sclk = TFT_SCLK; + //_miso = TFT_MISO; + gpio_init(_dc); + gpio_set_dir(_dc, GPIO_OUT); + gpio_init(_cs); + gpio_set_dir(_cs, GPIO_OUT); + digitalWrite(_cs, 1); + digitalWrite(_dc, 1); +} + + +void TFT_T_DMA::setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2) { + int dx=0; + int dy=0; +#ifdef ST7789 + if (TFT_REALWIDTH == TFT_REALHEIGHT) + { +#ifdef ROTATE_SCREEN + if (!flipped) { + dy += 80; + } +#else + if (flipped) { + dx += 80; + } +#endif + } +#endif + + digitalWrite(_dc, 0); + SPItransfer(TFT_CASET); + digitalWrite(_dc, 1); + SPItransfer16(x1+dx); + digitalWrite(_dc, 1); + SPItransfer16(x2+dx); + digitalWrite(_dc, 0); + SPItransfer(TFT_PASET); + digitalWrite(_dc, 1); + SPItransfer16(y1+dy); + digitalWrite(_dc, 1); + SPItransfer16(y2+dy); + + digitalWrite(_dc, 0); + SPItransfer(TFT_RAMWR); + digitalWrite(_dc, 1); + + return; +} + + +void TFT_T_DMA::begin(void) { + spi_init(TFT_SPIREG, SPICLOCK); + spi_set_format(TFT_SPIREG, 8, SPI_MODE, SPI_CPHA_0, SPI_MSB_FIRST); + gpio_set_function(_sclk , GPIO_FUNC_SPI); + gpio_set_function(_mosi , GPIO_FUNC_SPI); + //gpio_set_function(_miso, GPIO_FUNC_SPI); + + // Initialize display + if (_rst != 0xff) { + gpio_init(_rst); + gpio_set_dir(_rst, GPIO_OUT); + digitalWrite(_rst, 1); + sleep_ms(100); + digitalWrite(_rst, 0); + sleep_ms(100); + digitalWrite(_rst, 1); + sleep_ms(200); + } + + + const uint8_t *addr = init_commands; + digitalWrite(_cs, 0); +#ifdef ILI9341 + while (1) { + uint8_t count = *addr++; + if (count-- == 0) break; + + digitalWrite(_dc, 0); + SPItransfer(*addr++); + + while (count-- > 0) { + digitalWrite(_dc, 1); + SPItransfer(*addr++); + } + } + + digitalWrite(_dc, 0); + SPItransfer(ILI9341_SLPOUT); + digitalWrite(_dc, 1); + digitalWrite(_cs, 1); + + digitalWrite(_dc, 1); + digitalWrite(_cs, 1); + + digitalWrite(_dc, 0); + digitalWrite(_cs, 0); + SPItransfer(ILI9341_DISPON); + digitalWrite(_dc, 1); + digitalWrite(_cs, 1); +#endif +#ifdef ST7789 + uint8_t numCommands, numArgs; + uint16_t ms; + numCommands = *addr++; // Number of commands to follow + while(numCommands--) { // For each command... + digitalWrite(_dc, 0); + SPItransfer(*addr++); + numArgs = *addr++; // Number of args to follow + ms = numArgs & DELAY; // If hibit set, delay follows args + numArgs &= ~DELAY; // Mask out delay bit + while(numArgs > 1) { // For each argument... + digitalWrite(_dc, 1); + SPItransfer(*addr++); + numArgs--; + } + + if (numArgs) { + digitalWrite(_dc, 1); + SPItransfer(*addr++); + } + if(ms) { + ms = *addr++; // Read post-command delay time (ms) + if(ms == 255) ms = 500; // If 255, delay for 500 ms + digitalWrite(_cs, 1); + //SPI.endTransaction(); + sleep_ms(ms); + //SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_cs, 0); + } + } + digitalWrite(_cs, 1); +#endif + setArea(0, 0, TFT_REALWIDTH-1, TFT_REALHEIGHT-1); + + cancelled = false; + +#ifdef FLIP_SCREEN + flipscreen(true); +#else + flipscreen(false); +#endif +#ifdef ST7789 + if (TFT_REALWIDTH != TFT_REALHEIGHT) + { + flipscreen(true); + } +#endif +}; + + + +void TFT_T_DMA::flipscreen(bool flip) +{ + digitalWrite(_dc, 0); + digitalWrite(_cs, 0); + SPItransfer(TFT_MADCTL); + digitalWrite(_dc, 1); + if (flip) { + flipped=true; +#ifdef ILI9341 + SPItransfer(ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR); +#endif +#ifdef ST7789 +#ifdef ROTATE_SCREEN + SPItransfer(ST77XX_MADCTL_RGB); +#else + SPItransfer(ST77XX_MADCTL_MY | ST77XX_MADCTL_MV |ST77XX_MADCTL_RGB); +#endif +#endif + } + else { + flipped=false; +#ifdef ILI9341 + SPItransfer(ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR); +#endif +#ifdef ST7789 +#ifdef ROTATE_SCREEN + SPItransfer(ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | ST77XX_MADCTL_RGB); +#else + SPItransfer(ST77XX_MADCTL_MX | ST77XX_MADCTL_MV | ST77XX_MADCTL_RGB); +#endif +#endif + } + digitalWrite(_cs, 1); +} + +bool TFT_T_DMA::isflipped(void) +{ + return(flipped); +} + + +void TFT_T_DMA::startDMA(void) { + curTransfer = 0; + rstop = 0; + digitalWrite(_cs, 1); + setDmaStruct(); + fillScreen(RGBVAL16(0x00,0x00,0x00)); + + digitalWrite(_cs, 0); + setArea((TFT_REALWIDTH-TFT_WIDTH)/2, (TFT_REALHEIGHT-TFT_HEIGHT)/2, (TFT_REALWIDTH-TFT_WIDTH)/2 + TFT_WIDTH-1, (TFT_REALHEIGHT-TFT_HEIGHT)/2+TFT_HEIGHT-1); + // we switch to 16bit mode!! + spi_set_format(TFT_SPIREG, 16, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); + dma_start_channel_mask(1u << dma_tx); +} + + +void TFT_T_DMA::stopDMA(void) { + rstop = 0; + wait(); + sleep_ms(100); + cancelled = false; + //dmatx.detachInterrupt(); + fillScreen(RGBVAL16(0x00,0x00,0x00)); + digitalWrite(_cs, 1); + // we switch to 8bit mode!! + //spi_set_format(TFT_SPIREG, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); +//#ifdef ST7789 + begin(); +//#endif +//#ifdef ILI9341 +// SPI.begin(); +// digitalWrite(_cs, 0); +// SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); +// SPI.endTransaction(); +// digitalWrite(_cs, 1); +// digitalWrite(_dc, 1); +//#endif + setArea(0, 0, TFT_REALWIDTH-1, TFT_REALHEIGHT-1); +} + +void TFT_T_DMA::wait(void) { + rstop = 1; + unsigned long m = time_us_32()*1000; + cancelled = true; + while (!rstop) { + if ((time_us_32()*1000 - m) > 100) break; + sleep_ms(100); + asm volatile("wfi"); + }; + rstop = 0; +} + + +int TFT_T_DMA::get_frame_buffer_size(int *width, int *height){ + if (width != nullptr) *width = TFT_REALWIDTH; + if (height != nullptr) *height = TFT_REALHEIGHT; + return TFT_REALWIDTH; +} + +void TFT_T_DMA::waitSync() { +} + +/*********************************************************************************************** + No DMA functions + ***********************************************************************************************/ +void TFT_T_DMA::fillScreenNoDma(uint16_t color) { + digitalWrite(_cs, 0); + setArea(0, 0, TFT_REALWIDTH-1, TFT_REALHEIGHT-1); + //digitalWrite(_dc, 0); + //SPItransfer(TFT_RAMWR); + int i,j; + for (j=0; j(arx+arw)) || ((x+w)(ary+arh)) || ((y+h) arx) && (x<(arx+arw)) ) { + arw = arw - (x-arx); + arx = arx + (x-arx); + } else { + bmp_offx = arx; + } + if ( ((x+w) > arx) && ((x+w)<(arx+arw)) ) { + arw -= (arx+arw-x-w); + } + if ( (y > ary) && (y<(ary+arh)) ) { + arh = arh - (y-ary); + ary = ary + (y-ary); + } else { + bmp_offy = ary; + } + if ( ((y+h) > ary) && ((y+h)<(ary+arh)) ) { + arh -= (ary+arh-y-h); + } + } + + + //SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_cs, 0); + setArea(arx, ary, arx+arw-1, ary+arh-1); + + bitmap = bitmap + bmp_offy*w + bmp_offx; + for (int row=0;row> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + } + bits = *charpt++; + //digitalWrite(_dc, 1); + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + bits = bits >> 1; + if (bits&0x01) SPItransfer16(fgcolor); + else SPItransfer16(bgcolor); + } + x +=8; +#ifdef ILI9341 + digitalWrite(_dc, 0); + SPItransfer(ILI9341_SLPOUT); + digitalWrite(_dc, 1); +#endif + digitalWrite(_cs, 1); + //SPI.endTransaction(); + } + + //SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); + digitalWrite(_cs, 0); + setArea(0, 0, (TFT_REALWIDTH-1), (TFT_REALHEIGHT-1)); + digitalWrite(_cs, 1); + //SPI.endTransaction(); +} + + + +/*********************************************************************************************** + DMA functions + ***********************************************************************************************/ +uint16_t * TFT_T_DMA::getLineBuffer(int j) +{ + uint16_t * block=blocks[j>>6]; + return(&block[(j&0x3F)*TFT_REALWIDTH]); +} + +void TFT_T_DMA::writeScreen(int width, int height, int stride, uint8_t *buf, uint16_t *palette16) { + uint8_t *buffer=buf; + uint8_t *src; + + int i,j,y=0; + if (width*2 <= TFT_REALWIDTH) { + for (j=0; j>6]; + uint16_t * dst=&block[(y&0x3F)*TFT_WIDTH]; + src=buffer; + for (i=0; i>6]; + dst=&block[(y&0x3F)*TFT_WIDTH]; + src=buffer; + for (i=0; i>6]; + uint16_t * dst=&block[(y&0x3F)*TFT_WIDTH+(TFT_WIDTH-width)/2]; + src=buffer; + for (i=0; i>6]; + dst=&block[(y&0x3F)*TFT_WIDTH+(TFT_WIDTH-width)/2]; + src=buffer; + for (i=0; i>6]; + uint16_t * dst=&block[(y&0x3F)*TFT_WIDTH]; + if (width > TFT_WIDTH) { +#ifdef TFT_LINEARINT + int delta = (width/(width-TFT_WIDTH))-1; + int pos = delta; + for (int i=0; i> 8]]; + pos +=step; + } +#endif + } + else if ((width*2) == TFT_WIDTH) { + for (int i=0; i>6]; + uint16_t * dst=&block[(y&0x3F)*TFT_WIDTH]; + if (width > TFT_WIDTH) { +#ifdef TFT_LINEARINT + int delta = (width/(width-TFT_WIDTH))-1; + int pos = delta; + for (int i=0; i> 8]; + pos +=step; + } +#endif + } + else if ((width*2) == TFT_WIDTH) { + for (int i=0; i>6]; + uint16_t * dst=&block[(j&0x3F)*TFT_WIDTH]; + for (i=0; i>6]; + uint16_t * dst=&block[(l&0x3F)*TFT_WIDTH+x]; + for (i=0; i>6]; + dst=&block[(l&0x3F)*TFT_WIDTH+x]; + bits = *charpt; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + l++; + } + block=blocks[l>>6]; + dst=&block[(l&0x3F)*TFT_WIDTH+x]; + bits = *charpt++; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + bits = bits >> 1; + if (bits&0x01) *dst++=fgcolor; + else *dst++=bgcolor; + l++; + } + x +=8; + } +} + +void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap) { + drawSprite(x,y,bitmap, 0,0,0,0); +} + +void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t arx, uint16_t ary, uint16_t arw, uint16_t arh) +{ + int bmp_offx = 0; + int bmp_offy = 0; + uint16_t *bmp_ptr; + + int w =*bitmap++; + int h = *bitmap++; + + + if ( (arw == 0) || (arh == 0) ) { + // no crop window + arx = x; + ary = y; + arw = w; + arh = h; + } + else { + if ( (x>(arx+arw)) || ((x+w)(ary+arh)) || ((y+h) arx) && (x<(arx+arw)) ) { + arw = arw - (x-arx); + arx = arx + (x-arx); + } else { + bmp_offx = arx; + } + if ( ((x+w) > arx) && ((x+w)<(arx+arw)) ) { + arw -= (arx+arw-x-w); + } + if ( (y > ary) && (y<(ary+arh)) ) { + arh = arh - (y-ary); + ary = ary + (y-ary); + } else { + bmp_offy = ary; + } + if ( ((y+h) > ary) && ((y+h)<(ary+arh)) ) { + arh -= (ary+arh-y-h); + } + } + + + int l=ary; + bitmap = bitmap + bmp_offy*w + bmp_offx; + for (int row=0;row>6]; + uint16_t * dst=&block[(l&0x3F)*TFT_WIDTH+arx]; + bmp_ptr = (uint16_t*)bitmap; + for (int col=0;col> 8); + cnt = cnt & (sampleBufferSize*2-1); + + if (cnt == 0) { + fillfirsthalf = false; + //irq_set_pending(RTC_IRQ+1); + multicore_fifo_push_blocking(0); + } + else if (cnt == sampleBufferSize) { + fillfirsthalf = true; + //irq_set_pending(RTC_IRQ+1); + multicore_fifo_push_blocking(0); + } +} + +static void core1_sio_irq() { + irq_clear(SIO_IRQ_PROC1); + while(multicore_fifo_rvalid()) { + uint16_t raw = multicore_fifo_pop_blocking(); + SOFTWARE_isr(); + } + multicore_fifo_clear_irq(); +} + +static void core1_func() { + multicore_fifo_clear_irq(); + irq_set_exclusive_handler(SIO_IRQ_PROC1,core1_sio_irq); + //irq_set_priority (SIO_IRQ_PROC1, 129); + irq_set_enabled(SIO_IRQ_PROC1,true); + + while (true) { + tight_loop_contents(); + } +} + +void TFT_T_DMA::begin_audio(int samplesize, void (*callback)(short * stream, int len)) +{ + fillsamples = callback; + i2s_tx_buffer = (uint32_t*)malloc(samplesize*sizeof(uint32_t)); + + if (i2s_tx_buffer == NULL) { + printf("sound buffer could not be allocated!!!!!\n"); + return; + } + memset((void*)i2s_tx_buffer,0, samplesize*sizeof(uint32_t)); + printf("sound buffer allocated\n"); + + i2s_tx_buffer16 = (short*)i2s_tx_buffer; + + sampleBufferSize = samplesize; + + gpio_set_function(AUDIO_PIN, GPIO_FUNC_PWM); + + + multicore_launch_core1(core1_func); + + + int audio_pin_slice = pwm_gpio_to_slice_num(AUDIO_PIN); + // Setup PWM interrupt to fire when PWM cycle is complete + pwm_clear_irq(audio_pin_slice); + pwm_set_irq_enabled(audio_pin_slice, true); + irq_set_exclusive_handler(PWM_IRQ_WRAP, AUDIO_isr); + irq_set_priority (PWM_IRQ_WRAP, 128); + irq_set_enabled(PWM_IRQ_WRAP, true); + + //irq_set_exclusive_handler(RTC_IRQ+1,SOFTWARE_isr); + //irq_set_priority (RTC_IRQ+1, 120); + //irq_set_enabled(RTC_IRQ+1,true); + + + // Setup PWM for audio output + pwm_config config = pwm_get_default_config(); +// pwm_config_set_clkdiv(&config, 5.5f); + pwm_config_set_clkdiv(&config, 50.0f); + pwm_config_set_wrap(&config, 254); + pwm_init(audio_pin_slice, &config, true); + + pwm_set_gpio_level(AUDIO_PIN, 0); + printf("sound initialized\n"); +} + +void TFT_T_DMA::end_audio() +{ + if (i2s_tx_buffer != NULL) { + free(i2s_tx_buffer); + } +} +#endif diff --git a/MCUME_pico/tft_t/tft_t_dma.h b/MCUME_pico/tft_t/tft_t_dma.h new file mode 100644 index 0000000..9a69d3e --- /dev/null +++ b/MCUME_pico/tft_t/tft_t_dma.h @@ -0,0 +1,220 @@ +#ifndef _TFT_T_DMAH_ +#define _TFT_T_DMAH_ + +#ifdef __cplusplus +#include +#include +#include "pico.h" +#endif + +#include "tft_t_dma_config.h" + +#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b ) +#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) ) +#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) ) +#define R16(rgb) ((rgb>>8)&0xf8) +#define G16(rgb) ((rgb>>3)&0xfc) +#define B16(rgb) ((rgb<<3)&0xf8) + + +#ifdef LOHRES +#define TFT_WIDTH 240 +#define TFT_REALWIDTH 240 +#else +#define TFT_WIDTH 320 +#define TFT_REALWIDTH 320 +#endif +#define TFT_HEIGHT 240 +#define TFT_REALHEIGHT 240 + + +#define LINES_PER_BLOCK 64 +#define NR_OF_BLOCK 4 + + +#ifdef ILI9341 + +#define ILI9341_NOP 0x00 +#define ILI9341_SWRESET 0x01 +#define ILI9341_RDDID 0x04 +#define ILI9341_RDDST 0x09 + +#define ILI9341_SLPIN 0x10 +#define ILI9341_SLPOUT 0x11 +#define ILI9341_PTLON 0x12 +#define ILI9341_NORON 0x13 + +#define ILI9341_RDMODE 0x0A +#define ILI9341_RDMADCTL 0x0B +#define ILI9341_RDPIXFMT 0x0C +#define ILI9341_RDIMGFMT 0x0D +#define ILI9341_RDSELFDIAG 0x0F + +#define ILI9341_INVOFF 0x20 +#define ILI9341_INVON 0x21 +#define ILI9341_GAMMASET 0x26 +#define ILI9341_DISPOFF 0x28 +#define ILI9341_DISPON 0x29 + +#define ILI9341_CASET 0x2A +#define ILI9341_PASET 0x2B +#define ILI9341_RAMWR 0x2C +#define ILI9341_RAMRD 0x2E + +#define ILI9341_PTLAR 0x30 +#define ILI9341_MADCTL 0x36 +#define ILI9341_VSCRSADD 0x37 +#define ILI9341_PIXFMT 0x3A + +#define ILI9341_FRMCTR1 0xB1 +#define ILI9341_FRMCTR2 0xB2 +#define ILI9341_FRMCTR3 0xB3 +#define ILI9341_INVCTR 0xB4 +#define ILI9341_DFUNCTR 0xB6 + +#define ILI9341_PWCTR1 0xC0 +#define ILI9341_PWCTR2 0xC1 +#define ILI9341_PWCTR3 0xC2 +#define ILI9341_PWCTR4 0xC3 +#define ILI9341_PWCTR5 0xC4 +#define ILI9341_VMCTR1 0xC5 +#define ILI9341_VMCTR2 0xC7 + +#define ILI9341_RDID1 0xDA +#define ILI9341_RDID2 0xDB +#define ILI9341_RDID3 0xDC +#define ILI9341_RDID4 0xDD + +#define ILI9341_GMCTRP1 0xE0 +#define ILI9341_GMCTRN1 0xE1 + +#define ILI9341_MADCTL_MY 0x80 +#define ILI9341_MADCTL_MX 0x40 +#define ILI9341_MADCTL_MV 0x20 +#define ILI9341_MADCTL_ML 0x10 +#define ILI9341_MADCTL_RGB 0x00 +#define ILI9341_MADCTL_BGR 0x08 +#define ILI9341_MADCTL_MH 0x04 + +#define TFT_CASET ILI9341_CASET +#define TFT_PASET ILI9341_PASET +#define TFT_RAMWR ILI9341_RAMWR +#define TFT_MADCTL ILI9341_MADCTL + +#endif + + +#ifdef ST7789 + +#define ST7735_NOP 0x00 +#define ST7735_SWRESET 0x01 +#define ST7735_RDDID 0x04 +#define ST7735_RDDST 0x09 + +#define ST7735_SLPIN 0x10 +#define ST7735_SLPOUT 0x11 +#define ST7735_PTLON 0x12 +#define ST7735_NORON 0x13 + +#define ST7735_INVOFF 0x20 +#define ST7735_INVON 0x21 +#define ST7735_DISPOFF 0x28 +#define ST7735_DISPON 0x29 +#define ST7735_CASET 0x2A +#define ST7735_RASET 0x2B +#define ST7735_RAMWR 0x2C +#define ST7735_RAMRD 0x2E + +#define ST7735_PTLAR 0x30 +#define ST7735_COLMOD 0x3A +#define ST7735_MADCTL 0x36 + +#define ST7735_FRMCTR1 0xB1 +#define ST7735_FRMCTR2 0xB2 +#define ST7735_FRMCTR3 0xB3 +#define ST7735_INVCTR 0xB4 +#define ST7735_DISSET5 0xB6 + +#define ST7735_PWCTR1 0xC0 +#define ST7735_PWCTR2 0xC1 +#define ST7735_PWCTR3 0xC2 +#define ST7735_PWCTR4 0xC3 +#define ST7735_PWCTR5 0xC4 +#define ST7735_VMCTR1 0xC5 + +#define ST7735_RDID1 0xDA +#define ST7735_RDID2 0xDB +#define ST7735_RDID3 0xDC +#define ST7735_RDID4 0xDD + +#define ST7735_PWCTR6 0xFC + +#define ST7735_GMCTRP1 0xE0 +#define ST7735_GMCTRN1 0xE1 + +#define ST77XX_MADCTL_MY 0x80 +#define ST77XX_MADCTL_MX 0x40 +#define ST77XX_MADCTL_MV 0x20 +#define ST77XX_MADCTL_ML 0x10 +#define ST77XX_MADCTL_RGB 0x00 +#define ST77XX_MADCTL_BGR 0x08 +#define ST77XX_MADCTL_MH 0x04 + +#define TFT_CASET ST7735_CASET +#define TFT_PASET ST7735_RASET +#define TFT_RAMWR ST7735_RAMWR +#define TFT_MADCTL ST7735_MADCTL + +#endif + + + +#ifdef __cplusplus + +class TFT_T_DMA +{ + public: + TFT_T_DMA(); + + void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2); + void begin(void); + void flipscreen(bool flip); + bool isflipped(void); + void startDMA(void); + void stopDMA(); + int get_frame_buffer_size(int *width, int *height); + void waitSync(); + + void begin_audio(int samplesize, void (*callback)(short * stream, int len)); + void end_audio(); + + // NoDMA functions + void fillScreenNoDma(uint16_t color); + void writeScreenNoDma(const uint16_t *pcolors); + void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize); + void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap); + void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh); + + // DMA functions + uint16_t * getLineBuffer(int j); + void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16); + void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16); + void writeLine(int width, int height, int y, uint16_t *buf); + void fillScreen(uint16_t color); + void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize); + void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap); + void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh); + + protected: + uint8_t _rst, _cs, _dc; + uint8_t _miso, _mosi, _sclk; + bool flipped=false; + + void wait(void); +}; + +#endif +#endif + diff --git a/MCUME_pico/tft_t/tft_t_dma_config.h b/MCUME_pico/tft_t/tft_t_dma_config.h new file mode 100644 index 0000000..3227712 --- /dev/null +++ b/MCUME_pico/tft_t/tft_t_dma_config.h @@ -0,0 +1,11 @@ +#include "platform_config.h" +#include "iopins.h" + +//#define ST7789 1 +//#define ILI9341 1 + +//#define TFT_STATICFB 1 +#define TFT_LINEARINT 1 +#define LINEARINT_HACK 1 + + diff --git a/MCUME_pico/vga_t4/.DS_Store b/MCUME_pico/vga_t4/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/MCUME_pico/vga_t4/.DS_Store and /dev/null differ diff --git a/MCUME_pico/vga_t4/VGA_t4.cpp b/MCUME_pico/vga_t4/VGA_t4.cpp index f7bd217..7c5d1df 100755 --- a/MCUME_pico/vga_t4/VGA_t4.cpp +++ b/MCUME_pico/vga_t4/VGA_t4.cpp @@ -23,6 +23,11 @@ #include "hardware/irq.h" #include +#include "platform_config.h" +#include "iopins.h" + +#ifdef USE_VGA + #define R16(rgb) ((rgb>>8)&0xf8) #define G16(rgb) ((rgb>>3)&0xfc) #define B16(rgb) ((rgb<<3)&0xf8) @@ -1611,8 +1616,6 @@ void VGA_T4::set_vscroll(int layer, int colbeg, int colend, int mask) #include "hardware/irq.h" #include "hardware/pwm.h" -#define AUDIO_PIN 28 - static bool fillfirsthalf = true; static uint16_t cnt = 0; static uint16_t sampleBufferSize = 0; @@ -1709,7 +1712,6 @@ void VGA_T4::end_audio() } } - - +#endif diff --git a/MCUME_pico/vga_t4/scanvideo.c b/MCUME_pico/vga_t4/scanvideo.c index f8b6a06..96af1c5 100644 --- a/MCUME_pico/vga_t4/scanvideo.c +++ b/MCUME_pico/vga_t4/scanvideo.c @@ -27,7 +27,9 @@ #include "hardware/structs/bus_ctrl.h" #include "pico/binary_info.h" +#include "iopins.h" +#ifdef USE_VGA // PICO_CONFIG: PICO_SCANVIDEO_ADJUST_BUS_PRIORITY, Enable/disable adjust bus priority, type=bool, default=0, group=video #ifndef PICO_SCANVIDEO_ADJUST_BUS_PRIORITY @@ -649,6 +651,6 @@ void scanvideo_wait_for_vblank() { sem_acquire_blocking(&vblank_begin); } - +#endif #pragma GCC pop_options diff --git a/MCUME_pico/vga_t4/scanvideo_base.h b/MCUME_pico/vga_t4/scanvideo_base.h index ee5b2da..081c26c 100644 --- a/MCUME_pico/vga_t4/scanvideo_base.h +++ b/MCUME_pico/vga_t4/scanvideo_base.h @@ -22,7 +22,7 @@ extern "C" { // == CONFIG ============ #ifndef PICO_SCANVIDEO_COLOR_PIN_BASE -#define PICO_SCANVIDEO_COLOR_PIN_BASE 2 +#define PICO_SCANVIDEO_COLOR_PIN_BASE VGA_COLORBASE #endif #ifndef PICO_SCANVIDEO_COLOR_PIN_COUNT @@ -30,7 +30,7 @@ extern "C" { #endif #ifndef PICO_SCANVIDEO_SYNC_PIN_BASE -#define PICO_SCANVIDEO_SYNC_PIN_BASE (PICO_SCANVIDEO_COLOR_PIN_BASE + PICO_SCANVIDEO_COLOR_PIN_COUNT) +#define PICO_SCANVIDEO_SYNC_PIN_BASE VGA_SYNCBASE #endif