fix PICOMPUTERMAX keyboard and add dual screen support to MCUME_REV2

This commit is contained in:
jean-marcharvengt 2021-10-08 21:46:02 +02:00
parent a47483d3e6
commit 42601b4e91
47 changed files with 2264 additions and 542 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -32,8 +32,10 @@
#ifdef KEYMAP_PRESENT
#ifdef PICOMPUTER
#define keylables_map1_0 (char *)" "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
const unsigned short key_map1[] = {
15+1,14+1,13+1,11+1,10+1,9+1,7+1,6+1,5+1,2+1,0,
0,12+1,8+1,4+1,0+1,1+1,3+1,0,0,0,0,
@ -47,6 +49,9 @@ const unsigned short key_map1[] = {
// [PAUSE] 8 [ 6 ] 9 [ 5 ] 10 [ 4 ] 11
// [START] 12 [ 3 ] 13 [ 2 ] 14 [ 1 ] 15
#define keylables_map2_0 (char *)" "
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" "
const unsigned short key_map2[] = {
0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,
@ -54,6 +59,9 @@ const unsigned short key_map2[] = {
0,0,0,0
};
#define keylables_map3_0 (char *)" "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
const unsigned short key_map3[] = {
0,0,0,0,0,0,0,0,0,0,0, // function keys
0, 0,0,0,0,0,0,0,0,0,0,
@ -68,7 +76,6 @@ const unsigned short matkeys[] = {
0x508,0x501,0x502,0x504 }; // cursor keys
#endif
#endif
@ -86,7 +93,7 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_DOWN 0x0800
#define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000
#define MASK_OSKB 0x8000
extern void emu_init(void);

View file

@ -210,19 +210,19 @@ static void drawOskb(void)
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, (char *)"qwertyuiop\x1a", 0);
lineOSKB(KXOFF,KYOFF, (char *)" asdfghjkl\x19", 1);
lineOSKB(KXOFF,KYOFF, (char *)" zxcvbnm.\x10 ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, (char *)"1234567890=", 0);
lineOSKB(KXOFF,KYOFF, (char *)" !@#$%+&*- ", 1);
lineOSKB(KXOFF,KYOFF, (char *)" ()?/\"<>,: ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 ", 0);
lineOSKB(KXOFF,KYOFF, (char *)" ", 1);
lineOSKB(KXOFF,KYOFF, (char *)" ; ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
@ -306,6 +306,7 @@ static int handleOskb(void)
else {
retval = key_map3[retval];
}
//if (retval) { toggleOskb(true); updated=false; };
}
}
else {
@ -495,7 +496,12 @@ int emu_ReadKeys(void)
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
row=0;
row |= (gpio_get(9) ? 0 : 0x01);
row |= (gpio_get(9) ? 0 : 0x01);
@ -506,12 +512,16 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -527,13 +537,15 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -549,11 +561,13 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
@ -848,34 +862,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -884,18 +889,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}

View file

@ -29,6 +29,9 @@
#ifdef KEYMAP_PRESENT
#define keylables_map1_0 (char *)"qwertyuiop\x1a"
#define keylables_map1_1 (char *)" asdfghjkl\x19"
#define keylables_map1_2 (char *)" zxcvbnm.\x10 "
const unsigned short key_map1[] = {
'Q','W','E','R','T','Y','U','I','O','P',157,
0,'A','S','D','F','G','H','J','K','L',0x0D,
@ -36,6 +39,9 @@ const unsigned short key_map1[] = {
145,157,29,17
};
#define keylables_map2_0 (char *)"1234567890 "
#define keylables_map2_1 (char *)" !@#$%+&*- "
#define keylables_map2_2 (char *)" ()?/\"<>,: "
const unsigned short key_map2[] = {
'1','2','3','4','5','6','7','8','9','0',0,
0, '!','@','#','$','%','+','&','*','-','\/',
@ -43,6 +49,9 @@ const unsigned short key_map2[] = {
0,0,0,0
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" ;= "
const unsigned short key_map3[] = {
133,134,135,136,137,138,139,140,0,0,0, // function keys
0, 0,0,0,0,0,0,0,0,0,0,

View file

@ -13,11 +13,19 @@ extern "C" {
#include "iopins.h"
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// Dual display config, initialize TFT
#include "tft_t_dma.h"
static TFT_T_DMA tft;
#else
// Non Dual display config
#ifdef USE_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
extern TFT_T_DMA tft;
#endif
#define MAX_FILES 64
@ -39,7 +47,7 @@ extern "C" {
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft;
static char romspath[64];
static int nbFiles=0;
@ -142,8 +150,175 @@ void emu_Free(void * pt)
free(pt);
}
void emu_drawText(unsigned short x, unsigned short y, const char * text, unsigned short fgcolor, unsigned short bgcolor, int doublesize)
{
tft.drawText(x, y, text, fgcolor, bgcolor, doublesize?true:false);
}
/********************************
* OSKB handling
********************************/
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// On screen keyboard position
#define KXOFF 28 //64
#define KYOFF 96
#define KWIDTH 11 //22
#define KHEIGHT 3
static bool oskbOn = false;
static int cxpos = 0;
static int cypos = 0;
static int oskbMap = 0;
static uint16_t oskbBLastState = 0;
static void lineOSKB2(int kxoff, int kyoff, char * str, int row)
{
char c[2] = {'A',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[0] = *cpt++;
c[1] = 0;
uint16_t bg = RGBVAL16(0x00,0x00,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0xff,0x00,0x00);
tft.drawTextNoDma(kxoff+8*i,kyoff, &c[0], RGBVAL16(0x00,0xff,0xff), bg, ((i&1)?false:true));
}
}
static void lineOSKB(int kxoff, int kyoff, char * str, int row)
{
char c[4] = {' ',0,' ',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[1] = *cpt++;
uint16_t bg;
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+0 , " ", RGBVAL16(0x00,0x00,0x00), bg, false);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+8 , &c[0], RGBVAL16(0x00,0x00,0x00), bg, true);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+24, " ", RGBVAL16(0x00,0x00,0x00), bg, false);
}
}
static void drawOskb(void)
{
// lineOSKB2(KXOFF,KYOFF+0, (char *)"Q1W2E3R4T5Y6U7I8O9P0<=", 0);
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
void toggleOskb(bool forceoff) {
if (forceoff) oskbOn=true;
if (oskbOn) {
oskbOn = false;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, "Press USER2 to toggle onscreen keyboard.", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
} else {
oskbOn = true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, " Press USER2 to exit onscreen keyboard. ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
tft.drawTextNoDma(0,64, " (USER1 to toggle between keymaps) ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
tft.drawRectNoDma(KXOFF,KYOFF, 22*8, 3*16, RGBVAL16(0x00,0x00,0xFF));
drawOskb();
}
}
static int handleOskb(void)
{
int retval = 0;
uint16_t bClick = bLastState & ~oskbBLastState;
oskbBLastState = bLastState;
/*
static const char * digits = "0123456789ABCDEF";
char buf[5] = {0,0,0,0,0};
int val = bClick;
buf[0] = digits[(val>>12)&0xf];
buf[1] = digits[(val>>8)&0xf];
buf[2] = digits[(val>>4)&0xf];
buf[3] = digits[val&0xf];
tft.drawTextNoDma(0,KYOFF+ 64,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),1);
*/
if (bClick & MASK_KEY_USER2)
{
toggleOskb(false);
}
if (oskbOn)
{
bool updated = true;
if (bClick & MASK_KEY_USER1)
{
oskbMap += 1;
if (oskbMap == 3) oskbMap = 0;
}
else if (bClick & MASK_JOY2_LEFT)
{
cxpos++;
if (cxpos >= KWIDTH) cxpos = 0;
}
else if (bClick & MASK_JOY2_RIGHT)
{
cxpos--;
if (cxpos < 0) cxpos = KWIDTH-1;
}
else if (bClick & MASK_JOY2_DOWN)
{
cypos++;
if (cypos >= KHEIGHT) cypos = 0;
}
else if (bClick & MASK_JOY2_UP)
{
cypos--;
if (cypos < 0) cypos = KHEIGHT-1;
}
else if (oskbBLastState & MASK_JOY2_BTN)
{
retval = cypos*KWIDTH+cxpos+1;
if (retval) {
retval--;
//if (retval & 1) retval = key_map2[retval>>1];
//else retval = key_map1[retval>>1];
if (oskbMap == 0) {
retval = key_map1[retval];
}
else if (oskbMap == 1) {
retval = key_map2[retval];
}
else {
retval = key_map3[retval];
}
//if (retval) { toggleOskb(true); updated=false; };
}
}
else {
updated=false;
}
if (updated) drawOskb();
}
return retval;
}
#endif
/********************************
* Input and keyboard
********************************/
@ -318,8 +493,10 @@ int emu_ReadKeys(void)
keymatrix_hitrow = -1;
unsigned char row;
unsigned short cols[6]={1,2,3,4,5,14};
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -335,27 +512,80 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
keymatrix[i]=row;
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
unsigned char alt = keymatrix[0] & 0x02;
unsigned char del = keymatrix[5] & 0x20;
keymatrix[0] &= ~0x02;
keymatrix[5] &= ~0x20;
if (alt) keymatrix[5] |= 0x20;
if (del) keymatrix[0] |= 0x02;
unsigned char alt = keymatrixtmp[0] & 0x02;
unsigned char del = keymatrixtmp[5] & 0x20;
keymatrixtmp[0] &= ~0x02;
keymatrixtmp[5] &= ~0x20;
if (alt) keymatrixtmp[5] |= 0x20;
if (del) keymatrixtmp[0] |= 0x02;
#endif
bool alt_pressed=false;
if ( keymatrix[5] & 0x20 ) {alt_pressed=true; keymatrix[5] &= ~0x20;};
if ( keymatrixtmp[5] & 0x20 ) {alt_pressed=true; keymatrixtmp[5] &= ~0x20;};
for (int i=0;i<6;i++){
row = keymatrix[i];
row = keymatrixtmp[i];
if (row) keymatrix_hitrow=i;
keymatrix[i] = row;
}
//6,9,15,8,7,22
@ -400,6 +630,7 @@ int emu_ReadKeys(void)
if (hundred_ms_cnt >= 2)
{
hundred_ms_cnt = 0;
/*
if ( (time_ms-keypress_t_ms) < 500)
{
if (key_alt == false)
@ -411,13 +642,14 @@ int emu_ReadKeys(void)
key_alt = false;
}
}
*/
}
}
}
else {
// Keep press
if (hundred_ms_cnt == 1) {
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 1000)
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 2000)
{
if (key_alt == false)
{
@ -461,6 +693,12 @@ int emu_ReadKeys(void)
{
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (oskbOn) {
retval |= MASK_OSKB;
}
#endif
return (retval);
}
@ -487,8 +725,6 @@ int emu_ReadI2CKeyboard(void) {
}
if (keymatrix_hitrow >=0 ) {
unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow];
//if ( (match == 0x002 ) ) return 0; // shift or fn
//if (match < 0x100 ) match = match & ~0x002; // ignore shift key
for (int i=0; i<sizeof(matkeys)/sizeof(unsigned short); i++) {
if (match == matkeys[i]) {
hundred_ms_cnt = 0;
@ -496,6 +732,11 @@ int emu_ReadI2CKeyboard(void) {
}
}
}
#endif
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (!menuOn) {
retval = handleOskb();
}
#endif
return(retval);
}
@ -621,34 +862,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -657,18 +889,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}
@ -722,6 +954,14 @@ void backgroundMenu(void) {
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
}
static void menuLeft(void)
{
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
toggleOskb(true);
#endif
}
int handleMenu(uint16_t bClick)
{
int action = ACTION_NONE;
@ -741,12 +981,13 @@ int handleMenu(uint16_t bClick)
strcpy(romspath,newpath);
curFile = 0;
nbFiles = readNbFiles(newpath);
menuRedraw=true;
}
else
{
action = ACTION_RUNTFT;
menuLeft();
}
menuRedraw=true;
}
else if ( (bClick & MASK_KEY_USER1) ) {
menuRedraw=true;
@ -980,6 +1221,11 @@ int emu_LoadFile(char * filename, char * buf, int size)
********************************/
void emu_init(void)
{
// Dual display config, initialize TFT
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
tft.begin();
#endif
sd_init_driver();
FRESULT fr = f_mount(&fatfs, "0:", 1);

View file

@ -32,36 +32,45 @@
#ifdef KEYMAP_PRESENT
#ifdef PICOMPUTER
#define keylables_map1_0 (char *)"qwertyuiop\x1a"
#define keylables_map1_1 (char *)" asdfghjkl\x19"
#define keylables_map1_2 (char *)" zxcvbnm.\x10 "
const unsigned short key_map1[] = {
//0x1F+1,0x1F ,0x1A+1,0x18+1,0x1D+1,0x1B+1,0x33+1,0x35+1,0x30+1,0x32+1,0x34+1, // Digits
0x2F+1,0x2F ,0x2A+1,0x28+1,0x2D+1,0x2B+1,0x0B+1,0x0D+1,0x08+1,0x0A+1,0x34+1,
0x2C+1,0x3F+1,0x3F ,0x3A+1,0x38+1,0x3D+1,0x39+1,0x01+1,0x05+1,0x00+1,0x0C+1,
0, 0x17+1,0x16+1,0x12+1,0x10+1,0x15+1,0x23+1,0x25+1,0x20+1, 0x21+1,
0x2F+1,0x2F,0x2A+1,0x28+1,0x2D+1,0x2B+1,0x0B+1,0x0D+1,0x08+1,0x0A+1,0x34+1,
0,0x3F+1,0x3F,0x3A+1,0x38+1,0x3D+1,0x39+1,0x01+1,0x05+1,0x00+1,0x0C+1,
0,0x17+1,0x16+1,0x12+1,0x10+1,0x15+1,0x23+1,0x25+1,0x22+1, 0x21+1,
0,0,0,0
};
#define keylables_map2_0 (char *)"1234567890="
#define keylables_map2_1 (char *)"T!@#$%+&*- "
#define keylables_map2_2 (char *)" ()?/\"<>,: "
const unsigned short key_map2[] = {
0x1F+1,0x1F,0x1A+1,0x18+1,0x1D+1,0x1B+1,0x33+1,0x35+1,0x30+1,0x32+1,0x34+1, // Digits
0x2C+1,0x07+1,0x22+1,0x26+1,0x02+1,0x06+1,0x36+1,0x37+1,0x0F+1,0x0E + 1,0x06+1, // various
0x1F+1,0x1F,0x1A+1,0x18+1,0x1D+1,0x1B+1,0x33+1,0x35+1,0x30+1,0x32+1,0x0F+1, // Digits
0x2C+1,95+1,117+1,90+1,88+1,93+1,0x06+1,91+1,0x07+1,0x0E + 1,0, // various
0, 112+1,114+1,102+1,0x26+1,94+1,0x36+1,0x37+1,0x20+1,66+1,
0,0,0,0
};
//0x07+1=*, 0x22+1=.,0x26+1=/, 0x02+1=;, 0x06+1=+, 0x36+1=<, 0x37+1=>, 0x0F+1==, 0x0E+1=-, 0x06+1=+
0, 0,0,0,0,0,3,4,19,20,
#define keylables_map3_0 (char *)"\x11\x12\x13\x14H "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" ' ; "
const unsigned short key_map3[] = {
3+1,4+1,19+1,20+1,17+1,0,0,0,0,0,0, // function keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,115+1,0,0,0x02+1,0,
0,0,0,0
};
const unsigned short key_map3[] = {
0,0,0,0,0,0,0,0,0,0,0, // function keys
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,0x002, // row 1
0x510,0x010,0x110,0x210,0x310,0x410,0x401,0x301,0x201,0x101,0x001, // row 2
0x520,0x102,0x202,0x302,0x402,0x404,0x304,0x204,0x104,0x004, // row 3
0x508,0x501,0x502,0x504 }; // cursor keys
#endif
#endif
/* Pokey code
@ -139,7 +148,7 @@ KEY_L = 0
#define MASK_JOY1_DOWN 0x0800
#define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000
#define MASK_OSKB 0x8000
extern void emu_init(void);

View file

@ -19,6 +19,7 @@ extern "C" {
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
volatile bool vbl=true;
bool repeating_timer_callback(struct repeating_timer *t) {
@ -29,7 +30,6 @@ bool repeating_timer_callback(struct repeating_timer *t) {
}
return true;
}
#endif
TFT_T_DMA tft;
static int skip=0;
@ -62,10 +62,8 @@ int main(void) {
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
#ifndef USE_VGA
struct repeating_timer timer;
add_repeating_timer_ms(15, repeating_timer_callback, NULL, &timer);
#endif
}
tft.waitSync();
}

View file

@ -210,19 +210,19 @@ static void drawOskb(void)
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, (char *)"qwertyuiop\x1a", 0);
lineOSKB(KXOFF,KYOFF, (char *)" asdfghjkl\x19", 1);
lineOSKB(KXOFF,KYOFF, (char *)" zxcvbnm.\x10 ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, (char *)"1234567890=", 0);
lineOSKB(KXOFF,KYOFF, (char *)" $ + *- ", 1);
lineOSKB(KXOFF,KYOFF, (char *)" ()?/\"<>,: ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, (char *)" ", 0);
lineOSKB(KXOFF,KYOFF, (char *)" ", 1);
lineOSKB(KXOFF,KYOFF, (char *)" ; ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
@ -306,6 +306,7 @@ static int handleOskb(void)
else {
retval = key_map3[retval];
}
//if (retval) { toggleOskb(true); updated=false; };
}
}
else {
@ -495,7 +496,12 @@ int emu_ReadKeys(void)
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
row=0;
row |= (gpio_get(9) ? 0 : 0x01);
row |= (gpio_get(9) ? 0 : 0x01);
@ -506,12 +512,16 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -527,13 +537,15 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -549,11 +561,13 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
@ -848,34 +862,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -884,18 +889,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}

View file

@ -38,6 +38,9 @@
{ 5,17,16,1,44}, // bnm. <space>
*/
#define keylables_map1_0 (char *)"qwertyuiop\x1a"
#define keylables_map1_1 (char *)" asdfghjkl\x19"
#define keylables_map1_2 (char *)" zxcvbnm.\x10 "
const unsigned short key_map1[] = {
20,26,8,21,23,28,24,12,18,19,39+64,
0, 4, 22, 7,9, 10,11,13,14,15,40,
@ -45,6 +48,9 @@ const unsigned short key_map1[] = {
0,0,0,0 //up,left,right,down
};
#define keylables_map2_0 (char *)"1234567890="
#define keylables_map2_1 (char *)" $ + *- "
#define keylables_map2_2 (char *)" ()?/\"<>,: "
const unsigned short key_map2[] = {
30,31,32,33,34,35,36,37,38,39,15+64,
0, 0,0,0,24+64,0,14+64,0,5+64,13+64,0,
@ -52,6 +58,9 @@ const unsigned short key_map2[] = {
36+64,34+64,37+64,35+64 //up,left,right,down
};
#define keylables_map3_0 (char *)" "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" ; "
const unsigned short key_map3[] = {
0, 0,0,0,0,0,0,0,0,0,0, // Upper case
0, 0,0,0,0,0,0,0,0,0,0,

View file

@ -263,27 +263,28 @@ void SetColor(byte N,byte R,byte G,byte B)
void Joysticks(void)
{
int k;
int j;
int ij;
//int j;
int hk;
int N=0;
word JS[2] = { 0xFFFF,0xFFFF };
k=emu_ReadKeys();
j=emu_GetPad();
ij=emu_ReadI2CKeyboard();
k = emu_GetPad() & 0x7fff;
hk = emu_ReadI2CKeyboard();
if (j & 0x8000) N = 1;
else N = 0;
//if (j & 0x8000) N = 1;
//else N = 0;
if(j)
JS[N]=(JS[N]&0xFFF0)|(j-1);
if(ij)
JS[N]=(JS[N]&0xFFF0)|(ij-1);
if(k)
JS[N]=(JS[N]&0xFFF0)|(k-1);
if(hk)
JS[N]=(JS[N]&0xFFF0)|(hk-1);
if (k & MASK_JOY2_BTN)
{
JS[N]&=0xBFFF; //Fire 1
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
#else
if (k & MASK_KEY_USER1)
{
JS[N]&=0xFFBF; //Fire 2
@ -292,6 +293,7 @@ void Joysticks(void)
{
JS[0]=(JS[0]&0xFFF0)|(2); //1
}
#endif
// JS[0]=(JS[0]&0xFFF0)|(12);
// JS[0]=(JS[0]&0xFFF0)|(13);

View file

@ -13,11 +13,19 @@ extern "C" {
#include "iopins.h"
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// Dual display config, initialize TFT
#include "tft_t_dma.h"
static TFT_T_DMA tft;
#else
// Non Dual display config
#ifdef USE_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
extern TFT_T_DMA tft;
#endif
#define MAX_FILES 64
@ -39,7 +47,7 @@ extern "C" {
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft;
static char romspath[64];
static int nbFiles=0;
@ -142,8 +150,175 @@ void emu_Free(void * pt)
free(pt);
}
void emu_drawText(unsigned short x, unsigned short y, const char * text, unsigned short fgcolor, unsigned short bgcolor, int doublesize)
{
tft.drawText(x, y, text, fgcolor, bgcolor, doublesize?true:false);
}
/********************************
* OSKB handling
********************************/
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// On screen keyboard position
#define KXOFF 28 //64
#define KYOFF 96
#define KWIDTH 11 //22
#define KHEIGHT 3
static bool oskbOn = false;
static int cxpos = 0;
static int cypos = 0;
static int oskbMap = 0;
static uint16_t oskbBLastState = 0;
static void lineOSKB2(int kxoff, int kyoff, char * str, int row)
{
char c[2] = {'A',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[0] = *cpt++;
c[1] = 0;
uint16_t bg = RGBVAL16(0x00,0x00,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0xff,0x00,0x00);
tft.drawTextNoDma(kxoff+8*i,kyoff, &c[0], RGBVAL16(0x00,0xff,0xff), bg, ((i&1)?false:true));
}
}
static void lineOSKB(int kxoff, int kyoff, char * str, int row)
{
char c[4] = {' ',0,' ',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[1] = *cpt++;
uint16_t bg;
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+0 , " ", RGBVAL16(0x00,0x00,0x00), bg, false);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+8 , &c[0], RGBVAL16(0x00,0x00,0x00), bg, true);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+24, " ", RGBVAL16(0x00,0x00,0x00), bg, false);
}
}
static void drawOskb(void)
{
// lineOSKB2(KXOFF,KYOFF+0, (char *)"Q1W2E3R4T5Y6U7I8O9P0<=", 0);
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
void toggleOskb(bool forceoff) {
if (forceoff) oskbOn=true;
if (oskbOn) {
oskbOn = false;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, "Press USER2 to toggle onscreen keyboard.", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
} else {
oskbOn = true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, " Press USER2 to exit onscreen keyboard. ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
tft.drawTextNoDma(0,64, " (USER1 to toggle between keymaps) ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
tft.drawRectNoDma(KXOFF,KYOFF, 22*8, 3*16, RGBVAL16(0x00,0x00,0xFF));
drawOskb();
}
}
static int handleOskb(void)
{
int retval = 0;
uint16_t bClick = bLastState & ~oskbBLastState;
oskbBLastState = bLastState;
/*
static const char * digits = "0123456789ABCDEF";
char buf[5] = {0,0,0,0,0};
int val = bClick;
buf[0] = digits[(val>>12)&0xf];
buf[1] = digits[(val>>8)&0xf];
buf[2] = digits[(val>>4)&0xf];
buf[3] = digits[val&0xf];
tft.drawTextNoDma(0,KYOFF+ 64,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),1);
*/
if (bClick & MASK_KEY_USER2)
{
toggleOskb(false);
}
if (oskbOn)
{
bool updated = true;
if (bClick & MASK_KEY_USER1)
{
oskbMap += 1;
if (oskbMap == 3) oskbMap = 0;
}
else if (bClick & MASK_JOY2_LEFT)
{
cxpos++;
if (cxpos >= KWIDTH) cxpos = 0;
}
else if (bClick & MASK_JOY2_RIGHT)
{
cxpos--;
if (cxpos < 0) cxpos = KWIDTH-1;
}
else if (bClick & MASK_JOY2_DOWN)
{
cypos++;
if (cypos >= KHEIGHT) cypos = 0;
}
else if (bClick & MASK_JOY2_UP)
{
cypos--;
if (cypos < 0) cypos = KHEIGHT-1;
}
else if (oskbBLastState & MASK_JOY2_BTN)
{
retval = cypos*KWIDTH+cxpos+1;
if (retval) {
retval--;
//if (retval & 1) retval = key_map2[retval>>1];
//else retval = key_map1[retval>>1];
if (oskbMap == 0) {
retval = key_map1[retval];
}
else if (oskbMap == 1) {
retval = key_map2[retval];
}
else {
retval = key_map3[retval];
}
if (retval) { toggleOskb(true); updated=false; };
}
}
else {
updated=false;
}
if (updated) drawOskb();
}
return retval;
}
#endif
/********************************
* Input and keyboard
********************************/
@ -318,8 +493,10 @@ int emu_ReadKeys(void)
keymatrix_hitrow = -1;
unsigned char row;
unsigned short cols[6]={1,2,3,4,5,14};
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -335,27 +512,80 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
keymatrix[i]=row;
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
unsigned char alt = keymatrix[0] & 0x02;
unsigned char del = keymatrix[5] & 0x20;
keymatrix[0] &= ~0x02;
keymatrix[5] &= ~0x20;
if (alt) keymatrix[5] |= 0x20;
if (del) keymatrix[0] |= 0x02;
unsigned char alt = keymatrixtmp[0] & 0x02;
unsigned char del = keymatrixtmp[5] & 0x20;
keymatrixtmp[0] &= ~0x02;
keymatrixtmp[5] &= ~0x20;
if (alt) keymatrixtmp[5] |= 0x20;
if (del) keymatrixtmp[0] |= 0x02;
#endif
bool alt_pressed=false;
if ( keymatrix[5] & 0x20 ) {alt_pressed=true; keymatrix[5] &= ~0x20;};
if ( keymatrixtmp[5] & 0x20 ) {alt_pressed=true; keymatrixtmp[5] &= ~0x20;};
for (int i=0;i<6;i++){
row = keymatrix[i];
row = keymatrixtmp[i];
if (row) keymatrix_hitrow=i;
keymatrix[i] = row;
}
//6,9,15,8,7,22
@ -400,6 +630,7 @@ int emu_ReadKeys(void)
if (hundred_ms_cnt >= 2)
{
hundred_ms_cnt = 0;
/*
if ( (time_ms-keypress_t_ms) < 500)
{
if (key_alt == false)
@ -411,13 +642,14 @@ int emu_ReadKeys(void)
key_alt = false;
}
}
*/
}
}
}
else {
// Keep press
if (hundred_ms_cnt == 1) {
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 1000)
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 2000)
{
if (key_alt == false)
{
@ -461,6 +693,12 @@ int emu_ReadKeys(void)
{
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (oskbOn) {
retval |= MASK_OSKB;
}
#endif
return (retval);
}
@ -487,8 +725,6 @@ int emu_ReadI2CKeyboard(void) {
}
if (keymatrix_hitrow >=0 ) {
unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow];
//if ( (match == 0x002 ) ) return 0; // shift or fn
//if (match < 0x100 ) match = match & ~0x002; // ignore shift key
for (int i=0; i<sizeof(matkeys)/sizeof(unsigned short); i++) {
if (match == matkeys[i]) {
hundred_ms_cnt = 0;
@ -496,6 +732,11 @@ int emu_ReadI2CKeyboard(void) {
}
}
}
#endif
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (!menuOn) {
retval = handleOskb();
}
#endif
return(retval);
}
@ -621,34 +862,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -657,18 +889,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}
@ -722,6 +954,14 @@ void backgroundMenu(void) {
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
}
static void menuLeft(void)
{
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
toggleOskb(true);
#endif
}
int handleMenu(uint16_t bClick)
{
int action = ACTION_NONE;
@ -741,12 +981,13 @@ int handleMenu(uint16_t bClick)
strcpy(romspath,newpath);
curFile = 0;
nbFiles = readNbFiles(newpath);
menuRedraw=true;
}
else
{
action = ACTION_RUNTFT;
menuLeft();
}
menuRedraw=true;
}
else if ( (bClick & MASK_KEY_USER1) ) {
menuRedraw=true;
@ -980,6 +1221,11 @@ int emu_LoadFile(char * filename, char * buf, int size)
********************************/
void emu_init(void)
{
// Dual display config, initialize TFT
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
tft.begin();
#endif
sd_init_driver();
FRESULT fr = f_mount(&fatfs, "0:", 1);

View file

@ -27,11 +27,13 @@
#ifdef KEYMAP_PRESENT
#ifdef PICOMPUTER
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" # * "
#define keylables_map1_2 (char *)" "
const unsigned short key_map1[] = {
2,3,4,5,6,7,8,9,10,1,0,
0,11,12,0,0,0,0,0,0,0,0,
0,0,0,11,0,0,0,0,12,0,0,
0, 0,0,0,0,0,0,0,0,0,
0,0,0,0
};
@ -44,6 +46,9 @@ const unsigned short key_map1[] = {
11,1,12};
*/
#define keylables_map2_0 (char *)" "
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" "
const unsigned short key_map2[] = {
0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,
@ -51,6 +56,9 @@ const unsigned short key_map2[] = {
0,0,0,0
};
#define keylables_map3_0 (char *)" "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
const unsigned short key_map3[] = {
0,0,0,0,0,0,0,0,0,0,0, // function keys
0, 0,0,0,0,0,0,0,0,0,0,
@ -65,7 +73,6 @@ const unsigned short matkeys[] = {
0x508,0x501,0x502,0x504 }; // cursor keys
#endif
#endif
#define MASK_JOY2_RIGHT 0x0001
@ -82,7 +89,7 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_DOWN 0x0800
#define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000
#define MASK_OSKB 0x8000
extern void emu_init(void);
extern void emu_start(void);

View file

@ -16,6 +16,7 @@ extern "C" {
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
volatile bool vbl=true;
bool repeating_timer_callback(struct repeating_timer *t) {
@ -26,7 +27,6 @@ bool repeating_timer_callback(struct repeating_timer *t) {
}
return true;
}
#endif
TFT_T_DMA tft;
static int skip=0;
@ -60,17 +60,15 @@ int main(void) {
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
#ifndef USE_VGA
struct repeating_timer timer;
add_repeating_timer_ms(25, repeating_timer_callback, NULL, &timer);
#endif
}
tft.waitSync();
}
else {
emu_Step();
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
emu_Step();
}
//int c = getchar_timeout_us(0);
//switch (c) {

View file

@ -13,11 +13,19 @@ extern "C" {
#include "iopins.h"
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// Dual display config, initialize TFT
#include "tft_t_dma.h"
static TFT_T_DMA tft;
#else
// Non Dual display config
#ifdef USE_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
extern TFT_T_DMA tft;
#endif
#define MAX_FILES 64
@ -39,7 +47,7 @@ extern "C" {
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft;
static char romspath[64];
static int nbFiles=0;
@ -142,8 +150,175 @@ void emu_Free(void * pt)
free(pt);
}
void emu_drawText(unsigned short x, unsigned short y, const char * text, unsigned short fgcolor, unsigned short bgcolor, int doublesize)
{
tft.drawText(x, y, text, fgcolor, bgcolor, doublesize?true:false);
}
/********************************
* OSKB handling
********************************/
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// On screen keyboard position
#define KXOFF 28 //64
#define KYOFF 96
#define KWIDTH 11 //22
#define KHEIGHT 3
static bool oskbOn = false;
static int cxpos = 0;
static int cypos = 0;
static int oskbMap = 0;
static uint16_t oskbBLastState = 0;
static void lineOSKB2(int kxoff, int kyoff, char * str, int row)
{
char c[2] = {'A',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[0] = *cpt++;
c[1] = 0;
uint16_t bg = RGBVAL16(0x00,0x00,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0xff,0x00,0x00);
tft.drawTextNoDma(kxoff+8*i,kyoff, &c[0], RGBVAL16(0x00,0xff,0xff), bg, ((i&1)?false:true));
}
}
static void lineOSKB(int kxoff, int kyoff, char * str, int row)
{
char c[4] = {' ',0,' ',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[1] = *cpt++;
uint16_t bg;
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+0 , " ", RGBVAL16(0x00,0x00,0x00), bg, false);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+8 , &c[0], RGBVAL16(0x00,0x00,0x00), bg, true);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+24, " ", RGBVAL16(0x00,0x00,0x00), bg, false);
}
}
static void drawOskb(void)
{
// lineOSKB2(KXOFF,KYOFF+0, (char *)"Q1W2E3R4T5Y6U7I8O9P0<=", 0);
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
void toggleOskb(bool forceoff) {
if (forceoff) oskbOn=true;
if (oskbOn) {
oskbOn = false;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, "Press USER2 to toggle onscreen keyboard.", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
} else {
oskbOn = true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, " Press USER2 to exit onscreen keyboard. ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
tft.drawTextNoDma(0,64, " (USER1 to toggle between keymaps) ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
tft.drawRectNoDma(KXOFF,KYOFF, 22*8, 3*16, RGBVAL16(0x00,0x00,0xFF));
drawOskb();
}
}
static int handleOskb(void)
{
int retval = 0;
uint16_t bClick = bLastState & ~oskbBLastState;
oskbBLastState = bLastState;
/*
static const char * digits = "0123456789ABCDEF";
char buf[5] = {0,0,0,0,0};
int val = bClick;
buf[0] = digits[(val>>12)&0xf];
buf[1] = digits[(val>>8)&0xf];
buf[2] = digits[(val>>4)&0xf];
buf[3] = digits[val&0xf];
tft.drawTextNoDma(0,KYOFF+ 64,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),1);
*/
if (bClick & MASK_KEY_USER2)
{
toggleOskb(false);
}
if (oskbOn)
{
bool updated = true;
if (bClick & MASK_KEY_USER1)
{
oskbMap += 1;
if (oskbMap == 3) oskbMap = 0;
}
else if (bClick & MASK_JOY2_LEFT)
{
cxpos++;
if (cxpos >= KWIDTH) cxpos = 0;
}
else if (bClick & MASK_JOY2_RIGHT)
{
cxpos--;
if (cxpos < 0) cxpos = KWIDTH-1;
}
else if (bClick & MASK_JOY2_DOWN)
{
cypos++;
if (cypos >= KHEIGHT) cypos = 0;
}
else if (bClick & MASK_JOY2_UP)
{
cypos--;
if (cypos < 0) cypos = KHEIGHT-1;
}
else if (oskbBLastState & MASK_JOY2_BTN)
{
retval = cypos*KWIDTH+cxpos+1;
if (retval) {
retval--;
//if (retval & 1) retval = key_map2[retval>>1];
//else retval = key_map1[retval>>1];
if (oskbMap == 0) {
retval = key_map1[retval];
}
else if (oskbMap == 1) {
retval = key_map2[retval];
}
else {
retval = key_map3[retval];
}
//if (retval) { toggleOskb(true); updated=false; };
}
}
else {
updated=false;
}
if (updated) drawOskb();
}
return retval;
}
#endif
/********************************
* Input and keyboard
********************************/
@ -318,8 +493,10 @@ int emu_ReadKeys(void)
keymatrix_hitrow = -1;
unsigned char row;
unsigned short cols[6]={1,2,3,4,5,14};
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -335,27 +512,80 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
keymatrix[i]=row;
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
unsigned char alt = keymatrix[0] & 0x02;
unsigned char del = keymatrix[5] & 0x20;
keymatrix[0] &= ~0x02;
keymatrix[5] &= ~0x20;
if (alt) keymatrix[5] |= 0x20;
if (del) keymatrix[0] |= 0x02;
unsigned char alt = keymatrixtmp[0] & 0x02;
unsigned char del = keymatrixtmp[5] & 0x20;
keymatrixtmp[0] &= ~0x02;
keymatrixtmp[5] &= ~0x20;
if (alt) keymatrixtmp[5] |= 0x20;
if (del) keymatrixtmp[0] |= 0x02;
#endif
bool alt_pressed=false;
if ( keymatrix[5] & 0x20 ) {alt_pressed=true; keymatrix[5] &= ~0x20;};
if ( keymatrixtmp[5] & 0x20 ) {alt_pressed=true; keymatrixtmp[5] &= ~0x20;};
for (int i=0;i<6;i++){
row = keymatrix[i];
row = keymatrixtmp[i];
if (row) keymatrix_hitrow=i;
keymatrix[i] = row;
}
//6,9,15,8,7,22
@ -400,6 +630,7 @@ int emu_ReadKeys(void)
if (hundred_ms_cnt >= 2)
{
hundred_ms_cnt = 0;
/*
if ( (time_ms-keypress_t_ms) < 500)
{
if (key_alt == false)
@ -411,13 +642,14 @@ int emu_ReadKeys(void)
key_alt = false;
}
}
*/
}
}
}
else {
// Keep press
if (hundred_ms_cnt == 1) {
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 1000)
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 2000)
{
if (key_alt == false)
{
@ -461,6 +693,12 @@ int emu_ReadKeys(void)
{
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (oskbOn) {
retval |= MASK_OSKB;
}
#endif
return (retval);
}
@ -487,8 +725,6 @@ int emu_ReadI2CKeyboard(void) {
}
if (keymatrix_hitrow >=0 ) {
unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow];
//if ( (match == 0x002 ) ) return 0; // shift or fn
//if (match < 0x100 ) match = match & ~0x002; // ignore shift key
for (int i=0; i<sizeof(matkeys)/sizeof(unsigned short); i++) {
if (match == matkeys[i]) {
hundred_ms_cnt = 0;
@ -496,6 +732,11 @@ int emu_ReadI2CKeyboard(void) {
}
}
}
#endif
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (!menuOn) {
retval = handleOskb();
}
#endif
return(retval);
}
@ -621,34 +862,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -657,18 +889,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}
@ -722,6 +954,14 @@ void backgroundMenu(void) {
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
}
static void menuLeft(void)
{
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
toggleOskb(true);
#endif
}
int handleMenu(uint16_t bClick)
{
int action = ACTION_NONE;
@ -741,12 +981,13 @@ int handleMenu(uint16_t bClick)
strcpy(romspath,newpath);
curFile = 0;
nbFiles = readNbFiles(newpath);
menuRedraw=true;
}
else
{
action = ACTION_RUNTFT;
menuLeft();
}
menuRedraw=true;
}
else if ( (bClick & MASK_KEY_USER1) ) {
menuRedraw=true;
@ -980,6 +1221,11 @@ int emu_LoadFile(char * filename, char * buf, int size)
********************************/
void emu_init(void)
{
// Dual display config, initialize TFT
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
tft.begin();
#endif
sd_init_driver();
FRESULT fr = f_mount(&fatfs, "0:", 1);

View file

@ -29,15 +29,20 @@
#ifdef KEYMAP_PRESENT
#ifdef PICOMPUTER
#define keylables_map1_0 (char *)"12 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
const unsigned short key_map1[] = {
0,2,3,0,0,0,0,0,0,0, 0,
2,3,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,0,0,0,0, // not usable except last ones
0,0,0,0
};
#define keylables_map2_0 (char *)" "
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" "
const unsigned short key_map2[] = {
0,0,0,0,0,0,0,0,0,0, 0,
0, 0,0,0,0,0,0,0,0,0,0,
@ -46,6 +51,9 @@ const unsigned short key_map2[] = {
};
#define keylables_map3_0 (char *)" "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
const unsigned short key_map3[] = {
0,0,0,0,0,0,0,0,0,0,0, // function keys
0, 0,0,0,0,0,0,0,0,0,0,
@ -60,7 +68,6 @@ const unsigned short matkeys[] = {
0x508,0x501,0x502,0x504 }; // cursor keys
#endif
#endif
@ -78,7 +85,7 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_DOWN 0x0800
#define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000
#define MASK_OSKB 0x8000
extern void emu_init(void);

View file

@ -41,11 +41,6 @@ static char * lorom=0; //[MAX_ROM_SIZE];
/****************************************************************************
* Exported procedures
****************************************************************************/
void emu_KeyboardOnDown(int keymodifer, int key) {
}
void emu_KeyboardOnUp(int keymodifer, int key) {
}
void odd_Init(void)
{
@ -202,7 +197,6 @@ void odd_Step(void)
{
run();
//emu_printf("s");
emu_DrawScreen((unsigned char *)getGBuf()+BORDERW/2, BMPW-BORDERW, BMPH, BMPW);
emu_DrawVsync();
}

View file

@ -2,7 +2,7 @@ extern void odd_Init(void);
extern void odd_Start(char * filename);
extern void odd_Stop(void);
extern void odd_Step(void);
extern void odd_Input(int key);

View file

@ -13,11 +13,19 @@ extern "C" {
#include "iopins.h"
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// Dual display config, initialize TFT
#include "tft_t_dma.h"
static TFT_T_DMA tft;
#else
// Non Dual display config
#ifdef USE_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
extern TFT_T_DMA tft;
#endif
#define MAX_FILES 64
@ -39,7 +47,7 @@ extern "C" {
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft;
static char romspath[64];
static int nbFiles=0;
@ -142,8 +150,176 @@ void emu_Free(void * pt)
free(pt);
}
void emu_drawText(unsigned short x, unsigned short y, const char * text, unsigned short fgcolor, unsigned short bgcolor, int doublesize)
{
tft.drawText(x, y, text, fgcolor, bgcolor, doublesize?true:false);
}
/********************************
* OSKB handling
********************************/
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// On screen keyboard position
#define KXOFF 28 //64
#define KYOFF 96
#define KWIDTH 11 //22
#define KHEIGHT 3
static bool oskbOn = false;
static int cxpos = 0;
static int cypos = 0;
static int oskbMap = 0;
static uint16_t oskbBLastState = 0;
static void lineOSKB2(int kxoff, int kyoff, char * str, int row)
{
char c[2] = {'A',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[0] = *cpt++;
c[1] = 0;
uint16_t bg = RGBVAL16(0x00,0x00,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0xff,0x00,0x00);
tft.drawTextNoDma(kxoff+8*i,kyoff, &c[0], RGBVAL16(0x00,0xff,0xff), bg, ((i&1)?false:true));
}
}
static void lineOSKB(int kxoff, int kyoff, char * str, int row)
{
char c[4] = {' ',0,' ',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[1] = *cpt++;
uint16_t bg;
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+0 , " ", RGBVAL16(0x00,0x00,0x00), bg, false);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+8 , &c[0], RGBVAL16(0x00,0x00,0x00), bg, true);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+24, " ", RGBVAL16(0x00,0x00,0x00), bg, false);
}
}
static void drawOskb(void)
{
// lineOSKB2(KXOFF,KYOFF+0, (char *)"Q1W2E3R4T5Y6U7I8O9P0<=", 0);
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
void toggleOskb(bool forceoff) {
if (forceoff) oskbOn=true;
if (oskbOn) {
oskbOn = false;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, "Press USER2 to toggle onscreen keyboard.", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
} else {
oskbOn = true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, " Press USER2 to exit onscreen keyboard. ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
tft.drawTextNoDma(0,64, " (USER1 to toggle between keymaps) ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
tft.drawRectNoDma(KXOFF,KYOFF, 22*8, 3*16, RGBVAL16(0x00,0x00,0xFF));
drawOskb();
}
}
static int handleOskb(void)
{
int retval = 0;
uint16_t bClick = bLastState & ~oskbBLastState;
oskbBLastState = bLastState;
if (bClick & MASK_KEY_USER2)
{
toggleOskb(false);
}
if (oskbOn)
{
bool updated = true;
if (bClick & MASK_KEY_USER1)
{
oskbMap += 1;
if (oskbMap == 3) oskbMap = 0;
}
else if (bClick & MASK_JOY2_LEFT)
{
cxpos++;
if (cxpos >= KWIDTH) cxpos = 0;
}
else if (bClick & MASK_JOY2_RIGHT)
{
cxpos--;
if (cxpos < 0) cxpos = KWIDTH-1;
}
else if (bClick & MASK_JOY2_DOWN)
{
cypos++;
if (cypos >= KHEIGHT) cypos = 0;
}
else if (bClick & MASK_JOY2_UP)
{
cypos--;
if (cypos < 0) cypos = KHEIGHT-1;
}
else if (oskbBLastState & MASK_JOY2_BTN)
{
retval = cypos*KWIDTH+cxpos+1;
if (retval) {
retval--;
//if (retval & 1) retval = key_map2[retval>>1];
//else retval = key_map1[retval>>1];
if (oskbMap == 0) {
retval = key_map1[retval];
}
else if (oskbMap == 1) {
retval = key_map2[retval];
}
else {
retval = key_map3[retval];
}
if (retval) { toggleOskb(true); updated=false; };
}
}
else {
updated=false;
}
if (updated) drawOskb();
}
/*
static const char * digits = "0123456789ABCDEF";
char buf[5] = {0,0,0,0,0};
int val = retval;
buf[0] = digits[(val>>12)&0xf];
buf[1] = digits[(val>>8)&0xf];
buf[2] = digits[(val>>4)&0xf];
buf[3] = digits[val&0xf];
tft.drawTextNoDma(0,0,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),1);
*/
return retval;
}
#endif
/********************************
* Input and keyboard
********************************/
@ -318,8 +494,10 @@ int emu_ReadKeys(void)
keymatrix_hitrow = -1;
unsigned char row;
unsigned short cols[6]={1,2,3,4,5,14};
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -335,27 +513,80 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
keymatrix[i]=row;
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
unsigned char alt = keymatrix[0] & 0x02;
unsigned char del = keymatrix[5] & 0x20;
keymatrix[0] &= ~0x02;
keymatrix[5] &= ~0x20;
if (alt) keymatrix[5] |= 0x20;
if (del) keymatrix[0] |= 0x02;
unsigned char alt = keymatrixtmp[0] & 0x02;
unsigned char del = keymatrixtmp[5] & 0x20;
keymatrixtmp[0] &= ~0x02;
keymatrixtmp[5] &= ~0x20;
if (alt) keymatrixtmp[5] |= 0x20;
if (del) keymatrixtmp[0] |= 0x02;
#endif
bool alt_pressed=false;
if ( keymatrix[5] & 0x20 ) {alt_pressed=true; keymatrix[5] &= ~0x20;};
if ( keymatrixtmp[5] & 0x20 ) {alt_pressed=true; keymatrixtmp[5] &= ~0x20;};
for (int i=0;i<6;i++){
row = keymatrix[i];
row = keymatrixtmp[i];
if (row) keymatrix_hitrow=i;
keymatrix[i] = row;
}
//6,9,15,8,7,22
@ -400,6 +631,7 @@ int emu_ReadKeys(void)
if (hundred_ms_cnt >= 2)
{
hundred_ms_cnt = 0;
/*
if ( (time_ms-keypress_t_ms) < 500)
{
if (key_alt == false)
@ -411,13 +643,14 @@ int emu_ReadKeys(void)
key_alt = false;
}
}
*/
}
}
}
else {
// Keep press
if (hundred_ms_cnt == 1) {
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 1000)
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 2000)
{
if (key_alt == false)
{
@ -461,6 +694,12 @@ int emu_ReadKeys(void)
{
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (oskbOn) {
retval |= MASK_OSKB;
}
#endif
return (retval);
}
@ -487,8 +726,6 @@ int emu_ReadI2CKeyboard(void) {
}
if (keymatrix_hitrow >=0 ) {
unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow];
//if ( (match == 0x002 ) ) return 0; // shift or fn
//if (match < 0x100 ) match = match & ~0x002; // ignore shift key
for (int i=0; i<sizeof(matkeys)/sizeof(unsigned short); i++) {
if (match == matkeys[i]) {
hundred_ms_cnt = 0;
@ -496,6 +733,11 @@ int emu_ReadI2CKeyboard(void) {
}
}
}
#endif
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (!menuOn) {
retval = handleOskb();
}
#endif
return(retval);
}
@ -621,34 +863,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -657,18 +890,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}
@ -722,6 +955,14 @@ void backgroundMenu(void) {
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
}
static void menuLeft(void)
{
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
toggleOskb(true);
#endif
}
int handleMenu(uint16_t bClick)
{
int action = ACTION_NONE;
@ -741,12 +982,13 @@ int handleMenu(uint16_t bClick)
strcpy(romspath,newpath);
curFile = 0;
nbFiles = readNbFiles(newpath);
menuRedraw=true;
}
else
{
action = ACTION_RUNTFT;
menuLeft();
}
menuRedraw=true;
}
else if ( (bClick & MASK_KEY_USER1) ) {
menuRedraw=true;
@ -980,6 +1222,11 @@ int emu_LoadFile(char * filename, char * buf, int size)
********************************/
void emu_init(void)
{
// Dual display config, initialize TFT
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
tft.begin();
#endif
sd_init_driver();
FRESULT fr = f_mount(&fatfs, "0:", 1);

View file

@ -13,7 +13,7 @@
#define emu_Init(ROM) {odd_Init();odd_Start(ROM);}
#define emu_Step() {odd_Step();}
#define emu_Input(x) {}
#define emu_Input(x) {odd_Input(x);}
#define VID_FRAME_SKIP 0x0
#define PALETTE_SIZE 256
@ -26,8 +26,10 @@
#define ACTION_RUNVGA 130
#ifdef KEYMAP_PRESENT
#ifdef PICOMPUTER
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
const unsigned short key_map1[] = {
1,2,3,4,5,6,7,8,9,10,0,
0,0,0,0,0,0,0,0,0,0,0,
@ -56,6 +58,9 @@ const unsigned short key_map1[] = {
31,32,33,34,35,36,37,36,39,40,
*/
#define keylables_map2_0 (char *)" "
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" "
const unsigned short key_map2[] = {
0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,
@ -63,6 +68,9 @@ const unsigned short key_map2[] = {
0,0,0,0
};
#define keylables_map3_0 (char *)" "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
const unsigned short key_map3[] = {
0,0,0,0,0,0,0,0,0,0,0, // function keys
0, 0,0,0,0,0,0,0,0,0,0,
@ -77,7 +85,6 @@ const unsigned short matkeys[] = {
0x508,0x501,0x502,0x504 }; // cursor keys
#endif
#endif
#define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002
@ -93,7 +100,7 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_DOWN 0x0800
#define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000
#define MASK_OSKB 0x8000
extern void emu_init(void);

View file

@ -16,6 +16,7 @@ extern "C" {
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
volatile bool vbl=true;
bool repeating_timer_callback(struct repeating_timer *t) {
@ -26,7 +27,6 @@ bool repeating_timer_callback(struct repeating_timer *t) {
}
return true;
}
#endif
TFT_T_DMA tft;
static int skip=0;
@ -61,17 +61,15 @@ int main(void) {
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
#ifndef USE_VGA
struct repeating_timer timer;
add_repeating_timer_ms(15, repeating_timer_callback, NULL, &timer);
#endif
}
tft.waitSync();
}
else {
emu_Step();
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
emu_Step();
}
//int c = getchar_timeout_us(0);
//switch (c) {

View file

@ -129,6 +129,21 @@ static unsigned int key_map[6][8]= {
};
static int k = 0;
static int hk = 0;
void odd_Input(int key) {
k = emu_GetPad();
hk = emu_ReadI2CKeyboard() & 0x7f;
}
void emu_KeyboardOnDown(int keymodifer, int key) {
}
void emu_KeyboardOnUp(int keymodifer, int key) {
}
static void do_kluges(void);
static void setvideomode(int t);
@ -260,15 +275,14 @@ void write_p1(Byte d){
Byte read_P2(void){
int i,si,so,km;
int k;
int hksim = 0;
k=emu_GetPad()&0x7f;
int hk = emu_ReadI2CKeyboard()&0x7f;
int key = emu_ReadKeys();
if (key & MASK_KEY_USER1) { // 1
k = 1;
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
#else
if (k & MASK_KEY_USER1) { // 1
hksim = 1;
}
#endif
if (!(p1 & 0x04)) {
si = (p2 & 7);
@ -276,13 +290,17 @@ Byte read_P2(void){
if (si<6) {
for (i=0; i<8; i++) {
km = key_map[si][i];
if ( (km == (k-1)) && (k) )
{
so = i ^ 0x07;
if (hk) {
if ( km == (hk-1) )
{
so = i ^ 0x07;
}
}
else if ( (km == (hk-1)) && (hk) )
{
so = i ^ 0x07;
else if (hksim) {
if ( km == (hksim-1) )
{
so = i ^ 0x07;
}
}
// if ((key[km] && ((!joykeystab[km]) || (key_shifts & KB_CAPSLOCK_FLAG))) || (key2[km])) {
// so = i ^ 0x07;
@ -374,8 +392,6 @@ Byte ext_read(ADDRESS adr){
Byte in_bus(void){
Byte si=0,d=0,mode=0,jn=0;
int key;
if ((p1 & 0x08) && (p1 & 0x10)) {
/* Handle joystick read */
@ -383,13 +399,17 @@ Byte in_bus(void){
si = (p2 & 7);
}
d=0xFF;
/* Get current input */
key = emu_ReadKeys();
int key = 0;
if ( !(k & MASK_OSKB) ) {
key = k;
}
app_data.stick[0]=0;
app_data.stick[1]=1;
/*
if ( emu_GetPad() & 0x80 )
if ( key & 0x80 )
{
app_data.stick[0]=1;
app_data.stick[1]=0;
@ -410,8 +430,9 @@ Byte in_bus(void){
}
*/
mode=1;
if (key & 0x8000) jn=1;
else jn=0;
//if (key & 0x8000) jn=1;
//else jn=0;
switch(mode) {
case 1:
@ -424,7 +445,6 @@ Byte in_bus(void){
case 2:
/* Get current input */
// key = emu_GetPad();
// if (key & JKEY_PLEFT) d &= 0xF7;
// if (key & JKEY_PRIGHT) d &= 0xFD;
// if (key & JKEY_PUP) d &= 0xFE;

View file

@ -210,19 +210,19 @@ static void drawOskb(void)
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, (char *)"qwertyuiop\x1a", 0);
lineOSKB(KXOFF,KYOFF, (char *)" asdfghjkl\x19", 1);
lineOSKB(KXOFF,KYOFF, (char *)" zxcvbnm.\x10 ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, (char *)"1234567890=", 0);
lineOSKB(KXOFF,KYOFF, (char *)" !@#$%+&*- ", 1);
lineOSKB(KXOFF,KYOFF, (char *)" ()?/\"<>,: ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, (char *)"QWERTYUIOP ", 0);
lineOSKB(KXOFF,KYOFF, (char *)" ASDFGHJKL ", 1);
lineOSKB(KXOFF,KYOFF, (char *)" ZXCVBNM; ", 2);
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
@ -306,6 +306,7 @@ static int handleOskb(void)
else {
retval = key_map3[retval];
}
//if (retval) { toggleOskb(true); updated=false; };
}
}
else {
@ -495,7 +496,12 @@ int emu_ReadKeys(void)
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
row=0;
row |= (gpio_get(9) ? 0 : 0x01);
row |= (gpio_get(9) ? 0 : 0x01);
@ -506,12 +512,16 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -527,13 +537,15 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -549,11 +561,13 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
@ -848,34 +862,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -884,18 +889,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}

View file

@ -40,6 +40,9 @@
{ 5,17,16,225,44},// bnm <symbshift=RSHift> <space>
*/
#define keylables_map1_0 (char *)"qwertyuiop\x1a"
#define keylables_map1_1 (char *)" asdfghjkl\x19"
#define keylables_map1_2 (char *)" zxcvbnm.\x10 "
const unsigned short key_map1[] = {
20,26,8,21,23,28,24,12,18,19,39+128,
0, 4, 22, 7,9, 10,11,13,14,15,40,
@ -47,6 +50,9 @@ const unsigned short key_map1[] = {
0,0,0,0 //up,left,right,down
};
#define keylables_map2_0 (char *)"1234567890="
#define keylables_map2_1 (char *)" !@#$%+&*- "
#define keylables_map2_2 (char *)" ()?/\"<>,: "
const unsigned short key_map2[] = {
30,31,32,33,34,35,36,37,38,39,15+64,
0,30+64,31+64,32+64,33+64,34+64,14+64,35+64,5+64,13+64,0,
@ -54,6 +60,9 @@ const unsigned short key_map2[] = {
36+128,34+128,37+128,35+128 //up,left,right,down
};
#define keylables_map3_0 (char *)"QWERTYUIOP "
#define keylables_map3_1 (char *)" ASDFGHJKL "
#define keylables_map3_2 (char *)" ZXCVBNM; "
const unsigned short key_map3[] = {
20+128,26+128,8+128,21+128,23+128,28+128,24+128,12+128,18+128,19+128,0, // Upper case
0, 4+128, 22+128, 7+128,9+128, 10+128,11+128,13+128,14+128,15+128,0,

View file

@ -41,8 +41,21 @@ extern int nOptions_P1Diff;
extern int nOptions_P2Diff;
void emu_KeyboardOnDown(int keymodifer, int key) {
}
void emu_KeyboardOnUp(int keymodifer, int key) {
}
static int k = 0;
static int hk = 0;
void vcs_Input(int key) {
k = emu_GetPad();
hk = emu_ReadI2CKeyboard() & 0xF;
}
void keyjoy(void) {
int key;
BYTE v1,v2;
v1=v2=0x0f;
@ -50,8 +63,10 @@ void keyjoy(void) {
// 256 byte buffer which holds the state of all the keyboard keys. If a
// byte's upper bit is set to 1, the key is pressed.
key = emu_ReadKeys();
int key = 0;
if ( !(k & MASK_OSKB) ) {
key = k;
}
if (key & MASK_JOY2_UP) v1 &= 0x0E;
if (key & MASK_JOY2_DOWN) v1 &= 0x0D;
if (key & MASK_JOY2_RIGHT) v1 &= 0x0B;
@ -60,40 +75,41 @@ void keyjoy(void) {
riotRead[0x280]=(v1 << 4) | v2;
}
static int kswitches = 0;
void keycons(void) {
//---------------------------------------------------------
// This function reads the state of the joysticks (buttons)
//---------------------------------------------------------
int key = emu_ReadKeys();;
int sw = emu_GetPad() & 0xff;
int hk = emu_ReadI2CKeyboard();
int key = 0;
if ( !(k & MASK_OSKB) ) {
key = k;
}
kswitches = 0;
if (hk == 1) {
if (kswitches & 0x01)
kswitches &= ~0x01;
else
kswitches |= 0x01;
}
else if (hk == 2) {
if (kswitches & 0x02)
kswitches &= ~0x02;
else
kswitches |= 0x02;
}
else if (hk == 3) {
if (kswitches & 0x04)
kswitches &= ~0x04;
else
kswitches |= 0x04;
}
else if (hk == 4) {
if (kswitches & 0x08)
kswitches &= ~0x08;
else
kswitches |= 0x08;
int kswitches = 0;
if (hk) {
if (hk == 1) {
if (kswitches & 0x01)
kswitches &= ~0x01;
else
kswitches |= 0x01;
}
else if (hk == 2) {
if (kswitches & 0x02)
kswitches &= ~0x02;
else
kswitches |= 0x02;
}
else if (hk == 3) {
if (kswitches & 0x04)
kswitches &= ~0x04;
else
kswitches |= 0x04;
}
else if (hk == 4) {
if (kswitches & 0x08)
kswitches &= ~0x08;
else
kswitches |= 0x08;
}
}
@ -103,7 +119,7 @@ void keycons(void) {
riotRead[SWCHB] |= 0x03;
if ( (key & MASK_KEY_USER3) /*|| (sw == 2)*/ || (kswitches & 0x04) ) //
if ( (key & MASK_KEY_USER3) || (kswitches & 0x04) )
nOptions_Color = !nOptions_Color;
if (!nOptions_Color)
@ -112,9 +128,19 @@ void keycons(void) {
riotRead[SWCHB] |= 0x08; /* Color */
if ( (key & MASK_KEY_USER1) /*|| (sw == 4)*/ || (kswitches & 0x02) )
if ( (kswitches & 0x02)
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
#else
|| (key & MASK_KEY_USER1)
#endif
)
riotRead[SWCHB] &= 0xFE; /* Reset */
if ( (key & MASK_KEY_USER2) /*|| (sw == 3)*/ || (kswitches & 0x01) )
if ( (kswitches & 0x01)
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
#else
|| (key & MASK_KEY_USER2)
#endif
)
riotRead[SWCHB] &= 0xFD; /* Select */
if (nOptions_P1Diff) riotRead[SWCHB] &= 0xBF; /* P0 amateur */
@ -125,17 +151,17 @@ void keycons(void) {
}
void keytrig(void) {
int key;
// read the keyboard state. The return value (in keys) is a pointer to a
// 256 byte buffer which holds the state of all the keyboard keys. If a
// byte's upper bit is set to 1, the key is pressed.
key = emu_ReadKeys();
int key = 0;
if ( !(k & MASK_OSKB) ) {
key = k;
}
if (!(tiaWrite[VBLANK] & 0x40)) {
tiaRead[INPT5]=0x80;
if (key & 0x10)
if (key & MASK_JOY2_BTN)
tiaRead[INPT4]=0x00;
else
tiaRead[INPT4]=0x80;

View file

@ -25,12 +25,6 @@ extern void mainloop(void);
/****************************************************************************
* Exported procedures
****************************************************************************/
void emu_KeyboardOnDown(int keymodifer, int key) {
}
void emu_KeyboardOnUp(int keymodifer, int key) {
}
void vcs_Init(void)
{
init_machine();

View file

@ -2,7 +2,7 @@ extern void vcs_Init(void);
extern void vcs_Start(char * filename);
extern void vcs_Stop(void);
extern void vcs_Step(void);
extern void vcs_Input(int key);

View file

@ -13,11 +13,19 @@ extern "C" {
#include "iopins.h"
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// Dual display config, initialize TFT
#include "tft_t_dma.h"
static TFT_T_DMA tft;
#else
// Non Dual display config
#ifdef USE_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
extern TFT_T_DMA tft;
#endif
#define MAX_FILES 64
@ -39,7 +47,7 @@ extern "C" {
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft;
static char romspath[64];
static int nbFiles=0;
@ -142,8 +150,176 @@ void emu_Free(void * pt)
free(pt);
}
void emu_drawText(unsigned short x, unsigned short y, const char * text, unsigned short fgcolor, unsigned short bgcolor, int doublesize)
{
tft.drawText(x, y, text, fgcolor, bgcolor, doublesize?true:false);
}
/********************************
* OSKB handling
********************************/
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// On screen keyboard position
#define KXOFF 28 //64
#define KYOFF 96
#define KWIDTH 11 //22
#define KHEIGHT 3
static bool oskbOn = false;
static int cxpos = 0;
static int cypos = 0;
static int oskbMap = 0;
static uint16_t oskbBLastState = 0;
static void lineOSKB2(int kxoff, int kyoff, char * str, int row)
{
char c[2] = {'A',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[0] = *cpt++;
c[1] = 0;
uint16_t bg = RGBVAL16(0x00,0x00,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0xff,0x00,0x00);
tft.drawTextNoDma(kxoff+8*i,kyoff, &c[0], RGBVAL16(0x00,0xff,0xff), bg, ((i&1)?false:true));
}
}
static void lineOSKB(int kxoff, int kyoff, char * str, int row)
{
char c[4] = {' ',0,' ',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[1] = *cpt++;
uint16_t bg;
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+0 , " ", RGBVAL16(0x00,0x00,0x00), bg, false);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+8 , &c[0], RGBVAL16(0x00,0x00,0x00), bg, true);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+24, " ", RGBVAL16(0x00,0x00,0x00), bg, false);
}
}
static void drawOskb(void)
{
// lineOSKB2(KXOFF,KYOFF+0, (char *)"Q1W2E3R4T5Y6U7I8O9P0<=", 0);
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
void toggleOskb(bool forceoff) {
if (forceoff) oskbOn=true;
if (oskbOn) {
oskbOn = false;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, "Press USER2 to toggle onscreen keyboard.", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
} else {
oskbOn = true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, " Press USER2 to exit onscreen keyboard. ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
tft.drawTextNoDma(0,64, " (USER1 to toggle between keymaps) ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
tft.drawRectNoDma(KXOFF,KYOFF, 22*8, 3*16, RGBVAL16(0x00,0x00,0xFF));
drawOskb();
}
}
static int handleOskb(void)
{
int retval = 0;
uint16_t bClick = bLastState & ~oskbBLastState;
oskbBLastState = bLastState;
if (bClick & MASK_KEY_USER2)
{
toggleOskb(false);
}
if (oskbOn)
{
bool updated = true;
if (bClick & MASK_KEY_USER1)
{
oskbMap += 1;
if (oskbMap == 3) oskbMap = 0;
}
else if (bClick & MASK_JOY2_LEFT)
{
cxpos++;
if (cxpos >= KWIDTH) cxpos = 0;
}
else if (bClick & MASK_JOY2_RIGHT)
{
cxpos--;
if (cxpos < 0) cxpos = KWIDTH-1;
}
else if (bClick & MASK_JOY2_DOWN)
{
cypos++;
if (cypos >= KHEIGHT) cypos = 0;
}
else if (bClick & MASK_JOY2_UP)
{
cypos--;
if (cypos < 0) cypos = KHEIGHT-1;
}
else if (oskbBLastState & MASK_JOY2_BTN)
{
retval = cypos*KWIDTH+cxpos+1;
if (retval) {
retval--;
//if (retval & 1) retval = key_map2[retval>>1];
//else retval = key_map1[retval>>1];
if (oskbMap == 0) {
retval = key_map1[retval];
}
else if (oskbMap == 1) {
retval = key_map2[retval];
}
else {
retval = key_map3[retval];
}
//if (retval=2) { toggleOskb(true); updated=false; };
}
}
else {
updated=false;
}
if (updated) drawOskb();
}
/*
static const char * digits = "0123456789ABCDEF";
char buf[5] = {0,0,0,0,0};
int val = retval;
buf[0] = digits[(val>>12)&0xf];
buf[1] = digits[(val>>8)&0xf];
buf[2] = digits[(val>>4)&0xf];
buf[3] = digits[val&0xf];
tft.drawTextNoDma(0,0,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),1);
*/
return retval;
}
#endif
/********************************
* Input and keyboard
********************************/
@ -318,8 +494,10 @@ int emu_ReadKeys(void)
keymatrix_hitrow = -1;
unsigned char row;
unsigned short cols[6]={1,2,3,4,5,14};
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -335,27 +513,80 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
keymatrix[i]=row;
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
unsigned char alt = keymatrix[0] & 0x02;
unsigned char del = keymatrix[5] & 0x20;
keymatrix[0] &= ~0x02;
keymatrix[5] &= ~0x20;
if (alt) keymatrix[5] |= 0x20;
if (del) keymatrix[0] |= 0x02;
unsigned char alt = keymatrixtmp[0] & 0x02;
unsigned char del = keymatrixtmp[5] & 0x20;
keymatrixtmp[0] &= ~0x02;
keymatrixtmp[5] &= ~0x20;
if (alt) keymatrixtmp[5] |= 0x20;
if (del) keymatrixtmp[0] |= 0x02;
#endif
bool alt_pressed=false;
if ( keymatrix[5] & 0x20 ) {alt_pressed=true; keymatrix[5] &= ~0x20;};
if ( keymatrixtmp[5] & 0x20 ) {alt_pressed=true; keymatrixtmp[5] &= ~0x20;};
for (int i=0;i<6;i++){
row = keymatrix[i];
row = keymatrixtmp[i];
if (row) keymatrix_hitrow=i;
keymatrix[i] = row;
}
//6,9,15,8,7,22
@ -400,6 +631,7 @@ int emu_ReadKeys(void)
if (hundred_ms_cnt >= 2)
{
hundred_ms_cnt = 0;
/*
if ( (time_ms-keypress_t_ms) < 500)
{
if (key_alt == false)
@ -411,13 +643,14 @@ int emu_ReadKeys(void)
key_alt = false;
}
}
*/
}
}
}
else {
// Keep press
if (hundred_ms_cnt == 1) {
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 1000)
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 2000)
{
if (key_alt == false)
{
@ -461,6 +694,12 @@ int emu_ReadKeys(void)
{
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (oskbOn) {
retval |= MASK_OSKB;
}
#endif
return (retval);
}
@ -487,8 +726,6 @@ int emu_ReadI2CKeyboard(void) {
}
if (keymatrix_hitrow >=0 ) {
unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow];
//if ( (match == 0x002 ) ) return 0; // shift or fn
//if (match < 0x100 ) match = match & ~0x002; // ignore shift key
for (int i=0; i<sizeof(matkeys)/sizeof(unsigned short); i++) {
if (match == matkeys[i]) {
hundred_ms_cnt = 0;
@ -496,6 +733,11 @@ int emu_ReadI2CKeyboard(void) {
}
}
}
#endif
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (!menuOn) {
retval = handleOskb();
}
#endif
return(retval);
}
@ -621,34 +863,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -657,18 +890,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}
@ -722,6 +955,14 @@ void backgroundMenu(void) {
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
}
static void menuLeft(void)
{
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
toggleOskb(true);
#endif
}
int handleMenu(uint16_t bClick)
{
int action = ACTION_NONE;
@ -741,12 +982,13 @@ int handleMenu(uint16_t bClick)
strcpy(romspath,newpath);
curFile = 0;
nbFiles = readNbFiles(newpath);
menuRedraw=true;
}
else
{
action = ACTION_RUNTFT;
menuLeft();
}
menuRedraw=true;
}
else if ( (bClick & MASK_KEY_USER1) ) {
menuRedraw=true;
@ -980,6 +1222,11 @@ int emu_LoadFile(char * filename, char * buf, int size)
********************************/
void emu_init(void)
{
// Dual display config, initialize TFT
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
tft.begin();
#endif
sd_init_driver();
FRESULT fr = f_mount(&fatfs, "0:", 1);

View file

@ -12,7 +12,7 @@
#define emu_Init(ROM) {vcs_Init();vcs_Start(ROM);}
#define emu_Step() {vcs_Step();}
#define emu_Input(x) {}
#define emu_Input(x) {vcs_Input(x);}
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
@ -26,15 +26,20 @@
#define ACTION_RUNVGA 130
#ifdef KEYMAP_PRESENT
#ifdef PICOMPUTER
#define keylables_map1_0 (char *)"1234 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
const unsigned short key_map1[] = {
0,1,2,3,4,0,0,0,0,0,0,
1,2,3,4,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,0,0,
0,0,0,0
};
#define keylables_map2_0 (char *)" "
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" "
const unsigned short key_map2[] = {
0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,
@ -42,6 +47,9 @@ const unsigned short key_map2[] = {
0,0,0,0
};
#define keylables_map3_0 (char *)" "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
const unsigned short key_map3[] = {
0,0,0,0,0,0,0,0,0,0,0, // function keys
0, 0,0,0,0,0,0,0,0,0,0,
@ -56,7 +64,6 @@ const unsigned short matkeys[] = {
0x508,0x501,0x502,0x504 }; // cursor keys
#endif
#endif
#define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002
@ -72,7 +79,7 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_DOWN 0x0800
#define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000
#define MASK_OSKB 0x8000
extern void emu_init(void);
extern void emu_start(void);

View file

@ -16,6 +16,7 @@ extern "C" {
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
volatile bool vbl=true;
bool repeating_timer_callback(struct repeating_timer *t) {
@ -26,7 +27,6 @@ bool repeating_timer_callback(struct repeating_timer *t) {
}
return true;
}
#endif
TFT_T_DMA tft;
static int skip=0;
@ -61,17 +61,15 @@ int main(void) {
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
#ifndef USE_VGA
struct repeating_timer timer;
add_repeating_timer_ms(15, repeating_timer_callback, NULL, &timer);
#endif
}
tft.waitSync();
}
else {
emu_Step();
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
emu_Step();
}
//int c = getchar_timeout_us(0);
//switch (c) {

View file

@ -13,8 +13,50 @@ extern "C" {
#include "iopins.h"
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// Dual display config, initialize TFT
#include "tft_t_dma.h"
static TFT_T_DMA tft;
#else
// Non Dual display config
#ifdef USE_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
extern TFT_T_DMA tft;
#endif
#define MAX_FILES 64
#define MAX_FILENAME_SIZE 24
#define MAX_MENULINES 9
#define TEXT_HEIGHT 16
#define TEXT_WIDTH 8
#define MENU_FILE_XOFFSET (6*TEXT_WIDTH)
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
#define MENU_TFT_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_TFT_YOFFSET (MENU_VBAR_YOFFSET+32)
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
static char romspath[64];
static int nbFiles=0;
static int curFile=0;
static int topFile=0;
static char selection[MAX_FILENAME_SIZE+1]="";
static char files[MAX_FILES][MAX_FILENAME_SIZE];
static bool menuRedraw=true;
#ifdef PICOMPUTER
static const unsigned short * keys;
static unsigned char keymatrix[6];
@ -34,7 +76,13 @@ static int xRef;
static int yRef;
static uint8_t usbnavpad=0;
static bool menuOn=true;
/********************************
* Generic output and malloc
********************************/
void emu_printf(char * text)
{
printf("%s\n",text);
@ -55,11 +103,220 @@ void emu_printh(int val)
printf("0x%.8\n",val);
}
static int malbufpt = 0;
static char malbuf[EXTRA_HEAP];
void * emu_Malloc(int size)
{
void * retval = malloc(size);
if (!retval) {
emu_printf("failled to allocate");
emu_printf(size);
emu_printf("fallback");
if ( (malbufpt+size) < sizeof(malbuf) ) {
retval = (void *)&malbuf[malbufpt];
malbufpt += size;
}
else {
emu_printf("failure to allocate");
}
}
else {
emu_printf("could allocate dynamic ");
emu_printf(size);
}
return retval;
}
void * emu_MallocI(int size)
{
void * retval = NULL;
if ( (malbufpt+size) < sizeof(malbuf) ) {
retval = (void *)&malbuf[malbufpt];
malbufpt += size;
emu_printf("could allocate static ");
emu_printf(size);
}
else {
emu_printf("failure to allocate");
}
return retval;
}
void emu_Free(void * pt)
{
free(pt);
}
void emu_drawText(unsigned short x, unsigned short y, const char * text, unsigned short fgcolor, unsigned short bgcolor, int doublesize)
{
tft.drawText(x, y, text, fgcolor, bgcolor, doublesize?true:false);
}
/********************************
* OSKB handling
********************************/
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
// On screen keyboard position
#define KXOFF 28 //64
#define KYOFF 96
#define KWIDTH 11 //22
#define KHEIGHT 3
static bool oskbOn = false;
static int cxpos = 0;
static int cypos = 0;
static int oskbMap = 0;
static uint16_t oskbBLastState = 0;
static void lineOSKB2(int kxoff, int kyoff, char * str, int row)
{
char c[2] = {'A',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[0] = *cpt++;
c[1] = 0;
uint16_t bg = RGBVAL16(0x00,0x00,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0xff,0x00,0x00);
tft.drawTextNoDma(kxoff+8*i,kyoff, &c[0], RGBVAL16(0x00,0xff,0xff), bg, ((i&1)?false:true));
}
}
static void lineOSKB(int kxoff, int kyoff, char * str, int row)
{
char c[4] = {' ',0,' ',0};
const char * cpt = str;
for (int i=0; i<KWIDTH; i++)
{
c[1] = *cpt++;
uint16_t bg;
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == row) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+0 , " ", RGBVAL16(0x00,0x00,0x00), bg, false);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+8 , &c[0], RGBVAL16(0x00,0x00,0x00), bg, true);
tft.drawTextNoDma(kxoff+24*i,kyoff+32*row+24, " ", RGBVAL16(0x00,0x00,0x00), bg, false);
}
}
static void drawOskb(void)
{
// lineOSKB2(KXOFF,KYOFF+0, (char *)"Q1W2E3R4T5Y6U7I8O9P0<=", 0);
// lineOSKB2(KXOFF,KYOFF+16, (char *)" A!S@D#F$G%H+J&K*L-EN", 1);
// lineOSKB2(KXOFF,KYOFF+32, (char *)" Z(X)C?V/B\"N<M>.,SP ", 2);
if (oskbMap == 0) {
lineOSKB(KXOFF,KYOFF, keylables_map1_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map1_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map1_2, 2);
}
else if (oskbMap == 1) {
lineOSKB(KXOFF,KYOFF, keylables_map2_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map2_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map2_2, 2);
}
else {
lineOSKB(KXOFF,KYOFF, keylables_map3_0, 0);
lineOSKB(KXOFF,KYOFF, keylables_map3_1, 1);
lineOSKB(KXOFF,KYOFF, keylables_map3_2, 2);
}
}
void toggleOskb(bool forceoff) {
if (forceoff) oskbOn=true;
if (oskbOn) {
oskbOn = false;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, "Press USER2 to toggle onscreen keyboard.", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
} else {
oskbOn = true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
tft.drawTextNoDma(0,32, " Press USER2 to exit onscreen keyboard. ", RGBVAL16(0xff,0xff,0xff), RGBVAL16(0x00,0x00,0x00), true);
tft.drawTextNoDma(0,64, " (USER1 to toggle between keymaps) ", RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
tft.drawRectNoDma(KXOFF,KYOFF, 22*8, 3*16, RGBVAL16(0x00,0x00,0xFF));
drawOskb();
}
}
static int handleOskb(void)
{
int retval = 0;
uint16_t bClick = bLastState & ~oskbBLastState;
oskbBLastState = bLastState;
/*
static const char * digits = "0123456789ABCDEF";
char buf[5] = {0,0,0,0,0};
int val = bClick;
buf[0] = digits[(val>>12)&0xf];
buf[1] = digits[(val>>8)&0xf];
buf[2] = digits[(val>>4)&0xf];
buf[3] = digits[val&0xf];
tft.drawTextNoDma(0,KYOFF+ 64,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),1);
*/
if (bClick & MASK_KEY_USER2)
{
toggleOskb(false);
}
if (oskbOn)
{
bool updated = true;
if (bClick & MASK_KEY_USER1)
{
oskbMap += 1;
if (oskbMap == 3) oskbMap = 0;
}
else if (bClick & MASK_JOY2_LEFT)
{
cxpos++;
if (cxpos >= KWIDTH) cxpos = 0;
}
else if (bClick & MASK_JOY2_RIGHT)
{
cxpos--;
if (cxpos < 0) cxpos = KWIDTH-1;
}
else if (bClick & MASK_JOY2_DOWN)
{
cypos++;
if (cypos >= KHEIGHT) cypos = 0;
}
else if (bClick & MASK_JOY2_UP)
{
cypos--;
if (cypos < 0) cypos = KHEIGHT-1;
}
else if (oskbBLastState & MASK_JOY2_BTN)
{
retval = cypos*KWIDTH+cxpos+1;
if (retval) {
retval--;
//if (retval & 1) retval = key_map2[retval>>1];
//else retval = key_map1[retval>>1];
if (oskbMap == 0) {
retval = key_map1[retval];
}
else if (oskbMap == 1) {
retval = key_map2[retval];
}
else {
retval = key_map3[retval];
}
}
}
else {
updated=false;
}
if (updated) drawOskb();
}
return retval;
}
#endif
/********************************
* Input and keyboard
@ -235,8 +492,10 @@ int emu_ReadKeys(void)
keymatrix_hitrow = -1;
unsigned char row;
unsigned short cols[6]={1,2,3,4,5,14};
unsigned char keymatrixtmp[6];
for (int i=0;i<6;i++){
// gpio_set_dir(cols[i], GPIO_OUT);
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
@ -252,27 +511,81 @@ int emu_ReadKeys(void)
row |= (gpio_get(15) ? 0 : 0x08);
row |= (gpio_get(7) ? 0 : 0x10);
row |= (gpio_get(22) ? 0 : 0x20);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
// gpio_set_dir(cols[i], GPIO_IN);
keymatrix[i]=row;
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] = row;
}
#ifdef MULTI_DEBOUNCE
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
for (int i=0;i<6;i++){
gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 0);
#ifdef SWAP_ALT_DEL
sleep_us(1);
//__asm volatile ("nop\n"); // 4-8ns
#endif
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);
//gpio_set_dir(cols[i], GPIO_OUT);
gpio_put(cols[i], 1);
gpio_set_dir(cols[i], GPIO_IN);
gpio_disable_pulls(cols[i]);
keymatrixtmp[i] |= row;
}
#endif
#ifdef SWAP_ALT_DEL
// Swap ALT and DEL
unsigned char alt = keymatrix[0] & 0x02;
unsigned char del = keymatrix[5] & 0x20;
keymatrix[0] &= ~0x02;
keymatrix[5] &= ~0x20;
if (alt) keymatrix[5] |= 0x20;
if (del) keymatrix[0] |= 0x02;
unsigned char alt = keymatrixtmp[0] & 0x02;
unsigned char del = keymatrixtmp[5] & 0x20;
keymatrixtmp[0] &= ~0x02;
keymatrixtmp[5] &= ~0x20;
if (alt) keymatrixtmp[5] |= 0x20;
if (del) keymatrixtmp[0] |= 0x02;
#endif
bool alt_pressed=false;
if ( keymatrix[5] & 0x20 ) {alt_pressed=true; keymatrix[5] &= ~0x20;};
if ( keymatrixtmp[5] & 0x20 ) {alt_pressed=true; keymatrixtmp[5] &= ~0x20;};
for (int i=0;i<6;i++){
row = keymatrix[i];
row = keymatrixtmp[i];
if (row) keymatrix_hitrow=i;
keymatrix[i] = row;
}
//6,9,15,8,7,22
@ -317,6 +630,7 @@ int emu_ReadKeys(void)
if (hundred_ms_cnt >= 2)
{
hundred_ms_cnt = 0;
/*
if ( (time_ms-keypress_t_ms) < 500)
{
if (key_alt == false)
@ -328,13 +642,14 @@ int emu_ReadKeys(void)
key_alt = false;
}
}
*/
}
}
}
else {
// Keep press
if (hundred_ms_cnt == 1) {
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 1000)
if ((to_ms_since_boot (get_absolute_time())-keypress_t_ms) > 2000)
{
if (key_alt == false)
{
@ -378,6 +693,12 @@ int emu_ReadKeys(void)
{
}
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (oskbOn) {
retval |= MASK_OSKB;
}
#endif
return (retval);
}
@ -404,8 +725,6 @@ int emu_ReadI2CKeyboard(void) {
}
if (keymatrix_hitrow >=0 ) {
unsigned short match = ((unsigned short)keymatrix_hitrow<<8) | keymatrix[keymatrix_hitrow];
//if ( (match == 0x002 ) ) return 0; // shift or fn
//if (match < 0x100 ) match = match & ~0x002; // ignore shift key
for (int i=0; i<sizeof(matkeys)/sizeof(unsigned short); i++) {
if (match == matkeys[i]) {
hundred_ms_cnt = 0;
@ -413,6 +732,11 @@ int emu_ReadI2CKeyboard(void) {
}
}
}
#endif
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
if (!menuOn) {
retval = handleOskb();
}
#endif
return(retval);
}
@ -538,34 +862,25 @@ void emu_InitJoysticks(void) {
gpio_set_dir(4, GPIO_OUT);
gpio_set_dir(5, GPIO_OUT);
gpio_set_dir(14, GPIO_OUT);
gpio_put(1, 1);
gpio_put(2, 1);
gpio_put(3, 1);
gpio_put(4, 1);
gpio_put(5, 1);
gpio_put(14, 1);
/*
gpio_put(1, 0);
gpio_put(2, 0);
gpio_put(3, 0);
gpio_put(4, 0);
gpio_put(5, 0);
gpio_put(14, 0);
gpio_set_pulls(1,true,true);
gpio_set_pulls(2,true,true);
gpio_set_pulls(3,true,true);
gpio_set_pulls(4,true,true);
gpio_set_pulls(5,true,true);
gpio_set_pulls(14,true,true);
// but set as input floating when not used!
gpio_set_dir(1, GPIO_IN);
gpio_set_dir(2, GPIO_IN);
gpio_set_dir(3, GPIO_IN);
gpio_set_dir(4, GPIO_IN);
gpio_set_dir(5, GPIO_IN);
gpio_set_dir(14, GPIO_IN);
*/
gpio_disable_pulls(1);
gpio_disable_pulls(2);
gpio_disable_pulls(3);
gpio_disable_pulls(4);
gpio_disable_pulls(5);
gpio_disable_pulls(14);
// Input pins (cols)
gpio_init(6);
@ -574,18 +889,18 @@ void emu_InitJoysticks(void) {
gpio_init(8);
gpio_init(7);
gpio_init(22);
gpio_set_pulls(6,true,false);
gpio_set_dir(6,GPIO_IN);
gpio_set_pulls(9,true,false);
gpio_set_dir(9,GPIO_IN);
gpio_set_pulls(15,true,false);
gpio_set_dir(15,GPIO_IN);
gpio_set_pulls(8,true,false);
gpio_set_dir(8,GPIO_IN);
gpio_set_pulls(7,true,false);
gpio_set_dir(7,GPIO_IN);
gpio_set_pulls(22,true,false);
gpio_set_dir(22,GPIO_IN);
gpio_pull_up(6);
gpio_pull_up(9);
gpio_pull_up(15);
gpio_pull_up(8);
gpio_pull_up(7);
gpio_pull_up(22);
#endif
}
@ -594,8 +909,17 @@ int emu_setKeymap(int index) {
/********************************
* Initialization
********************************/
void emu_init(void)
{
// Dual display config, initialize TFT
#if (defined(ILI9341) || defined(ST7789)) && defined(USE_VGA)
tft.begin();
#endif
emu_InitJoysticks();
#ifdef SWAP_JOYSTICK
joySwapped = true;
@ -627,7 +951,6 @@ void emu_init(void)
void emu_start(void)
{
usbnavpad = 0;
keyMap = 0;

View file

@ -11,19 +11,42 @@
#ifdef KEYMAP_PRESENT
#define keylables_map1_0 (char *)"qwertyuiop\x1a"
#define keylables_map1_1 (char *)" asdfghjkl\x19"
#define keylables_map1_2 (char *)" zxcvbnm.\x10 "
const unsigned short key_map1[] = {
1,2,3,4,5,6,7,8,9,10,11,
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 };
'Q','W','E','R','T','Y','U','I','O','P',157,
0,'A','S','D','F','G','H','J','K','L',0x0D,
0,'Z','X','C','V','B','N','M','.',' ',
145,157,29,17
};
#define keylables_map2_0 (char *)"1234567890 "
#define keylables_map2_1 (char *)" !@#$%+&*- "
#define keylables_map2_2 (char *)" ()?/\"<>,: "
const unsigned short key_map2[] = {
'1','2','3','4','5','6','7','8','9','0',0,
0, '!','@','#','$','%','+','&','*','-','\/',
0, '(',')','?','\/','"','<','>',',',':',
0,0,0,0
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" ;= "
const unsigned short key_map3[] = {
133,134,135,136,137,138,139,140,0,0,0, // function keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,';','=',
0,0,0,0
};
#ifdef PICOMPUTER
const unsigned short matkeys[] = {
0x020,0x120,0x220,0x320,0x420, 0x408,0x308,0x208,0x108,0x008 ,0x002, // row 1
0x510, 0x010,0x110,0x210,0x310,0x410, 0x401,0x301,0x201,0x101,0x001, // row 2
0x520,0x102,0x202,0x302,0x402, 0x404,0x304,0x204,0x104,0x004, // row 3
0x020,0x120,0x220,0x320,0x420,0x408,0x308,0x208,0x108,0x008,0x002, // row 1
0x510,0x010,0x110,0x210,0x310,0x410,0x401,0x301,0x201,0x101,0x001, // row 2
0x520,0x102,0x202,0x302,0x402,0x404,0x304,0x204,0x104,0x004, // row 3
0x508,0x501,0x502,0x504 }; // cursor keys
#endif
#endif

View file

@ -25,10 +25,19 @@ static int fb_width, fb_height;
#include "hardware/vreg.h"
static const char * digits = "0123456789ABCDEF";
static int hk = 0;
static int prevhk = 0;
static int col=0;
static int row=0;
void emu_Input(uint16_t bClick) {
hk = emu_ReadI2CKeyboard();
}
bool repeating_timer_callback(struct repeating_timer *t) {
uint16_t bClick = emu_DebounceLocalKeys();
//emu_Input(bClick);
emu_Input(bClick);
return true;
}
@ -49,14 +58,14 @@ int main(void) {
emu_start();
//tft.startDMA();
struct repeating_timer timer;
add_repeating_timer_ms(25, repeating_timer_callback, NULL, &timer);
add_repeating_timer_ms(20, repeating_timer_callback, NULL, &timer);
tft.fillScreenNoDma(LIGHT_BLUE);
tft.get_frame_buffer_size(&fb_width, &fb_height);
tft.drawRectNoDma((fb_width-320)/2,(fb_height-200)/2, 320,200, BLUE);
tft.drawTextNoDma((fb_width-320)/2,(fb_height-200)/2+1*8," **** COMMODORE 64 BASIC V2 **** ",LIGHT_BLUE,BLUE,false);
tft.drawTextNoDma((fb_width-320)/2,(fb_height-200)/2+3*8," 64K RAM SYSTEM 38911 BASIC BYTES FREE ",LIGHT_BLUE,BLUE,false);
tft.drawTextNoDma((fb_width-320)/2,(fb_height-200)/2+5*8,"READY.",LIGHT_BLUE,BLUE,false);
//tft.drawTextNoDma((fb_width-320)/2,(fb_height-200)/2+1*8," **** COMMODORE 64 BASIC V2 **** ",LIGHT_BLUE,BLUE,false);
//tft.drawTextNoDma((fb_width-320)/2,(fb_height-200)/2+3*8," 64K RAM SYSTEM 38911 BASIC BYTES FREE ",LIGHT_BLUE,BLUE,false);
//tft.drawTextNoDma((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;
@ -68,7 +77,7 @@ int main(void) {
buf[0] = digits[r1];
buf[1] = digits[r2];
buf[2] = digits[r3];
tft.drawTextNoDma(4*8,0,buf,BLUE,LIGHT_BLUE,false);
tft.drawTextNoDma(0,0,buf,BLUE,LIGHT_BLUE,false);
while (true) {
uint16_t bClick = emu_GetPad();
@ -77,39 +86,60 @@ int main(void) {
buf[1] = digits[(bClick>>8)&0xf];
buf[2] = digits[(bClick>>4)&0xf];
buf[3] = digits[bClick&0xf];
tft.drawTextNoDma(4*8,16,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
tft.drawTextNoDma(4*8,0,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),false);
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.drawTextNoDma(4*8,16*2,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
tft.drawTextNoDma(4*8,8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),false);
buf[2] = 0;
key = emu_ReadI2CKeyboard2(0);
buf[0] = digits[(key>>4)&0xf];
buf[1] = digits[key&0xf];
tft.drawTextNoDma(4*8,16*4,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
tft.drawTextNoDma(9*8+0*24,0*8,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.drawTextNoDma(4*8,16*5,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
tft.drawTextNoDma(9*8+1*24,0*8,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.drawTextNoDma(4*8,16*6,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
tft.drawTextNoDma(9*8+2*24,0*8,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.drawTextNoDma(4*8,16*7,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
tft.drawTextNoDma(9*8+3*24,0*8,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.drawTextNoDma(4*8,16*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
tft.drawTextNoDma(9*8+4*24,0*8,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.drawTextNoDma(4*8,16*9,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
tft.drawTextNoDma(9*8+5*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
if ( (hk != 0) && (hk < 128) ) {
buf[0] = (char)(hk&0xff);
buf[1] = 0;
tft.drawTextNoDma(col*8,(row+3)*8,buf,LIGHT_BLUE,BLUE,false);
col += 1;
if (col >= 40) {
col=0;
row += 1;
if (row >= 25) {
row=0;
}
}
if (hk != prevhk) {
sleep_ms(200);
}
else {
sleep_ms(100);
}
}
prevhk = hk;
sleep_ms(20);