Add multi display support to teensy41

This commit is contained in:
jean-marcharvengt 2023-05-27 16:25:40 +02:00
parent 2b0e3107c3
commit e664552ed1
321 changed files with 57544 additions and 40442 deletions

View file

@ -0,0 +1 @@
Go to T-COMPUTER GitHub to find T-COMPUTER HEX precompiled binaries...

View file

@ -1,4 +1,10 @@
HEX can be found in bin directory. Select target board in platform_config.h file.
Default is TEECOMPUTER.
Comment out for MCUMEVGA (see wiring in schematics subdirectory)
Soldering the PSRAM (PT8211) below the Teensy4.1 is mandatory!!!!
All compiled with Arduino 1.8.19 + Teensyduino 1.56 All compiled with Arduino 1.8.19 + Teensyduino 1.56
Except UAE TEECOMPUTER for TFT that needs Arduino 1.8.13 + 1.54 Chose optimize:smallest code and USB keyboard layout if needed.
Default CPU speed 600MZ except for TeenyUAE and TeensySNES that need 816MHz.
TeensySNES has USB disabled!

View file

@ -1,4 +1,4 @@
#include "platform_config.h" #include "emuapi.h"
#ifdef HAS_SND #ifdef HAS_SND
@ -176,7 +176,6 @@ void AudioPlaySystem::step(void) {
} }
#ifndef HAS_T4_VGA
/******************************************************************* /*******************************************************************
Experimental I2S interrupt based sound driver for PCM51xx !!! Experimental I2S interrupt based sound driver for PCM51xx !!!
*******************************************************************/ *******************************************************************/
@ -263,7 +262,57 @@ FLASHMEM static void config_sai1()
I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE ;//<-- not using DMA */; I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE ;//<-- not using DMA */;
} }
FLASHMEM static void config_pt8211()
{
CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON);
double fs = AUDIO_SAMPLE_RATE_EXACT;
// PLL between 27*24 = 648MHz und 54*24=1296MHz
int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
int n2 = 1 + (24000000 * 27) / (fs * 256 * n1);
double C = (fs * 256 * n1 * n2) / 24000000;
int c0 = C;
int c2 = 10000;
int c1 = C * c2 - (c0 * c2);
set_audioClock(c0, c1, c2, true);
// clear SAI1_CLK register locations
CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK))
| CCM_CSCMR1_SAI1_CLK_SEL(2); // &0x03 // (0,1,2): PLL3PFD0, PLL5, PLL4
//n1 = n1 / 2; //Double Speed for TDM
CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
| CCM_CS1CDR_SAI1_CLK_PRED(n1 - 1) // &0x07
| CCM_CS1CDR_SAI1_CLK_PODF(n2 - 1); // &0x3f
IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 & ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK))
| (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0)); //Select MCLK
// configure transmitter
int rsync = 0;
int tsync = 1;
I2S1_TMR = 0;
I2S1_TCR1 = I2S_TCR1_RFW(0);
I2S1_TCR2 = I2S_TCR2_SYNC(tsync) | I2S_TCR2_BCP | I2S_TCR2_MSEL(1) | I2S_TCR2_BCD | I2S_TCR2_DIV(1);
I2S1_TCR3 = I2S_TCR3_TCE;
I2S1_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(15) | I2S_TCR4_MF | I2S_TCR4_FSD /*| I2S_TCR4_FSE*/ | I2S_TCR4_FSP ; //PT8211
I2S1_TCR5 = I2S_TCR5_WNW(15) | I2S_TCR5_W0W(15) | I2S_TCR5_FBT(15);
I2S1_RMR = 0;
I2S1_RCR1 = I2S_RCR1_RFW(0);
I2S1_RCR2 = I2S_RCR2_SYNC(rsync) | I2S_RCR2_BCP | I2S_RCR2_MSEL(1)| I2S_RCR2_BCD | I2S_RCR2_DIV(1) ;
I2S1_RCR3 = I2S_RCR3_RCE;
I2S1_RCR4 = I2S_RCR4_FRSZ(1) | I2S_RCR4_SYWD(15) | I2S_RCR4_MF /*| I2S_RCR4_FSE*/ | I2S_RCR4_FSP | I2S_RCR4_FSD; //PT8211
I2S1_RCR5 = I2S_RCR5_WNW(15) | I2S_RCR5_W0W(15) | I2S_RCR5_FBT(15);
CORE_PIN21_CONFIG = 3; // RX_BCLK
CORE_PIN20_CONFIG = 3; // RX_SYNC
CORE_PIN7_CONFIG = 3; // TX_DATA0
I2S1_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE;
I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE ;//<-- not using DMA */;
}
//DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx[1024]; //DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx[1024];
@ -277,7 +326,6 @@ static uint32_t * i2s_tx_buffer __attribute__((aligned(32)));
static uint16_t * i2s_tx_buffer16; static uint16_t * i2s_tx_buffer16;
static uint16_t * txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2); static uint16_t * txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2);
FASTRUN void AudioPlaySystem::AUDIO_isr() { FASTRUN void AudioPlaySystem::AUDIO_isr() {
*txreg = i2s_tx_buffer16[cnt]; *txreg = i2s_tx_buffer16[cnt];
@ -335,7 +383,14 @@ FLASHMEM void AudioPlaySystem::begin_audio(int samplesize, void (*callback)(shor
sampleBufferSize = samplesize; sampleBufferSize = samplesize;
#ifdef PT8211
txreg = (uint16_t *)((uint32_t)&I2S1_TDR0);
config_pt8211();
#else
txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2);
config_sai1(); config_sai1();
#endif
attachInterruptVector(IRQ_SAI1, AUDIO_isr); attachInterruptVector(IRQ_SAI1, AUDIO_isr);
NVIC_ENABLE_IRQ(IRQ_SAI1); NVIC_ENABLE_IRQ(IRQ_SAI1);
NVIC_SET_PRIORITY(IRQ_QTIMER3, 0); // 0 highest priority, 255 = lowest priority NVIC_SET_PRIORITY(IRQ_QTIMER3, 0); // 0 highest priority, 255 = lowest priority
@ -358,4 +413,3 @@ FLASHMEM void AudioPlaySystem::end_audio()
} }
#endif #endif
#endif

View file

@ -19,13 +19,10 @@ public:
void buzz(int size, int val); void buzz(int size, int val);
void step(void); void step(void);
static void snd_Mixer(short * stream, int len ); static void snd_Mixer(short * stream, int len );
#ifndef HAS_T4_VGA
void begin_audio(int samplesize, void (*callback)(short * stream, int len)); void begin_audio(int samplesize, void (*callback)(short * stream, int len));
void end_audio(); void end_audio();
static void AUDIO_isr(void); static void AUDIO_isr(void);
static void SOFTWARE_isr(void); static void SOFTWARE_isr(void);
#endif
}; };

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
#ifndef EMUAPI_H
#define EMUAPI_H
#include "platform_config.h"
#include "emucfg.h"
#define ACTION_NONE 0
#define ACTION_RUN1 1
#define ACTION_RUN2 2
#define FORCE_VGATIMERVSYNC 1
#define SUPPORT_HIRES 1
#define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002
#define MASK_JOY2_UP 0x0004
#define MASK_JOY2_DOWN 0x0008
#define MASK_JOY2_BTN 0x0010
#define MASK_KEY_USER1 0x0020
#define MASK_KEY_USER2 0x0040
#define MASK_KEY_USER3 0x0080
#define MASK_JOY1_RIGHT 0x0100
#define MASK_JOY1_LEFT 0x0200
#define MASK_JOY1_UP 0x0400
#define MASK_JOY1_DOWN 0x0800
#define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#ifdef __cplusplus
extern "C" {
extern void emu_init(int hires=0);
extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif
extern void emu_printf(const char * text);
extern void emu_printi(int val);
extern void emu_printh(int val);
extern void * emu_Malloc(unsigned int size);
extern void * emu_MallocI(unsigned int size);
extern void emu_Free(void * pt);
extern void * emu_SMalloc(unsigned int size);
extern void emu_SFree(void * pt);
extern int emu_FileOpen(const char * filepath, const char * mode);
extern int emu_FileRead(void * buf, int size, int handler);
extern int emu_FileWrite(void * buf, int size, int handler);
extern int emu_FileGetc(int handler);
extern int emu_FileSeek(int handler, int seek, int origin);
extern int emu_FileTell(int handler);
extern void emu_FileClose(int handler);
extern unsigned int emu_FileSize(const char * filepath);
extern unsigned int emu_LoadFile(const char * filepath, void * buf, int size);
extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek);
extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index);
extern void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line);
extern void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride);
extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void);
extern int emu_IsVga(void);
extern int emu_IsVgaHires(void);
extern int menuActive(void);
extern char * menuSelection(void);
extern char * menuSecondSelection(void);
extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void);
extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly);
extern unsigned short emu_DebounceLocalKeys(void);
extern int emu_ReadKeys(void);
extern int emu_GetPad(void);
extern int emu_GetMouse(int *x, int *y, int *buts);
extern int emu_MouseDetected(void);
extern int emu_GetJoystick(void);
extern int emu_KeyboardDetected(void);
extern int emu_ReadAnalogJoyX(int min, int max);
extern int emu_ReadAnalogJoyY(int min, int max);
extern int emu_ReadI2CKeyboard(void);
extern unsigned char emu_ReadI2CKeyboard2(int row);
extern void emu_KeyboardOnUp(int keymodifer, int key);
extern void emu_KeyboardOnDown(int keymodifer, int key);
extern void emu_MidiOnDataReceived(unsigned char data);
extern void emu_sndPlaySound(int chan, int volume, int freq);
extern void emu_sndPlayBuzz(int size, int val);
extern void emu_sndInit();
extern void emu_resetus(void);
extern int emu_us(void);
extern int emu_setKeymap(int index);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,108 @@
#ifndef EMUCFG_H
#define EMUCFG_H
// Title: < >
#define TITLE " XXXX Emulator "
#define ROMSDIR "snes"
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
//#define CUSTOM_SND 1
//#define TIMER_REND 1
//#define EXTPAD 1
#define EXTRA_HEAP 0x10
//#define FILEBROWSER 1
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"QWERTYUIOP\x1a"
#define keylables_map0_1 (char *)" ASDFGHJKL\x19"
#define keylables_map0_2 (char *)" ZXCVBNM,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'q','w','E','R','T','Y','U','I','O','P',157, //default C64 uppercase always
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
#define keylables_map1_3 (char *)" "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit 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,0,0,
0,0,' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
153,151,150,152, //U L R D
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
129,130,131,132,133,134,135,136,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,0,0,
0,0,' ',0
};
#define keylables_map4_0 (char *)"QWERTYUIOP@"
#define keylables_map4_1 (char *)" ASDFGHJKL\x19"
#define keylables_map4_2 (char *)" ZXCVBNM<>:?"
#define keylables_map4_3 (char *)" =\x10_"
const unsigned short key_map4[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M','<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#endif

View file

@ -1,8 +1,34 @@
#ifndef _PLATFORM_CONFIG_H_ #ifndef _PLATFORM_CONFIG_H_
#define _PLATFORM_CONFIG_H_ #define _PLATFORM_CONFIG_H_
#define ST7789 1 // Will work on TEECOMPUTER as is
#define TFTSPI1 1 // NO TEECOMPUTER specific switch
#define HAS_T4_VGA 1
//#define INVX 1
#define INVY 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
//#define HAS_USBKEY 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
//#define HAS_USBJOY 1 // not working yet
//#define PT8211 1
//#define FLIP_SCREEN 1
//#define ILI9341 1
//#define ST7789 1
//#define SWAP_JOYSTICK 1
//#define LOHRES 1
//#define ROTATE_SCREEN 1
//#define EXTERNAL_SD 1
//#define USE_SDFAT 1
//#define SD_FAT_TYPE 1
//#define USE_SDFS 1
//#define SDFSDEV "1:"
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
/*
TFT/VGA driver
DMA TFT driver based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _T4_DSPH_
#define _T4_DSPH_
#ifdef __cplusplus
#include <Arduino.h>
#include <DMAChannel.h>
#endif
#include "platform_config.h"
#include "iopins.h"
#ifndef TFT_WIDTH
#define TFT_WIDTH 320
#endif
#define TFT_REALWIDTH 320
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 240
#endif
#define TFT_REALHEIGHT 240
typedef enum gfx_mode_t
{
MODE_UNDEFINED = 0,
MODE_TFTILI_320x240 = 1,
MODE_TFTST_320x240 = 2,
MODE_VGA_320x240 = 3,
MODE_VGA_320x480 = 4,
MODE_VGA_352x240 = 5,
MODE_VGA_352x480 = 6,
MODE_VGA_512x240 = 7,
MODE_VGA_512x480 = 8,
MODE_VGA_640x240 = 9,
MODE_VGA_640x480 = 10
} gfx_mode_t;
typedef enum gfx_error_t
{
GFX_OK = 0,
GFX_ERROR = -1
} gfx_error_t;
#ifdef __cplusplus
class T4_DSP
{
public:
T4_DSP();
gfx_error_t begin(gfx_mode_t mode);
gfx_mode_t getMode(void);
void startRefresh(void);
void stopRefresh();
int get_frame_buffer_size(int *width, int *height);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
// wait next Vsync
void waitSync();
void waitLine(int line);
// NoDMA functions
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
void writeLine(int width, int height, int y, uint16_t *buf);
void writeLinePal(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
void writeScreenPal(int width, int height, int stride, uint8_t *buf, uint16_t *palette16);
void writeLine8(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
protected:
static uint8_t _rst, _cs, _dc;
static uint8_t _mosi, _sclk;
static uint8_t _vsync_pin;
static DMAChannel flexio1DMA;
static DMAChannel flexio2DMA;
void tft_setup(bool isST);
static void TFT_isr(void);
static void QT3_isr(void);
};
#endif
#endif

View file

@ -1,73 +1,15 @@
extern "C" { #include "emuapi.h"
#include "iopins.h" #include "iopins.h"
}
#include "t4_dsp.h"
#include "tft_t_dma.h" extern T4_DSP tft;
TFT_T_DMA tft = TFT_T_DMA(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO, TFT_TOUCH_CS, TFT_TOUCH_INT);
static IntervalTimer myTimer;
volatile boolean vbl=true;
static int skip=0;
static elapsedMicros tius;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
#ifdef HAS_SND
#include "AudioPlaySystem.h"
static AudioPlaySystem mymixer;
static void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
// sgtl5000_1.enable();
// sgtl5000_1.volume(0.6);
mymixer.start();
}
static void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
static void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif
// **************************************************** // ****************************************************
// the setup() method runs once, when the sketch starts // the setup() method runs once, when the sketch starts
// **************************************************** // ****************************************************
void setup() { void setup() {
tft.begin(); emu_init();
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) ); emu_start(20000,nullptr);
tft.startDMA();
myTimer.begin(vblCount, 20000); //to run every 20ms
#ifdef HAS_SND
emu_sndInit();
#endif
} }
@ -97,12 +39,13 @@ void loop(void)
tft.fillScreen( RGBVAL16(colcomponent,0x00,0x00) ); tft.fillScreen( RGBVAL16(colcomponent,0x00,0x00) );
colcomponent += 1; colcomponent += 1;
colcomponent &= 0xff; colcomponent &= 0xff;
volatile boolean vb=vbl; emu_DrawVsync();
while (vbl==vb) {};
notedelay += 1; notedelay += 1;
notedelay &= 0x07; notedelay &= 0x07;
int note = notes[note_pos]; int note = notes[note_pos];
#ifdef HAS_SND
emu_sndPlaySound(1, notedelay<<4, note); emu_sndPlaySound(1, notedelay<<4, note);
#endif
if ( !notedelay ) if ( !notedelay )
{ {
note_pos += 1; note_pos += 1;

File diff suppressed because it is too large Load diff

View file

@ -1,234 +0,0 @@
/*
Based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _TFT_T_DMAH_
#define _TFT_T_DMAH_
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include <DMAChannel.h>
#endif
#include "tft_t_dma_config.h"
#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b )
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define R16(rgb) ((rgb>>8)&0xf8)
#define G16(rgb) ((rgb>>3)&0xfc)
#define B16(rgb) ((rgb<<3)&0xf8)
#define PAL_COLOR_MASK 0xff
#ifdef LOHRES
#define TFT_WIDTH 240
#define TFT_REALWIDTH 240
#else
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#endif
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
//#define WIDTH 272
//#define HEIGHT 228
#define LINES_PER_BLOCK 64
#define NR_OF_BLOCK 4
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
#ifdef ILI9341
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0D
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_MH 0x04
#define TFT_CASET ILI9341_CASET
#define TFT_PASET ILI9341_PASET
#define TFT_RAMWR ILI9341_RAMWR
#define TFT_MADCTL ILI9341_MADCTL
#endif
#ifdef ST7789
#define ST7735_NOP 0x00
#define ST7735_SWRESET 0x01
#define ST7735_RDDID 0x04
#define ST7735_RDDST 0x09
#define ST7735_SLPIN 0x10
#define ST7735_SLPOUT 0x11
#define ST7735_PTLON 0x12
#define ST7735_NORON 0x13
#define ST7735_INVOFF 0x20
#define ST7735_INVON 0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_RAMRD 0x2E
#define ST7735_PTLAR 0x30
#define ST7735_COLMOD 0x3A
#define ST7735_MADCTL 0x36
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_DISSET5 0xB6
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_RDID1 0xDA
#define ST7735_RDID2 0xDB
#define ST7735_RDID3 0xDC
#define ST7735_RDID4 0xDD
#define ST7735_PWCTR6 0xFC
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_MADCTL_BGR 0x08
#define ST77XX_MADCTL_MH 0x04
#define TFT_CASET ST7735_CASET
#define TFT_PASET ST7735_RASET
#define TFT_RAMWR ST7735_RAMWR
#define TFT_MADCTL ST7735_MADCTL
#endif
#ifdef __cplusplus
class TFT_T_DMA
{
public:
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
void begin(void);
void flipscreen(bool flip);
boolean isflipped(void);
void startDMA(void);
void stopDMA();
int get_frame_buffer_size(int *width, int *height);
// Touch screen functions
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
// NoDMA functions
void writeScreenNoDma(const uint16_t *pcolors);
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
uint16_t * getLineBuffer(int j);
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int y, uint16_t *buf);
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
protected:
uint8_t _rst, _cs, _dc;
uint8_t _miso, _mosi, _sclk;
uint8_t _touch_irq=255, _touch_cs=255;
bool flipped=false;
void wait(void);
void enableTouchIrq();
};
#endif
#endif

View file

@ -1,14 +0,0 @@
#include "platform_config.h"
//#define ST7789 1
//#define ILI9341 1
#define TFT_LINEARINT 1
#define LINEARINT_HACK 1
//#define FLIP_SCREEN 1
//#define TFT_DEBUG 1
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
//#define TFT_STATICFB 1
#endif

View file

@ -176,7 +176,6 @@ void AudioPlaySystem::step(void) {
} }
#ifndef HAS_T4_VGA
/******************************************************************* /*******************************************************************
Experimental I2S interrupt based sound driver for PCM51xx !!! Experimental I2S interrupt based sound driver for PCM51xx !!!
*******************************************************************/ *******************************************************************/
@ -263,7 +262,57 @@ FLASHMEM static void config_sai1()
I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE ;//<-- not using DMA */; I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE ;//<-- not using DMA */;
} }
FLASHMEM static void config_pt8211()
{
CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON);
double fs = AUDIO_SAMPLE_RATE_EXACT;
// PLL between 27*24 = 648MHz und 54*24=1296MHz
int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
int n2 = 1 + (24000000 * 27) / (fs * 256 * n1);
double C = (fs * 256 * n1 * n2) / 24000000;
int c0 = C;
int c2 = 10000;
int c1 = C * c2 - (c0 * c2);
set_audioClock(c0, c1, c2, true);
// clear SAI1_CLK register locations
CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK))
| CCM_CSCMR1_SAI1_CLK_SEL(2); // &0x03 // (0,1,2): PLL3PFD0, PLL5, PLL4
//n1 = n1 / 2; //Double Speed for TDM
CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
| CCM_CS1CDR_SAI1_CLK_PRED(n1 - 1) // &0x07
| CCM_CS1CDR_SAI1_CLK_PODF(n2 - 1); // &0x3f
IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 & ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK))
| (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0)); //Select MCLK
// configure transmitter
int rsync = 0;
int tsync = 1;
I2S1_TMR = 0;
I2S1_TCR1 = I2S_TCR1_RFW(0);
I2S1_TCR2 = I2S_TCR2_SYNC(tsync) | I2S_TCR2_BCP | I2S_TCR2_MSEL(1) | I2S_TCR2_BCD | I2S_TCR2_DIV(1);
I2S1_TCR3 = I2S_TCR3_TCE;
I2S1_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(15) | I2S_TCR4_MF | I2S_TCR4_FSD /*| I2S_TCR4_FSE*/ | I2S_TCR4_FSP ; //PT8211
I2S1_TCR5 = I2S_TCR5_WNW(15) | I2S_TCR5_W0W(15) | I2S_TCR5_FBT(15);
I2S1_RMR = 0;
I2S1_RCR1 = I2S_RCR1_RFW(0);
I2S1_RCR2 = I2S_RCR2_SYNC(rsync) | I2S_RCR2_BCP | I2S_RCR2_MSEL(1)| I2S_RCR2_BCD | I2S_RCR2_DIV(1) ;
I2S1_RCR3 = I2S_RCR3_RCE;
I2S1_RCR4 = I2S_RCR4_FRSZ(1) | I2S_RCR4_SYWD(15) | I2S_RCR4_MF /*| I2S_RCR4_FSE*/ | I2S_RCR4_FSP | I2S_RCR4_FSD; //PT8211
I2S1_RCR5 = I2S_RCR5_WNW(15) | I2S_RCR5_W0W(15) | I2S_RCR5_FBT(15);
CORE_PIN21_CONFIG = 3; // RX_BCLK
CORE_PIN20_CONFIG = 3; // RX_SYNC
CORE_PIN7_CONFIG = 3; // TX_DATA0
I2S1_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE;
I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE ;//<-- not using DMA */;
}
//DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx[1024]; //DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx[1024];
@ -277,7 +326,6 @@ static uint32_t * i2s_tx_buffer __attribute__((aligned(32)));
static uint16_t * i2s_tx_buffer16; static uint16_t * i2s_tx_buffer16;
static uint16_t * txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2); static uint16_t * txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2);
FASTRUN void AudioPlaySystem::AUDIO_isr() { FASTRUN void AudioPlaySystem::AUDIO_isr() {
*txreg = i2s_tx_buffer16[cnt]; *txreg = i2s_tx_buffer16[cnt];
@ -335,7 +383,14 @@ FLASHMEM void AudioPlaySystem::begin_audio(int samplesize, void (*callback)(shor
sampleBufferSize = samplesize; sampleBufferSize = samplesize;
#ifdef PT8211
txreg = (uint16_t *)((uint32_t)&I2S1_TDR0);
config_pt8211();
#else
txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2);
config_sai1(); config_sai1();
#endif
attachInterruptVector(IRQ_SAI1, AUDIO_isr); attachInterruptVector(IRQ_SAI1, AUDIO_isr);
NVIC_ENABLE_IRQ(IRQ_SAI1); NVIC_ENABLE_IRQ(IRQ_SAI1);
NVIC_SET_PRIORITY(IRQ_QTIMER3, 0); // 0 highest priority, 255 = lowest priority NVIC_SET_PRIORITY(IRQ_QTIMER3, 0); // 0 highest priority, 255 = lowest priority
@ -358,4 +413,3 @@ FLASHMEM void AudioPlaySystem::end_audio()
} }
#endif #endif
#endif

View file

@ -19,13 +19,10 @@ public:
void buzz(int size, int val); void buzz(int size, int val);
void step(void); void step(void);
static void snd_Mixer(short * stream, int len ); static void snd_Mixer(short * stream, int len );
#ifndef HAS_T4_VGA
void begin_audio(int samplesize, void (*callback)(short * stream, int len)); void begin_audio(int samplesize, void (*callback)(short * stream, int len));
void end_audio(); void end_audio();
static void AUDIO_isr(void); static void AUDIO_isr(void);
static void SOFTWARE_isr(void); static void SOFTWARE_isr(void);
#endif
}; };

View file

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#ifdef HAS_T4_VGA #include <Arduino.h>
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#ifdef HAS_USBKEY #ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info #include "USBHost_t36.h" // Read this header first for key info
USBHost myusb; USBHost myusb;
USBHub hub1(myusb); USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb); KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb); USBHIDParser hid1(myusb);
MouseController mouse1(myusb); MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb); MIDIDevice midi1(myusb);
#endif #endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void); static bool emu_writeConfig(void);
static bool emu_readConfig(void); static bool emu_readConfig(void);
static bool emu_eraseConfig(void); static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false; static bool mouseDetected = false;
static bool keyboardDetected = false; static bool keyboardDetected = false;
@ -34,12 +40,13 @@ static File file;
#define MAX_FILES 64 #define MAX_FILES 64
#define AUTORUN_FILENAME "autorun.txt" #define AUTORUN_FILENAME "autorun.txt"
#define GFX_CFG_FILENAME "gfxmode.txt"
#define MAX_FILENAME_SIZE 24 #define MAX_FILENAME_SIZE 34
#define MAX_MENULINES 9 #define MAX_MENULINES 9
#define TEXT_HEIGHT 16 #define TEXT_HEIGHT 16
#define TEXT_WIDTH 8 #define TEXT_WIDTH 8
#define MENU_FILE_XOFFSET (6*TEXT_WIDTH) #define MENU_FILE_XOFFSET (2*TEXT_WIDTH)
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT) #define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH) #define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT) #define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
@ -53,7 +60,8 @@ static File file;
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft; #include "t4_dsp.h"
T4_DSP tft;
static int nbFiles=0; static int nbFiles=0;
static int curFile=0; static int curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]=""; static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true; static bool menuRedraw=true;
static bool autorun=false; static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys; static const unsigned short * keys;
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
@ -158,6 +168,29 @@ void emu_Free(void * pt)
free(pt); free(pt);
} }
#define SMEMPOOL (0x800000)
EXTMEM static unsigned char slowmem[SMEMPOOL];
static int slowmempt = 0;
void * emu_SMalloc(unsigned int size)
{
void * mem = (void*)&slowmem[slowmempt];
slowmempt += size;
if ( slowmempt > SMEMPOOL ) {
mem = NULL;
emu_printf("failure to allocate slow");
}
else {
emu_printf("could allocate slow static ");
emu_printf(size);
}
return mem;
}
void emu_SFree(void * pt)
{
}
/******************************** /********************************
* Input and keyboard * Input and keyboard
********************************/ ********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif #endif
if ( row & 0x02 ) retval |= MASK_JOY2_BTN; if ( row & 0x02 ) retval |= MASK_JOY2_BTN;
#ifdef EXTPAD
if ( sh_pressed ) retval |= MASK_KEY_USER3;
if ( fn_pressed ) retval |= MASK_KEY_USER1;
digitalWrite(KLED, 0);
#else
// Handle LED flash // Handle LED flash
uint32_t time_ms=millis(); uint32_t time_ms=millis();
if ((time_ms-last_t_ms) > 100) { if ((time_ms-last_t_ms) > 100) {
@ -412,8 +451,9 @@ int emu_ReadKeys(void)
if ( key_fn ) retval |= MASK_KEY_USER2; if ( key_fn ) retval |= MASK_KEY_USER2;
if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1; if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) ) if ( (fn_pressed) && (sh_pressed) )
#else #else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) ) || (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) { while (true) {
; ;
} }
#endif #endif
} }
emu_GetJoystick();
return (retval); return (retval);
} }
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
} }
int emu_GetMouse(int *x, int *y, int *buts) { int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) { if (mouse1.available()) {
*buts = mouse1.getButtons(); *buts = mouse1.getButtons();
*x = mouse1.getMouseX(); *x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
return 0; return 0;
} }
#ifdef HAS_USBKEY int emu_GetJoystick(void) {
#if defined(HAS_USB) && (HAS_USBJOY)
for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++) {
if (joysticks[joystick_index].available()) {
uint64_t axis_mask = joysticks[joystick_index].axisMask();
uint64_t axis_changed_mask = joysticks[joystick_index].axisChangedMask();
uint32_t buttons = joysticks[joystick_index].getButtons();
Serial.printf("Joystick(%d): buttons = %x", joystick_index, buttons);
Serial.println();
}
}
return 1;
#endif
return 0;
}
#if defined(HAS_USB) && (HAS_USBKEY)
void OnPress(auto key) void OnPress(auto key)
{ {
keyboardDetected = true; keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0); return (keyboardDetected?1:0);
} }
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16]; static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0; static unsigned char midiLastCmd=0;
static int midiDataCnt=0; static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif #endif
void emu_MidiOnDataReceived(unsigned char value) { void emu_MidiOnDataReceived(unsigned char value) {
#if defined(HAS_USB) && (HAS_USBMIDI)
#ifdef HAS_USBKEY
//Serial.println(value, HEX); //Serial.println(value, HEX);
//10000000 = 128 = note off //10000000 = 128 = note off
//10010000 = 144 = note on //10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/******************************** /********************************
* Menu file loader UI * Menu file loader UI
********************************/ ********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) { static int readNbFiles(void) {
int totalFiles = 0; int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles; return totalFiles;
} }
void backgroundMenu(void) { void backgroundMenu(void) {
menuRedraw=true; menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick) int handleMenu(uint16_t bClick)
{ {
if (autorun) { if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1); return (ACTION_RUN1);
} }
int action = ACTION_NONE; int action = ACTION_NONE;
if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) ) { if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) || ( bClick & MASK_KEY_USER2 ) ) {
char newpath[MAX_FILENAME_PATH]; char newpath[MAX_FILENAME_PATH];
strcpy(newpath, selection); strcpy(newpath, selection);
strcat(newpath, "/"); strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection); File file = SD.open(selection);
if (file.isDirectory()) { if (file.isDirectory()) {
curFile = 0; curFile = 0;
nbFiles = readNbFiles(); nbFiles = readNbFiles();
menuRedraw=true;
} }
else { else
action = ACTION_RUN1; {
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
if (key_extmode) { if ( (key_extmode) || ( key_sh) ) {
emu_writeConfig(); emu_writeConfig();
} }
if ( tft.getMode() < MODE_VGA_320x240) {
if ( bClick & MASK_KEY_USER2 ) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
}
//emu_SwapJoysticks(0);
#endif #endif
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
} }
menuRedraw=true;
} }
else if ( bClick & MASK_KEY_USER1 ) { else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true; menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/"); strcat(second_selection, "/");
strcat(second_selection, second_selected_filename); strcat(second_selection, second_selected_filename);
action = ACTION_RUN2; action = ACTION_RUN2;
} }
else if ( bClick & MASK_KEY_USER2 ) {
menuRedraw=true;
//action = ACTION_RUN3;
emu_SwapJoysticks(0);
}
else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) { else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) {
if (curFile!=0) { if (curFile!=0) {
menuRedraw=true; menuRedraw=true;
curFile--; curFile--;
} }
} }
else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) { else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) {
if ((curFile-9)>=0) { if ((curFile-9)>=0) {
menuRedraw=true; menuRedraw=true;
curFile -= 9; curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
menuRedraw=true; menuRedraw=true;
} }
} }
else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) { else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) {
if ((curFile<(nbFiles-9)) && (nbFiles)) { if ((curFile<(nbFiles-9)) && (nbFiles)) {
curFile += 9; curFile += 9;
menuRedraw=true; menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action); return (action);
} }
bool menuActive(void) int menuActive(void)
{ {
return (menuOn); return (menuOn?1:0);
} }
void toggleMenu(bool on) { void toggleMenu(int on) {
if (on) { if (on) {
menuOn=true; menuOn=true;
backgroundMenu(); backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{ {
return (second_selection); return (second_selection);
} }
#endif
/******************************** /********************************
* OSKB handling * OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0}; char c[4] = {' ',0,' ',0};
const char * cpt = str; const char * cpt = str;
int i=0; int i=0;
int fb_width,fb_height; int fb_width,fb_height,fbstride;
tft.get_frame_buffer_size(&fb_width, &fb_height);
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0); int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0); int line = row + (bottom?2:0);
while ((c[1] = *cpt++)) while ((c[1] = *cpt++))
@ -1150,7 +1218,7 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0); 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); else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff); if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false); tft.drawText(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false);
i++; i++;
} }
} }
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval; return retval;
} }
void toggleOSKB(bool forceon) { void toggleOSKB(int forceon) {
if (forceon) { if (forceon) {
oskbOn = true; oskbOn = true;
drawOSKB(); drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#endif #endif
} }
int emu_FileWrite(void * buf, int size, int handler)
{
// emu_printf("emu_FileWrite");
// emu_printi(handler);
#ifdef HCFH
return (file.write(buf, size));
#else
return (getFileHandler(handler).write(buf, size));
#endif
}
int emu_FileGetc(int handler) { int emu_FileGetc(int handler) {
// emu_printf("FileGetc"); // emu_printf("FileGetc");
// emu_printi(handler); // emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize); emu_printf(filesize);
lofile.close(); lofile.close();
} }
else {
emu_printf("filesize failed");
}
return(filesize); return(filesize);
} }
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
SD.remove (ROMSDIR "/" AUTORUN_FILENAME); SD.remove (ROMSDIR "/" AUTORUN_FILENAME);
} }
static bool emu_writeGfxConfig(char * display_type)
{
bool retval = false;
SD.remove ("/" GFX_CFG_FILENAME);
if (strcmp(display_type, "VGA")) {
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_CREAT | O_WRITE)))
{
if (lofile.write(display_type, strlen(display_type)) != strlen(display_type)) {
emu_printf("GFX config write failed");
}
else {
retval = true;
}
lofile.close();
}
}
return retval;
}
#define CFG_VGA 0
#define CFG_ILI 1
#define CFG_ST 2
static int emu_readGfxConfig(void)
{
int retval = CFG_VGA; // No file = VGA
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_READ)))
{
unsigned int filesize = lofile.size();
if (filesize == 2) // "ST"
{
retval = CFG_ST;
}
else if (filesize == 3) // "ILI"
{
retval = CFG_ILI;
}
lofile.close();
}
return retval;
}
/******************************** /********************************
* File IO compatibility * File IO compatibility
********************************/ ********************************/
@ -1670,62 +1794,249 @@ FRESULT f_mkdir (const char* path)
/******************************** /********************************
* Initialization * GFX wrapper
********************************/ ********************************/
void emu_init(void) static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
volatile boolean vgatimervsync=false;
static void (*vblCallback)(void) = nullptr;
static int skip=0;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if ( tft.getMode() >= MODE_VGA_320x240 ) {
if (vgatimervsync) {
while (vbl==vb) {};
}
else {
tft.waitSync();
}
}
else {
while (vbl==vb) {};
}
if (vblCallback != nullptr) {
vblCallback();
}
}
void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride)
{
if (skip == 0) {
tft.writeScreenPal(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
}
}
void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLinePal(width,height,line, VBuf, palette16);
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine(width,height,line, VBuf);
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine8(width,height,line, VBuf, palette16);
}
}
int emu_IsVga(void)
{
return (tft.getMode() >= MODE_VGA_320x240?1:0);
}
int emu_IsVgaHires(void)
{
return (tft.getMode() >= MODE_VGA_640x240?1:0);
}
int emu_FrameSkip(void)
{
return skip;
}
/********************************
* AUDIO wrapper
********************************/
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif
/********************************
* Initialization
********************************/
void emu_init(int hires)
{ {
Serial.begin(115200); Serial.begin(115200);
vgahires = hires;
#ifdef HAS_USBKEY #ifdef HAS_USB
myusb.begin(); myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress); keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease); keyboard1.attachRelease(OnRelease);
#endif #endif
#endif
while (!SD.begin(SD_CS)) #ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{ {
Serial.println("SD begin failed, retrying..."); Serial.println("No SD card detected");
delay(1000);
} }
strcpy(selection,ROMSDIR); strcpy(selection,ROMSDIR);
FileHandlersInit(); FileHandlersInit();
nbFiles = readNbFiles(); nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles); Serial.println(nbFiles);
#endif
emu_InitJoysticks(); emu_InitJoysticks();
#ifdef SWAP_JOYSTICK #ifdef SWAP_JOYSTICK
joySwapped = true; joySwapped = true;
#else #else
joySwapped = false; joySwapped = false;
#endif #endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
int keypressed = emu_ReadKeys(); int keypressed = emu_ReadKeys();
#ifdef HAS_T4_VGA
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
#else
int gfx_mode = CFG_VGA; // default
#ifdef FILEBROWSER
gfx_mode = emu_readGfxConfig();
#endif
// Force VGA if UP pressed
if (keypressed & MASK_JOY2_UP)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("VGA");
#endif
gfx_mode = CFG_VGA;
}
else {
if (keypressed & MASK_JOY2_LEFT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ST");
#endif
gfx_mode = CFG_ST;
}
else if (keypressed & MASK_JOY2_RIGHT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ILI");
#endif
gfx_mode = CFG_ILI;
}
}
if (gfx_mode == CFG_VGA) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
else
{
tft.begin(gfx_mode == CFG_ILI?MODE_TFTILI_320x240:MODE_TFTST_320x240);
}
#endif
if (keypressed & MASK_JOY2_DOWN) { if (keypressed & MASK_JOY2_DOWN) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig(); emu_eraseConfig();
delay(1000); delay(1000);
#endif
} }
else { else {
#ifdef FILEBROWSER
if (emu_readConfig()) { if (emu_readConfig()) {
autorun = true; autorun = true;
} }
#endif
} }
#ifdef FILEBROWSER
toggleMenu(true); toggleMenu(true);
#endif
} }
void emu_start(void) void emu_start(int vblms, void * callback, int forcetimervsync)
{ {
vgatimervsync = forcetimervsync?true:false;
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startRefresh();
if (callback != nullptr) {
vblCallback = callback;
}
myTimer.begin(vblCount, vblms);
#ifdef HAS_SND
emu_sndInit();
#endif
usbnavpad = 0; usbnavpad = 0;
} }

View file

@ -2,127 +2,14 @@
#define EMUAPI_H #define EMUAPI_H
#include "platform_config.h" #include "platform_config.h"
#include "emucfg.h"
#define CUSTOM_SND 1
//#define TIMER_REND 1
#define EXTRA_HEAP 0x10
// Title: < >
#define TITLE " Emulator "
#define ROMSDIR "/c64"
#define emu_Init(ROM1,ROM2) {uae_Start(ROM1,ROM2);}
#define emu_Init2() {uae_Init();}
#define emu_Step(x) {uae_Step();}
#define emu_Input(x) {uae_Input(x);}
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 1
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define R32(rgb) ((rgb>>16)&0xff)
#define G32(rgb) ((rgb>>8)&0xff)
#define B32(rgb) (rgb & 0xff)
#define ACTION_NONE 0 #define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16 #define ACTION_RUN1 1
#define ACTION_EXITKBD 128 #define ACTION_RUN2 2
#define ACTION_RUN1 129
#define ACTION_RUN2 130
#define ACTION_RUN3 131
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"qwertyuiop\x1a"
#define keylables_map0_1 (char *)" asdfghjkl\x19"
#define keylables_map0_2 (char *)" zxcvbnm,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'q','w','e','r','t','y','u','i','o','p',157, //lowecase
0,'a','s','d','f','g','h','j','k','l',0x0D,
0,'z','x','c','v','b','n','m',',','.',';','/',
145,157,29,17,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"QWERTYUIOP@"
#define keylables_map1_1 (char *)" ASDFGHJKL\x19"
#define keylables_map1_2 (char *)" ZXCVBNM<>:?"
#define keylables_map1_3 (char *)" =\x10_"
const unsigned short key_map1[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',0x0D,
0,'Z','X','C','V','B','N','M','<','>',':','?',
145,157,29,17,
0,'=',' ','_'
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" |\\[]{}' "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, '|','\\','[',']','{','}','\'',0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"1234567890 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit 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,0,0,
0,0,' ',0
};
#define keylables_map4_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map4_1 (char *)" "
#define keylables_map4_2 (char *)" "
#define keylables_map4_3 (char *)" "
const unsigned short key_map4[] = {
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,
0,0,0,0,
0,0,' ',0
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra 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,0,0,
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#define FORCE_VGATIMERVSYNC 1
#define SUPPORT_HIRES 1
#define MASK_JOY2_RIGHT 0x0001 #define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002 #define MASK_JOY2_LEFT 0x0002
@ -139,21 +26,25 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_BTN 0x1000 #define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000 #define MASK_KEY_USER4 0x2000
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
extern void emu_init(int hires=0);
extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif #endif
extern void emu_init(void);
extern void emu_start(void);
extern void emu_printf(const char * text); extern void emu_printf(const char * text);
extern void emu_printi(int val); extern void emu_printi(int val);
extern void emu_printh(int val); extern void emu_printh(int val);
extern void * emu_Malloc(unsigned int size); extern void * emu_Malloc(unsigned int size);
extern void * emu_MallocI(unsigned int size); extern void * emu_MallocI(unsigned int size);
extern void emu_Free(void * pt); extern void emu_Free(void * pt);
extern void * emu_SMalloc(unsigned int size);
extern void emu_SFree(void * pt);
extern int emu_FileOpen(const char * filepath, const char * mode); extern int emu_FileOpen(const char * filepath, const char * mode);
extern int emu_FileRead(void * buf, int size, int handler); extern int emu_FileRead(void * buf, int size, int handler);
extern int emu_FileWrite(void * buf, int size, int handler);
extern int emu_FileGetc(int handler); extern int emu_FileGetc(int handler);
extern int emu_FileSeek(int handler, int seek, int origin); extern int emu_FileSeek(int handler, int seek, int origin);
extern int emu_FileTell(int handler); extern int emu_FileTell(int handler);
@ -164,24 +55,23 @@ extern unsigned int emu_LoadFile(const char * filepath, void * buf, int size);
extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek); extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek);
extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index); extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index);
extern void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride); extern void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line); extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line);
extern void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride);
extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line); extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line);
extern void emu_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void); extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void); extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line); extern int emu_IsVga(void);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta); extern int emu_IsVgaHires(void);
extern bool menuActive(void); extern int menuActive(void);
extern char * menuSelection(void); extern char * menuSelection(void);
extern char * menuSecondSelection(void); extern char * menuSecondSelection(void);
extern void toggleMenu(bool on); extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick); extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void); extern int handleOSKB(void);
extern void toggleOSKB(bool forceon); extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void); extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly); extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ extern int emu_ReadKeys(void);
extern int emu_GetPad(void); extern int emu_GetPad(void);
extern int emu_GetMouse(int *x, int *y, int *buts); extern int emu_GetMouse(int *x, int *y, int *buts);
extern int emu_MouseDetected(void); extern int emu_MouseDetected(void);
extern int emu_GetJoystick(void);
extern int emu_KeyboardDetected(void); extern int emu_KeyboardDetected(void);
extern int emu_ReadAnalogJoyX(int min, int max); extern int emu_ReadAnalogJoyX(int min, int max);
extern int emu_ReadAnalogJoyY(int min, int max); extern int emu_ReadAnalogJoyY(int min, int max);

View file

@ -0,0 +1,108 @@
#ifndef EMUCFG_H
#define EMUCFG_H
// Title: < >
#define TITLE " XXXX Emulator "
#define ROMSDIR "snes"
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
//#define CUSTOM_SND 1
//#define TIMER_REND 1
//#define EXTPAD 1
#define EXTRA_HEAP 0x10
#define FILEBROWSER 1
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"QWERTYUIOP\x1a"
#define keylables_map0_1 (char *)" ASDFGHJKL\x19"
#define keylables_map0_2 (char *)" ZXCVBNM,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'Q','W','E','R','T','Y','U','I','O','P',157, //default C64 uppercase always
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
#define keylables_map1_3 (char *)" "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit 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,0,0,
0,0,' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
153,151,150,152, //U L R D
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
129,130,131,132,133,134,135,136,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,0,0,
0,0,' ',0
};
#define keylables_map4_0 (char *)"QWERTYUIOP@"
#define keylables_map4_1 (char *)" ASDFGHJKL\x19"
#define keylables_map4_2 (char *)" ZXCVBNM<>:?"
#define keylables_map4_3 (char *)" =\x10_"
const unsigned short key_map4[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M','<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#endif

View file

@ -4,27 +4,32 @@
#define TEECOMPUTER 1 #define TEECOMPUTER 1
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
#define TFTSPI1 1
//#define ILI9341 1 //#define HAS_T4_VGA 1
//#define ST7789 1 #define HAS_SND 1
//#define TFTSPI1 1 #define HAS_USB 1
#define HAS_T4_VGA 1
//#define HIRES 1
//#define HAS_SND 1
//#define HAS_USBKEY 1 //#define HAS_USBKEY 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
//#define HAS_USBJOY 1 // not working yet
#define PT8211 1
#else #else
#define HAS_T4_VGA 1 #define HAS_T4_VGA 1
#define HIRES 1
//#define INVX 1 //#define INVX 1
#define INVY 1 #define INVY 1
//#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
//#define HAS_USBKEY 1 //#define HAS_USBKEY 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
//#define HAS_USBJOY 1 // not working yet
#endif #endif
//#define FLIP_SCREEN 1
//#define ILI9341 1 //#define ILI9341 1
//#define ST7789 1 //#define ST7789 1
//#define SWAP_JOYSTICK 1 //#define SWAP_JOYSTICK 1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
/*
TFT/VGA driver
DMA TFT driver based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _T4_DSPH_
#define _T4_DSPH_
#ifdef __cplusplus
#include <Arduino.h>
#include <DMAChannel.h>
#endif
#include "platform_config.h"
#include "iopins.h"
#ifndef TFT_WIDTH
#define TFT_WIDTH 320
#endif
#define TFT_REALWIDTH 320
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 240
#endif
#define TFT_REALHEIGHT 240
typedef enum gfx_mode_t
{
MODE_UNDEFINED = 0,
MODE_TFTILI_320x240 = 1,
MODE_TFTST_320x240 = 2,
MODE_VGA_320x240 = 3,
MODE_VGA_320x480 = 4,
MODE_VGA_352x240 = 5,
MODE_VGA_352x480 = 6,
MODE_VGA_512x240 = 7,
MODE_VGA_512x480 = 8,
MODE_VGA_640x240 = 9,
MODE_VGA_640x480 = 10
} gfx_mode_t;
typedef enum gfx_error_t
{
GFX_OK = 0,
GFX_ERROR = -1
} gfx_error_t;
#ifdef __cplusplus
class T4_DSP
{
public:
T4_DSP();
gfx_error_t begin(gfx_mode_t mode);
gfx_mode_t getMode(void);
void startRefresh(void);
void stopRefresh();
int get_frame_buffer_size(int *width, int *height);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
// wait next Vsync
void waitSync();
void waitLine(int line);
// NoDMA functions
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
void writeLine(int width, int height, int y, uint16_t *buf);
void writeLinePal(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
void writeScreenPal(int width, int height, int stride, uint8_t *buf, uint16_t *palette16);
void writeLine8(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
protected:
static uint8_t _rst, _cs, _dc;
static uint8_t _mosi, _sclk;
static uint8_t _vsync_pin;
static DMAChannel flexio1DMA;
static DMAChannel flexio2DMA;
void tft_setup(bool isST);
static void TFT_isr(void);
static void QT3_isr(void);
};
#endif
#endif

View file

@ -1,217 +1,94 @@
#include "emuapi.h" #include "emuapi.h"
#include "iopins.h" #include "iopins.h"
#ifdef HAS_T4_VGA #include "t4_dsp.h"
#include "vga_t_dma.h" extern T4_DSP tft;
TFT_T_DMA tft;
#else
#include "tft_t_dma.h"
TFT_T_DMA tft = TFT_T_DMA(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO, TFT_TOUCH_CS, TFT_TOUCH_INT);
#endif
bool vgaMode = false;
static unsigned char palette8[PALETTE_SIZE];
static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
static int skip=0;
static elapsedMicros tius;
#define BLUE RGBVAL16(0, 0, 170) #define BLUE RGBVAL16(0, 0, 170)
#define LIGHT_BLUE RGBVAL16(0, 136, 255) #define LIGHT_BLUE RGBVAL16(0, 136, 255)
static int fb_width, fb_height; static int fb_width, fb_height;
static const char * digits = "0123456789ABCDEF"; static const char * digits = "0123456789ABCDEF";
static int hk = 0;
static int prevhk = 0; static int prevhk = 0;
static int col=0; static int col=0;
static int row=0; static int row=0;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
uint16_t bClick = emu_DebounceLocalKeys();
hk = emu_ReadI2CKeyboard();
//emu_Input(bClick);
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
palette8[index] = RGBVAL8(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.waitSync();
#else
while (vbl==vb) {};
#endif
}
}
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.writeLine(width,1,line, VBuf, palette8);
#else
tft.writeLine(width,1,line, VBuf, palette16);
#endif
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifndef HAS_T4_VGA
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8);
#else
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
#endif
}
}
}
void emu_CopyLine(int width, int height, int ysrc, int ydst)
{
#ifdef HAS_T4_VGA
tft.copyLine(width,height,ysrc,ydst);
#endif
}
int emu_FrameSkip(void)
{
return skip;
}
void * emu_LineBuffer(int line)
{
if (!vgaMode) {
return (void*)tft.getLineBuffer(line);
}
}
void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta) {
#ifdef HAS_T4_VGA
tft.tweak_video(shiftdelta, numdelta, denomdelta);
#endif
}
// **************************************************** // ****************************************************
// the setup() method runs once, when the sketch starts // the setup() method runs once, when the sketch starts
// **************************************************** // ****************************************************
void setup() { void setup() {
emu_init();
#ifdef HAS_T4_VGA char * filename;
#ifdef HIRES #ifdef FILEBROWSER
tft.begin(VGA_MODE_640x480); while (true) {
#else if (menuActive()) {
tft.begin(VGA_MODE_320x240); uint16_t bClick = emu_DebounceLocalKeys();
#endif int action = handleMenu(bClick);
//NVIC_SET_PRIORITY(IRQ_QTIMER3, 0); filename = menuSelection();
#else if (action == ACTION_RUN1) {
tft.begin(); break;
#endif }
delay(20);
emu_init(); }
emu_start(); }
tft.fillScreenNoDma(LIGHT_BLUE); #endif
emu_start(20000,nullptr,1);
tft.fillScreen(LIGHT_BLUE);
tft.get_frame_buffer_size(&fb_width, &fb_height); tft.get_frame_buffer_size(&fb_width, &fb_height);
tft.drawRectNoDma((fb_width-320)/2,(fb_height-200)/2, 320,200, BLUE); tft.drawRect((fb_width-320)/2,(fb_height-200)/2, 320,200, BLUE);
myTimer.begin(vblCount, 20000); //to run every 20ms
toggleOSKB(true); toggleOSKB(true);
} }
void loop(void) void loop(void)
{ {
char buf[5] = {0,0,0,0,0}; char buf[5] = {0,0,0,0,0};
/*
uint16_t bClick = emu_GetPad(); uint16_t bClick = emu_GetPad();
buf[0] = digits[(bClick>>12)&0xf]; buf[0] = digits[(bClick>>12)&0xf];
buf[1] = digits[(bClick>>8)&0xf]; buf[1] = digits[(bClick>>8)&0xf];
buf[2] = digits[(bClick>>4)&0xf]; buf[2] = digits[(bClick>>4)&0xf];
buf[3] = digits[bClick&0xf]; buf[3] = digits[bClick&0xf];
tft.drawTextNoDma(4*8,0,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),false); tft.drawText(4*8,0,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),false);
buf[3] = 0; buf[3] = 0;
int key = emu_ReadI2CKeyboard(); int key = emu_ReadI2CKeyboard();
buf[0] = digits[(key>>8)&0xf]; buf[0] = digits[(key>>8)&0xf];
buf[1] = digits[(key>>4)&0xf]; buf[1] = digits[(key>>4)&0xf];
buf[2] = digits[key&0xf]; buf[2] = digits[key&0xf];
tft.drawTextNoDma(4*8,8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),false); tft.drawText(4*8,8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),false);
buf[2] = 0; buf[2] = 0;
key = emu_ReadI2CKeyboard2(0); key = emu_ReadI2CKeyboard2(0);
buf[0] = digits[(key>>4)&0xf]; buf[0] = digits[(key>>4)&0xf];
buf[1] = digits[key&0xf]; buf[1] = digits[key&0xf];
tft.drawTextNoDma(9*8+0*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); tft.drawText(9*8+0*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
key = emu_ReadI2CKeyboard2(1); key = emu_ReadI2CKeyboard2(1);
buf[0] = digits[(key>>4)&0xf]; buf[0] = digits[(key>>4)&0xf];
buf[1] = digits[key&0xf]; buf[1] = digits[key&0xf];
tft.drawTextNoDma(9*8+1*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); tft.drawText(9*8+1*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
key = emu_ReadI2CKeyboard2(2); key = emu_ReadI2CKeyboard2(2);
buf[0] = digits[(key>>4)&0xf]; buf[0] = digits[(key>>4)&0xf];
buf[1] = digits[key&0xf]; buf[1] = digits[key&0xf];
tft.drawTextNoDma(9*8+2*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); tft.drawText(9*8+2*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
key = emu_ReadI2CKeyboard2(3); key = emu_ReadI2CKeyboard2(3);
buf[0] = digits[(key>>4)&0xf]; buf[0] = digits[(key>>4)&0xf];
buf[1] = digits[key&0xf]; buf[1] = digits[key&0xf];
tft.drawTextNoDma(9*8+3*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); tft.drawText(9*8+3*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
key = emu_ReadI2CKeyboard2(4); key = emu_ReadI2CKeyboard2(4);
buf[0] = digits[(key>>4)&0xf]; buf[0] = digits[(key>>4)&0xf];
buf[1] = digits[key&0xf]; buf[1] = digits[key&0xf];
tft.drawTextNoDma(9*8+4*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); tft.drawText(9*8+4*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
key = emu_ReadI2CKeyboard2(5); key = emu_ReadI2CKeyboard2(5);
buf[0] = digits[(key>>4)&0xf]; buf[0] = digits[(key>>4)&0xf];
buf[1] = digits[key&0xf]; buf[1] = digits[key&0xf];
tft.drawTextNoDma(9*8+5*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true); tft.drawText(9*8+5*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
*/
handleOSKB(); bClick = emu_DebounceLocalKeys();
int hk = hk = emu_ReadI2CKeyboard();
//handleOSKB();
if ( (hk != 0) && (hk < 128) ) { if ( (hk != 0) && (hk < 128) ) {
buf[0] = (char)(hk&0xff); buf[0] = (char)(hk&0xff);
buf[1] = 0; buf[1] = 0;
tft.drawTextNoDma(col*8,(row+3)*8,buf,LIGHT_BLUE,BLUE,false); tft.drawText(col*8,(row+3)*8,buf,LIGHT_BLUE,BLUE,false);
col += 1; col += 1;
if (col >= 40) { if (col >= 40) {
col=0; col=0;
@ -231,67 +108,3 @@ void loop(void)
delay(20); delay(20);
} }
// ****************************************************
// the loop() method runs continuously
// ****************************************************
void loop2(void)
{
if (menuActive()) {
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
char * floppy1 = menuSelection();
if (action == ACTION_RUN1) {
toggleMenu(false);
vgaMode = false;
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
}
delay(20);
}
else {
uint16_t bClick = 0; //emu_DebounceLocalKeys();
}
}
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
#ifdef HAS_T4_VGA
tft.begin_audio(256, mymixer.snd_Mixer);
#else
mymixer.begin_audio(256, mymixer.snd_Mixer);
#endif
// sgtl5000_1.enable();
// sgtl5000_1.volume(0.6);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,234 +0,0 @@
/*
Based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _TFT_T_DMAH_
#define _TFT_T_DMAH_
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include <DMAChannel.h>
#endif
#include "tft_t_dma_config.h"
#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b )
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define R16(rgb) ((rgb>>8)&0xf8)
#define G16(rgb) ((rgb>>3)&0xfc)
#define B16(rgb) ((rgb<<3)&0xf8)
#define PAL_COLOR_MASK 0xff
#ifdef LOHRES
#define TFT_WIDTH 240
#define TFT_REALWIDTH 240
#else
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#endif
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
//#define WIDTH 272
//#define HEIGHT 228
#define LINES_PER_BLOCK 64
#define NR_OF_BLOCK 4
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
#ifdef ILI9341
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0D
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_MH 0x04
#define TFT_CASET ILI9341_CASET
#define TFT_PASET ILI9341_PASET
#define TFT_RAMWR ILI9341_RAMWR
#define TFT_MADCTL ILI9341_MADCTL
#endif
#ifdef ST7789
#define ST7735_NOP 0x00
#define ST7735_SWRESET 0x01
#define ST7735_RDDID 0x04
#define ST7735_RDDST 0x09
#define ST7735_SLPIN 0x10
#define ST7735_SLPOUT 0x11
#define ST7735_PTLON 0x12
#define ST7735_NORON 0x13
#define ST7735_INVOFF 0x20
#define ST7735_INVON 0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_RAMRD 0x2E
#define ST7735_PTLAR 0x30
#define ST7735_COLMOD 0x3A
#define ST7735_MADCTL 0x36
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_DISSET5 0xB6
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_RDID1 0xDA
#define ST7735_RDID2 0xDB
#define ST7735_RDID3 0xDC
#define ST7735_RDID4 0xDD
#define ST7735_PWCTR6 0xFC
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_MADCTL_BGR 0x08
#define ST77XX_MADCTL_MH 0x04
#define TFT_CASET ST7735_CASET
#define TFT_PASET ST7735_RASET
#define TFT_RAMWR ST7735_RAMWR
#define TFT_MADCTL ST7735_MADCTL
#endif
#ifdef __cplusplus
class TFT_T_DMA
{
public:
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
void begin(void);
void flipscreen(bool flip);
boolean isflipped(void);
void startDMA(void);
void stopDMA();
int get_frame_buffer_size(int *width, int *height);
// Touch screen functions
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
// NoDMA functions
void writeScreenNoDma(const uint16_t *pcolors);
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
uint16_t * getLineBuffer(int j);
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int y, uint16_t *buf);
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
protected:
uint8_t _rst, _cs, _dc;
uint8_t _miso, _mosi, _sclk;
uint8_t _touch_irq=255, _touch_cs=255;
bool flipped=false;
void wait(void);
void enableTouchIrq();
};
#endif
#endif

View file

@ -1,14 +0,0 @@
#include "platform_config.h"
//#define ST7789 1
//#define ILI9341 1
#define TFT_LINEARINT 1
#define LINEARINT_HACK 1
//#define FLIP_SCREEN 1
//#define TFT_DEBUG 1
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
//#define TFT_STATICFB 1
#endif

View file

@ -1,57 +0,0 @@
/*
Wrapping class to extend VGA_T4 to TFT_T_DMA
*/
#ifndef _VGA_T_DMAH_
#define _VGA_T_DMAH_
#ifdef __cplusplus
#include <VGA_t4.h>
#endif
#define RGBVAL16(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#ifdef HIRES
#define TFT_WIDTH 640
#define TFT_REALWIDTH 640
#else
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#endif
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
#ifdef __cplusplus
class TFT_T_DMA: public VGA_T4
{
public:
// Fake touch screen functions
bool isTouching(void) { return false; }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { }
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { };
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax) { }
// fake DMA functions
void startDMA(void) { };
void stopDMA(void) { };
// fake no DMA functions
void writeScreenNoDma(const vga_pixel *pcolors) { writeScreen(pcolors); }
void fillScreenNoDma(vga_pixel color) { clear(color); }
void drawTextNoDma(int16_t x, int16_t y, const char * text, vga_pixel fgcolor, vga_pixel bgcolor, bool doublesize) { drawText(x,y,text,fgcolor,bgcolor,doublesize); }
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, vga_pixel color) { drawRect(x, y, w, h, color); }
void drawSpriteNoDma(int16_t x, int16_t y, const int16_t *bitmap) { drawSprite(x, y, bitmap); }
void drawSpriteNoDma(int16_t x, int16_t y, const int16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh) { drawSprite(x, y, bitmap, croparx, cropary, croparw, croparh); }
};
#endif
#endif

View file

@ -5,18 +5,10 @@ extern "C" {
#include "platform_config.h" #include "platform_config.h"
} }
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
typedef uint8_t Pixel;
#else
#include "tft_t_dma.h"
typedef uint16_t Pixel; typedef uint16_t Pixel;
#endif
#define WIN_W TFT_WIDTH #define WIN_W 320 //TFT_WIDTH
#define WIN_H TFT_HEIGHT #define WIN_H 240 //TFT_HEIGHT
//#include <stdio.h>
// definitions for easy access to registers // definitions for easy access to registers
@ -70,6 +62,8 @@ static uint16_t remap[16] = {
0x1c00 0x1c00
}; };
static Pixel linebuf[WIN_W];
MOS6561::MOS6561() : IC(), curRow(0), frameReady(true) { MOS6561::MOS6561() : IC(), curRow(0), frameReady(true) {
// Set clock speed // Set clock speed
this->setClockSpeed(1108000); this->setClockSpeed(1108000);
@ -102,10 +96,11 @@ void MOS6561::initialize() {
void MOS6561::renderBorder(uint16_t raster){ void MOS6561::renderBorder(uint16_t raster){
if (raster < WIN_H) { if (raster < WIN_H) {
Pixel bcol = vicPalette[REG_BORDER_COLOUR]; Pixel bcol = vicPalette[REG_BORDER_COLOUR];
Pixel * dst = (Pixel *)emu_LineBuffer(raster); Pixel * dst = &linebuf[0];
for (int x=0; x < WIN_W; x++) { for (int x=0; x < WIN_W; x++) {
*dst++ = bcol; *dst++ = bcol;
} }
emu_DrawLine16(&linebuf[0], WIN_W, WIN_H, raster);
} }
} }
@ -137,7 +132,7 @@ void MOS6561::renderLine(uint16_t raster, uint16_t row, uint8_t rowHeight, uint8
cols[bakcol] = vicPalette[REG_BACKGROUND_COLOUR]; cols[bakcol] = vicPalette[REG_BACKGROUND_COLOUR];
// Border Left // Border Left
Pixel * dst = (Pixel *)emu_LineBuffer(raster); Pixel * dst = &linebuf[0];
for (int x=0; x < bWidth; x++) { for (int x=0; x < bWidth; x++) {
*dst++ = cols[borcol]; *dst++ = cols[borcol];
} }
@ -179,7 +174,8 @@ void MOS6561::renderLine(uint16_t raster, uint16_t row, uint8_t rowHeight, uint8
// Border Right // Border Right
for (int x=0; x < bWidth; x++) { for (int x=0; x < bWidth; x++) {
*dst++ = cols[borcol]; *dst++ = cols[borcol];
} }
emu_DrawLine16(&linebuf[0], WIN_W, 1, raster);
} }
} }
@ -214,7 +210,7 @@ void MOS6561::renderRow(uint16_t raster, uint16_t row, uint8_t rowHeight)
for (int line=0; line < rowHeight; line++) { for (int line=0; line < rowHeight; line++) {
// Border Left // Border Left
Pixel * dst = (Pixel *)emu_LineBuffer(curRow*rowHeight+line+raster); Pixel * dst = &linebuf[0];
for (int x=0; x < bWidth; x++) { for (int x=0; x < bWidth; x++) {
*dst++ = cols[borcol]; *dst++ = cols[borcol];
} }
@ -230,25 +226,25 @@ void MOS6561::renderRow(uint16_t raster, uint16_t row, uint8_t rowHeight)
uint8_t multiColour = colPointer[x] & 0x8; uint8_t multiColour = colPointer[x] & 0x8;
cols[forcol] = vicPalette[colour]; cols[forcol] = vicPalette[colour];
if (!multiColour) { if (!multiColour) {
Pixel * dest = dst; Pixel * dest = dst;
for (int a = 0; a < 8; a++) { for (int a = 0; a < 8; a++) {
if ((characterByte << a) & 0x80) { if ((characterByte << a) & 0x80) {
*dest++ = cols[forcol]; *dest++ = cols[forcol];
} }
else { else {
*dest++ = cols[bakcol]; *dest++ = cols[bakcol];
} }
} }
} }
else { else {
Pixel * dest = dst; Pixel * dest = dst;
cols[auxcol] = vicPalette[REG_AUXILIARY_COLOUR]; cols[auxcol] = vicPalette[REG_AUXILIARY_COLOUR];
for (int a = 0; a < 8; a += 2) { for (int a = 0; a < 8; a += 2) {
// Set colour // Set colour
Pixel col = cols[((characterByte << a) & 0xC0) >> 6]; Pixel col = cols[((characterByte << a) & 0xC0) >> 6];
*dest++ = col; *dest++ = col;
*dest++ = col; *dest++ = col;
} }
} }
dst +=8; dst +=8;
} }
@ -256,7 +252,8 @@ void MOS6561::renderRow(uint16_t raster, uint16_t row, uint8_t rowHeight)
// Border Right // Border Right
for (int x=0; x < bWidth; x++) { for (int x=0; x < bWidth; x++) {
*dst++ = cols[borcol]; *dst++ = cols[borcol];
} }
emu_DrawLine16(&linebuf[0], WIN_W, 1, curRow*rowHeight+line+raster);
} }
} }
} }

View file

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#ifdef HAS_T4_VGA #include <Arduino.h>
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#ifdef HAS_USBKEY #ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info #include "USBHost_t36.h" // Read this header first for key info
USBHost myusb; USBHost myusb;
USBHub hub1(myusb); USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb); KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb); USBHIDParser hid1(myusb);
MouseController mouse1(myusb); MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb); MIDIDevice midi1(myusb);
#endif #endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void); static bool emu_writeConfig(void);
static bool emu_readConfig(void); static bool emu_readConfig(void);
static bool emu_eraseConfig(void); static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false; static bool mouseDetected = false;
static bool keyboardDetected = false; static bool keyboardDetected = false;
@ -34,12 +40,13 @@ static File file;
#define MAX_FILES 64 #define MAX_FILES 64
#define AUTORUN_FILENAME "autorun.txt" #define AUTORUN_FILENAME "autorun.txt"
#define GFX_CFG_FILENAME "gfxmode.txt"
#define MAX_FILENAME_SIZE 24 #define MAX_FILENAME_SIZE 34
#define MAX_MENULINES 9 #define MAX_MENULINES 9
#define TEXT_HEIGHT 16 #define TEXT_HEIGHT 16
#define TEXT_WIDTH 8 #define TEXT_WIDTH 8
#define MENU_FILE_XOFFSET (6*TEXT_WIDTH) #define MENU_FILE_XOFFSET (2*TEXT_WIDTH)
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT) #define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH) #define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT) #define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
@ -53,7 +60,8 @@ static File file;
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft; #include "t4_dsp.h"
T4_DSP tft;
static int nbFiles=0; static int nbFiles=0;
static int curFile=0; static int curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]=""; static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true; static bool menuRedraw=true;
static bool autorun=false; static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys; static const unsigned short * keys;
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
@ -158,6 +168,29 @@ void emu_Free(void * pt)
free(pt); free(pt);
} }
#define SMEMPOOL (0x800000)
EXTMEM static unsigned char slowmem[SMEMPOOL];
static int slowmempt = 0;
void * emu_SMalloc(unsigned int size)
{
void * mem = (void*)&slowmem[slowmempt];
slowmempt += size;
if ( slowmempt > SMEMPOOL ) {
mem = NULL;
emu_printf("failure to allocate slow");
}
else {
emu_printf("could allocate slow static ");
emu_printf(size);
}
return mem;
}
void emu_SFree(void * pt)
{
}
/******************************** /********************************
* Input and keyboard * Input and keyboard
********************************/ ********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif #endif
if ( row & 0x02 ) retval |= MASK_JOY2_BTN; if ( row & 0x02 ) retval |= MASK_JOY2_BTN;
#ifdef EXTPAD
if ( sh_pressed ) retval |= MASK_KEY_USER3;
if ( fn_pressed ) retval |= MASK_KEY_USER1;
digitalWrite(KLED, 0);
#else
// Handle LED flash // Handle LED flash
uint32_t time_ms=millis(); uint32_t time_ms=millis();
if ((time_ms-last_t_ms) > 100) { if ((time_ms-last_t_ms) > 100) {
@ -412,8 +451,9 @@ int emu_ReadKeys(void)
if ( key_fn ) retval |= MASK_KEY_USER2; if ( key_fn ) retval |= MASK_KEY_USER2;
if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1; if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) ) if ( (fn_pressed) && (sh_pressed) )
#else #else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) ) || (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) { while (true) {
; ;
} }
#endif #endif
} }
emu_GetJoystick();
return (retval); return (retval);
} }
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
} }
int emu_GetMouse(int *x, int *y, int *buts) { int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) { if (mouse1.available()) {
*buts = mouse1.getButtons(); *buts = mouse1.getButtons();
*x = mouse1.getMouseX(); *x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
return 0; return 0;
} }
#ifdef HAS_USBKEY int emu_GetJoystick(void) {
#if defined(HAS_USB) && (HAS_USBJOY)
for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++) {
if (joysticks[joystick_index].available()) {
uint64_t axis_mask = joysticks[joystick_index].axisMask();
uint64_t axis_changed_mask = joysticks[joystick_index].axisChangedMask();
uint32_t buttons = joysticks[joystick_index].getButtons();
Serial.printf("Joystick(%d): buttons = %x", joystick_index, buttons);
Serial.println();
}
}
return 1;
#endif
return 0;
}
#if defined(HAS_USB) && (HAS_USBKEY)
void OnPress(auto key) void OnPress(auto key)
{ {
keyboardDetected = true; keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0); return (keyboardDetected?1:0);
} }
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16]; static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0; static unsigned char midiLastCmd=0;
static int midiDataCnt=0; static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif #endif
void emu_MidiOnDataReceived(unsigned char value) { void emu_MidiOnDataReceived(unsigned char value) {
#if defined(HAS_USB) && (HAS_USBMIDI)
#ifdef HAS_USBKEY
//Serial.println(value, HEX); //Serial.println(value, HEX);
//10000000 = 128 = note off //10000000 = 128 = note off
//10010000 = 144 = note on //10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/******************************** /********************************
* Menu file loader UI * Menu file loader UI
********************************/ ********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) { static int readNbFiles(void) {
int totalFiles = 0; int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles; return totalFiles;
} }
void backgroundMenu(void) { void backgroundMenu(void) {
menuRedraw=true; menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick) int handleMenu(uint16_t bClick)
{ {
if (autorun) { if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1); return (ACTION_RUN1);
} }
int action = ACTION_NONE; int action = ACTION_NONE;
if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) ) { if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) || ( bClick & MASK_KEY_USER2 ) ) {
char newpath[MAX_FILENAME_PATH]; char newpath[MAX_FILENAME_PATH];
strcpy(newpath, selection); strcpy(newpath, selection);
strcat(newpath, "/"); strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection); File file = SD.open(selection);
if (file.isDirectory()) { if (file.isDirectory()) {
curFile = 0; curFile = 0;
nbFiles = readNbFiles(); nbFiles = readNbFiles();
menuRedraw=true;
} }
else { else
action = ACTION_RUN1; {
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
if (key_extmode) { if ( (key_extmode) || ( key_sh) ) {
emu_writeConfig(); emu_writeConfig();
} }
if ( tft.getMode() < MODE_VGA_320x240) {
if ( bClick & MASK_KEY_USER2 ) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
}
//emu_SwapJoysticks(0);
#endif #endif
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
} }
menuRedraw=true;
} }
else if ( bClick & MASK_KEY_USER1 ) { else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true; menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/"); strcat(second_selection, "/");
strcat(second_selection, second_selected_filename); strcat(second_selection, second_selected_filename);
action = ACTION_RUN2; action = ACTION_RUN2;
} }
else if ( bClick & MASK_KEY_USER2 ) {
menuRedraw=true;
//action = ACTION_RUN3;
emu_SwapJoysticks(0);
}
else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) { else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) {
if (curFile!=0) { if (curFile!=0) {
menuRedraw=true; menuRedraw=true;
curFile--; curFile--;
} }
} }
else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) { else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) {
if ((curFile-9)>=0) { if ((curFile-9)>=0) {
menuRedraw=true; menuRedraw=true;
curFile -= 9; curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
menuRedraw=true; menuRedraw=true;
} }
} }
else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) { else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) {
if ((curFile<(nbFiles-9)) && (nbFiles)) { if ((curFile<(nbFiles-9)) && (nbFiles)) {
curFile += 9; curFile += 9;
menuRedraw=true; menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action); return (action);
} }
bool menuActive(void) int menuActive(void)
{ {
return (menuOn); return (menuOn?1:0);
} }
void toggleMenu(bool on) { void toggleMenu(int on) {
if (on) { if (on) {
menuOn=true; menuOn=true;
backgroundMenu(); backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{ {
return (second_selection); return (second_selection);
} }
#endif
/******************************** /********************************
* OSKB handling * OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0}; char c[4] = {' ',0,' ',0};
const char * cpt = str; const char * cpt = str;
int i=0; int i=0;
int fb_width,fb_height; int fb_width,fb_height,fbstride;
tft.get_frame_buffer_size(&fb_width, &fb_height);
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0); int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0); int line = row + (bottom?2:0);
while ((c[1] = *cpt++)) while ((c[1] = *cpt++))
@ -1150,7 +1218,7 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0); 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); else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff); if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false); tft.drawText(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false);
i++; i++;
} }
} }
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval; return retval;
} }
void toggleOSKB(bool forceon) { void toggleOSKB(int forceon) {
if (forceon) { if (forceon) {
oskbOn = true; oskbOn = true;
drawOSKB(); drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#endif #endif
} }
int emu_FileWrite(void * buf, int size, int handler)
{
// emu_printf("emu_FileWrite");
// emu_printi(handler);
#ifdef HCFH
return (file.write(buf, size));
#else
return (getFileHandler(handler).write(buf, size));
#endif
}
int emu_FileGetc(int handler) { int emu_FileGetc(int handler) {
// emu_printf("FileGetc"); // emu_printf("FileGetc");
// emu_printi(handler); // emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize); emu_printf(filesize);
lofile.close(); lofile.close();
} }
else {
emu_printf("filesize failed");
}
return(filesize); return(filesize);
} }
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
SD.remove (ROMSDIR "/" AUTORUN_FILENAME); SD.remove (ROMSDIR "/" AUTORUN_FILENAME);
} }
static bool emu_writeGfxConfig(char * display_type)
{
bool retval = false;
SD.remove ("/" GFX_CFG_FILENAME);
if (strcmp(display_type, "VGA")) {
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_CREAT | O_WRITE)))
{
if (lofile.write(display_type, strlen(display_type)) != strlen(display_type)) {
emu_printf("GFX config write failed");
}
else {
retval = true;
}
lofile.close();
}
}
return retval;
}
#define CFG_VGA 0
#define CFG_ILI 1
#define CFG_ST 2
static int emu_readGfxConfig(void)
{
int retval = CFG_VGA; // No file = VGA
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_READ)))
{
unsigned int filesize = lofile.size();
if (filesize == 2) // "ST"
{
retval = CFG_ST;
}
else if (filesize == 3) // "ILI"
{
retval = CFG_ILI;
}
lofile.close();
}
return retval;
}
/******************************** /********************************
* File IO compatibility * File IO compatibility
********************************/ ********************************/
@ -1670,62 +1794,249 @@ FRESULT f_mkdir (const char* path)
/******************************** /********************************
* Initialization * GFX wrapper
********************************/ ********************************/
void emu_init(void) static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
volatile boolean vgatimervsync=false;
static void (*vblCallback)(void) = nullptr;
static int skip=0;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if ( tft.getMode() >= MODE_VGA_320x240 ) {
if (vgatimervsync) {
while (vbl==vb) {};
}
else {
tft.waitSync();
}
}
else {
while (vbl==vb) {};
}
if (vblCallback != nullptr) {
vblCallback();
}
}
void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride)
{
if (skip == 0) {
tft.writeScreenPal(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
}
}
void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLinePal(width,height,line, VBuf, palette16);
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine(width,height,line, VBuf);
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine8(width,height,line, VBuf, palette16);
}
}
int emu_IsVga(void)
{
return (tft.getMode() >= MODE_VGA_320x240?1:0);
}
int emu_IsVgaHires(void)
{
return (tft.getMode() >= MODE_VGA_640x240?1:0);
}
int emu_FrameSkip(void)
{
return skip;
}
/********************************
* AUDIO wrapper
********************************/
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif
/********************************
* Initialization
********************************/
void emu_init(int hires)
{ {
Serial.begin(115200); Serial.begin(115200);
vgahires = hires;
#ifdef HAS_USBKEY #ifdef HAS_USB
myusb.begin(); myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress); keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease); keyboard1.attachRelease(OnRelease);
#endif #endif
#endif
while (!SD.begin(SD_CS)) #ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{ {
Serial.println("SD begin failed, retrying..."); Serial.println("No SD card detected");
delay(1000);
} }
strcpy(selection,ROMSDIR); strcpy(selection,ROMSDIR);
FileHandlersInit(); FileHandlersInit();
nbFiles = readNbFiles(); nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles); Serial.println(nbFiles);
#endif
emu_InitJoysticks(); emu_InitJoysticks();
#ifdef SWAP_JOYSTICK #ifdef SWAP_JOYSTICK
joySwapped = true; joySwapped = true;
#else #else
joySwapped = false; joySwapped = false;
#endif #endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
int keypressed = emu_ReadKeys(); int keypressed = emu_ReadKeys();
#ifdef HAS_T4_VGA
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
#else
int gfx_mode = CFG_VGA; // default
#ifdef FILEBROWSER
gfx_mode = emu_readGfxConfig();
#endif
// Force VGA if UP pressed
if (keypressed & MASK_JOY2_UP)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("VGA");
#endif
gfx_mode = CFG_VGA;
}
else {
if (keypressed & MASK_JOY2_LEFT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ST");
#endif
gfx_mode = CFG_ST;
}
else if (keypressed & MASK_JOY2_RIGHT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ILI");
#endif
gfx_mode = CFG_ILI;
}
}
if (gfx_mode == CFG_VGA) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
else
{
tft.begin(gfx_mode == CFG_ILI?MODE_TFTILI_320x240:MODE_TFTST_320x240);
}
#endif
if (keypressed & MASK_JOY2_DOWN) { if (keypressed & MASK_JOY2_DOWN) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig(); emu_eraseConfig();
delay(1000); delay(1000);
#endif
} }
else { else {
#ifdef FILEBROWSER
if (emu_readConfig()) { if (emu_readConfig()) {
autorun = true; autorun = true;
} }
#endif
} }
#ifdef FILEBROWSER
toggleMenu(true); toggleMenu(true);
#endif
} }
void emu_start(void) void emu_start(int vblms, void * callback, int forcetimervsync)
{ {
vgatimervsync = forcetimervsync?true:false;
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startRefresh();
if (callback != nullptr) {
vblCallback = callback;
}
myTimer.begin(vblCount, vblms);
#ifdef HAS_SND
emu_sndInit();
#endif
usbnavpad = 0; usbnavpad = 0;
} }

View file

@ -2,126 +2,14 @@
#define EMUAPI_H #define EMUAPI_H
#include "platform_config.h" #include "platform_config.h"
#include "emucfg.h"
#define CUSTOM_SND 1
//#define TIMER_REND 1
#define EXTRA_HEAP 0x10
// Title: < >
#define TITLE " Vic20 Emulator "
#define ROMSDIR "v20"
#define emu_Init(ROM) { v20_Init(); v20_Start(ROM);}
#define emu_Step(x) { v20_Step(); }
#define emu_Input(x) { v20_Input(x); }
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define R32(rgb) ((rgb>>16)&0xff)
#define G32(rgb) ((rgb>>8)&0xff)
#define B32(rgb) (rgb & 0xff)
#define ACTION_NONE 0 #define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16 #define ACTION_RUN1 1
#define ACTION_EXITKBD 128 #define ACTION_RUN2 2
#define ACTION_RUN1 129
#define ACTION_RUN2 130
#define ACTION_RUN3 131
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"QWERTYUIOP\x1a"
#define keylables_map0_1 (char *)" ASDFGHJKL\x19"
#define keylables_map0_2 (char *)" ZXCVBNM,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'Q','W','E','R','T','Y','U','I','O','P',157, //default C64 uppercase always
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
#define keylables_map1_3 (char *)" "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit 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,0,0,
0,0,' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
153,151,150,152, //U L R D
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
129,130,131,132,133,134,135,136,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,0,0,
0,0,' ',0
};
#define keylables_map4_0 (char *)"QWERTYUIOP@"
#define keylables_map4_1 (char *)" ASDFGHJKL\x19"
#define keylables_map4_2 (char *)" ZXCVBNM<>:?"
#define keylables_map4_3 (char *)" =\x10_"
const unsigned short key_map4[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M','<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#define FORCE_VGATIMERVSYNC 1
#define SUPPORT_HIRES 1
#define MASK_JOY2_RIGHT 0x0001 #define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002 #define MASK_JOY2_LEFT 0x0002
@ -138,22 +26,25 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_BTN 0x1000 #define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000 #define MASK_KEY_USER4 0x2000
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
extern void emu_init(int hires=0);
extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif #endif
extern void emu_init(void);
extern void emu_start(void);
extern void emu_printf(const char * text); extern void emu_printf(const char * text);
extern void emu_printi(int val); extern void emu_printi(int val);
extern void emu_printh(int val); extern void emu_printh(int val);
extern void * emu_Malloc(unsigned int size); extern void * emu_Malloc(unsigned int size);
extern void * emu_MallocI(unsigned int size); extern void * emu_MallocI(unsigned int size);
extern void emu_Free(void * pt); extern void emu_Free(void * pt);
extern void * emu_SMalloc(unsigned int size);
extern void emu_SFree(void * pt);
extern int emu_FileOpen(const char * filepath, const char * mode); extern int emu_FileOpen(const char * filepath, const char * mode);
extern int emu_FileRead(void * buf, int size, int handler); extern int emu_FileRead(void * buf, int size, int handler);
extern int emu_FileWrite(void * buf, int size, int handler);
extern int emu_FileGetc(int handler); extern int emu_FileGetc(int handler);
extern int emu_FileSeek(int handler, int seek, int origin); extern int emu_FileSeek(int handler, int seek, int origin);
extern int emu_FileTell(int handler); extern int emu_FileTell(int handler);
@ -164,24 +55,23 @@ extern unsigned int emu_LoadFile(const char * filepath, void * buf, int size);
extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek); extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek);
extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index); extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index);
extern void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride); extern void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line); extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line);
extern void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride);
extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line); extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line);
extern void emu_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void); extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void); extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line); extern int emu_IsVga(void);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta); extern int emu_IsVgaHires(void);
extern bool menuActive(void); extern int menuActive(void);
extern char * menuSelection(void); extern char * menuSelection(void);
extern char * menuSecondSelection(void); extern char * menuSecondSelection(void);
extern void toggleMenu(bool on); extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick); extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void); extern int handleOSKB(void);
extern void toggleOSKB(bool forceon); extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void); extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly); extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ extern int emu_ReadKeys(void);
extern int emu_GetPad(void); extern int emu_GetPad(void);
extern int emu_GetMouse(int *x, int *y, int *buts); extern int emu_GetMouse(int *x, int *y, int *buts);
extern int emu_MouseDetected(void); extern int emu_MouseDetected(void);
extern int emu_GetJoystick(void);
extern int emu_KeyboardDetected(void); extern int emu_KeyboardDetected(void);
extern int emu_ReadAnalogJoyX(int min, int max); extern int emu_ReadAnalogJoyX(int min, int max);
extern int emu_ReadAnalogJoyY(int min, int max); extern int emu_ReadAnalogJoyY(int min, int max);

View file

@ -0,0 +1,115 @@
#ifndef EMUCFG_H
#define EMUCFG_H
#include "wrapemu.h"
// Title: < >
#define TITLE " Vic20 Emulator "
#define ROMSDIR "v20"
#define emu_Init(ROM) { v20_Init(); v20_Start(ROM);}
#define emu_Step(x) { v20_Step(); }
#define emu_Input(x) { v20_Input(x); }
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 16
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define CUSTOM_SND 1
//#define TIMER_REND 1
//#define EXTPAD 1
#define EXTRA_HEAP 0x10
#define FILEBROWSER 1
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"QWERTYUIOP\x1a"
#define keylables_map0_1 (char *)" ASDFGHJKL\x19"
#define keylables_map0_2 (char *)" ZXCVBNM,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'Q','W','E','R','T','Y','U','I','O','P',151, //default C64 uppercase always
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
#define keylables_map1_3 (char *)" "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
153,151,150,152, //U L R D
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
129,130,131,132,133,134,135,136,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,
153,151,150,152, //U L R D
0,0,' ',0
};
#define keylables_map4_0 (char *)"QWERTYUIOP@"
#define keylables_map4_1 (char *)" ASDFGHJKL\x19"
#define keylables_map4_2 (char *)" ZXCVBNM<>:?"
#define keylables_map4_3 (char *)" =\x10_"
const unsigned short key_map4[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M','<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra 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,0,0,
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#endif

View file

@ -4,13 +4,13 @@
#define TEECOMPUTER 1 #define TEECOMPUTER 1
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
//#define ILI9341 1 #define TFTSPI1 1
//#define ST7789 1 //#define HAS_T4_VGA 1
//#define TFTSPI1 1
#define HAS_T4_VGA 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
#define INVX 1 //#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1 #define PT8211 1
#else #else
@ -19,7 +19,11 @@
//#define INVX 1 //#define INVX 1
#define INVY 1 #define INVY 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
/*
TFT/VGA driver
DMA TFT driver based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _T4_DSPH_
#define _T4_DSPH_
#ifdef __cplusplus
#include <Arduino.h>
#include <DMAChannel.h>
#endif
#include "platform_config.h"
#include "iopins.h"
#ifndef TFT_WIDTH
#define TFT_WIDTH 320
#endif
#define TFT_REALWIDTH 320
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 240
#endif
#define TFT_REALHEIGHT 240
typedef enum gfx_mode_t
{
MODE_UNDEFINED = 0,
MODE_TFTILI_320x240 = 1,
MODE_TFTST_320x240 = 2,
MODE_VGA_320x240 = 3,
MODE_VGA_320x480 = 4,
MODE_VGA_352x240 = 5,
MODE_VGA_352x480 = 6,
MODE_VGA_512x240 = 7,
MODE_VGA_512x480 = 8,
MODE_VGA_640x240 = 9,
MODE_VGA_640x480 = 10
} gfx_mode_t;
typedef enum gfx_error_t
{
GFX_OK = 0,
GFX_ERROR = -1
} gfx_error_t;
#ifdef __cplusplus
class T4_DSP
{
public:
T4_DSP();
gfx_error_t begin(gfx_mode_t mode);
gfx_mode_t getMode(void);
void startRefresh(void);
void stopRefresh();
int get_frame_buffer_size(int *width, int *height);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
// wait next Vsync
void waitSync();
void waitLine(int line);
// NoDMA functions
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
void writeLine(int width, int height, int y, uint16_t *buf);
void writeLinePal(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
void writeScreenPal(int width, int height, int stride, uint8_t *buf, uint16_t *palette16);
void writeLine8(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
protected:
static uint8_t _rst, _cs, _dc;
static uint8_t _mosi, _sclk;
static uint8_t _vsync_pin;
static DMAChannel flexio1DMA;
static DMAChannel flexio2DMA;
void tft_setup(bool isST);
static void TFT_isr(void);
static void QT3_isr(void);
};
#endif
#endif

View file

@ -3,133 +3,16 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#include "v20.h" #include "t4_dsp.h"
extern T4_DSP tft;
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
TFT_T_DMA tft;
#else
#include "tft_t_dma.h"
TFT_T_DMA tft = TFT_T_DMA(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO, TFT_TOUCH_CS, TFT_TOUCH_INT);
#endif
bool vgaMode = false;
static unsigned char palette8[PALETTE_SIZE];
static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
static int skip=0;
static elapsedMicros tius;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
//Serial.println("%d: %d %d %d\n", index, r,g,b);
palette8[index] = RGBVAL8(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.waitSync();
#else
while (vbl==vb) {};
#endif
}
}
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.writeLine(width,1,line, VBuf, palette8);
#else
tft.writeLine(width,1,line, VBuf, palette16);
#endif
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine16(width,height,line, VBuf);
#else
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8);
#else
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
#endif
}
}
}
int emu_FrameSkip(void)
{
return skip;
}
void * emu_LineBuffer(int line)
{
if (!vgaMode) {
return (void*)tft.getLineBuffer(line);
}
}
// **************************************************** // ****************************************************
// the setup() method runs once, when the sketch starts // the setup() method runs once, when the sketch starts
// **************************************************** // ****************************************************
void setup() { void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init(); emu_init();
} }
// **************************************************** // ****************************************************
// the loop() method runs continuously // the loop() method runs continuously
// **************************************************** // ****************************************************
@ -139,14 +22,9 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick); int action = handleMenu(bClick);
char * filename = menuSelection(); char * filename = menuSelection();
if (action == ACTION_RUN1) { if (action == ACTION_RUN1) {
toggleMenu(false); emu_start(20000,nullptr);
vgaMode = false;
emu_start();
emu_Init(filename); emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 20000); //to run every 20ms
} }
delay(20); delay(20);
} }
@ -154,45 +32,6 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick); emu_Input(bClick);
emu_Step(); emu_Step();
delay(10); delay(20);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// emu_Input(bClick);
//}
} }
} }
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,234 +0,0 @@
/*
Based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _TFT_T_DMAH_
#define _TFT_T_DMAH_
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include <DMAChannel.h>
#endif
#include "tft_t_dma_config.h"
#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b )
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define R16(rgb) ((rgb>>8)&0xf8)
#define G16(rgb) ((rgb>>3)&0xfc)
#define B16(rgb) ((rgb<<3)&0xf8)
#define PAL_COLOR_MASK 0xff
#ifdef LOHRES
#define TFT_WIDTH 240
#define TFT_REALWIDTH 240
#else
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#endif
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
//#define WIDTH 272
//#define HEIGHT 228
#define LINES_PER_BLOCK 64
#define NR_OF_BLOCK 4
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
#ifdef ILI9341
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0D
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_MH 0x04
#define TFT_CASET ILI9341_CASET
#define TFT_PASET ILI9341_PASET
#define TFT_RAMWR ILI9341_RAMWR
#define TFT_MADCTL ILI9341_MADCTL
#endif
#ifdef ST7789
#define ST7735_NOP 0x00
#define ST7735_SWRESET 0x01
#define ST7735_RDDID 0x04
#define ST7735_RDDST 0x09
#define ST7735_SLPIN 0x10
#define ST7735_SLPOUT 0x11
#define ST7735_PTLON 0x12
#define ST7735_NORON 0x13
#define ST7735_INVOFF 0x20
#define ST7735_INVON 0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_RAMRD 0x2E
#define ST7735_PTLAR 0x30
#define ST7735_COLMOD 0x3A
#define ST7735_MADCTL 0x36
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_DISSET5 0xB6
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_RDID1 0xDA
#define ST7735_RDID2 0xDB
#define ST7735_RDID3 0xDC
#define ST7735_RDID4 0xDD
#define ST7735_PWCTR6 0xFC
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_MADCTL_BGR 0x08
#define ST77XX_MADCTL_MH 0x04
#define TFT_CASET ST7735_CASET
#define TFT_PASET ST7735_RASET
#define TFT_RAMWR ST7735_RAMWR
#define TFT_MADCTL ST7735_MADCTL
#endif
#ifdef __cplusplus
class TFT_T_DMA
{
public:
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
void begin(void);
void flipscreen(bool flip);
boolean isflipped(void);
void startDMA(void);
void stopDMA();
int get_frame_buffer_size(int *width, int *height);
// Touch screen functions
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
// NoDMA functions
void writeScreenNoDma(const uint16_t *pcolors);
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
uint16_t * getLineBuffer(int j);
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int y, uint16_t *buf);
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
protected:
uint8_t _rst, _cs, _dc;
uint8_t _miso, _mosi, _sclk;
uint8_t _touch_irq=255, _touch_cs=255;
bool flipped=false;
void wait(void);
void enableTouchIrq();
};
#endif
#endif

View file

@ -1,14 +0,0 @@
#include "platform_config.h"
//#define ST7789 1
//#define ILI9341 1
#define TFT_LINEARINT 1
#define LINEARINT_HACK 1
//#define FLIP_SCREEN 1
//#define TFT_DEBUG 1
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
//#define TFT_STATICFB 1
#endif

View file

@ -1,53 +0,0 @@
/*
Wrapping class to extend VGA_T4 to TFT_T_DMA
*/
#ifndef _VGA_T_DMAH_
#define _VGA_T_DMAH_
#ifdef __cplusplus
#include <VGA_t4.h>
#endif
#define RGBVAL16(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
#ifdef __cplusplus
class TFT_T_DMA: public VGA_T4
{
public:
// Fake touch screen functions
bool isTouching(void) { return false; }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { }
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { };
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax) { }
// fake DMA functions
void startDMA(void) { };
void stopDMA(void) { };
// fake no DMA functions
void writeScreenNoDma(const vga_pixel *pcolors) { writeScreen(pcolors); }
void fillScreenNoDma(vga_pixel color) { clear(color); }
void drawTextNoDma(int16_t x, int16_t y, const char * text, vga_pixel fgcolor, vga_pixel bgcolor, bool doublesize) { drawText(x,y,text,fgcolor,bgcolor,doublesize); }
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, vga_pixel color) { drawRect(x, y, w, h, color); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap) { drawSprite(x, y, bitmap); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh) { drawSprite(x, y, bitmap, croparx, cropary, croparw, croparh); }
};
#endif
#endif

View file

@ -176,25 +176,24 @@ __
const uint32_t ascii2scan[] = { const uint32_t ascii2scan[] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F //0 1 2 3 4 5 6 7 8 9 A B C D E F
0,0,0,0,0,0,0,0,0,0,0xfd7f,0,0,0,0,0, // return 0,0,0,0,0,0,0,0,0,0,0xfd7f,0,0,0xfd7f,0,0, // return
// 31:RUNSTOP 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xf7fe, //31:RUNSTOP
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xf7fe,
//sp ! " # $ % & ' ( ) * + , - . / //sp ! " # $ % & ' ( ) * + , - . /
0xeffe ,0x1fefe,0x17ffe,0x1fe02,0x17ffd,0x1fefb,0x17ffb,0x1fef7,0x17ff7,0x1feef,0xfdbf ,0xfedf ,0xf7df ,0x7fDf ,0xefdf ,0xf7bf, 0xeffe ,0x1fefe,0x17ffe,0x1fefd,0x17ffd,0x1fefb,0xfebf,0x1fef7,0x17ff7,0x1feef,0xfdbf ,0xfedf ,0xf7df ,0x7fDf ,0xefdf ,0xf7bf,
//0 1 2 3 4 5 6 7 8 9 : ; < = > ? //0 1 2 3 4 5 6 7 8 9 : ; < = > ?
0x7fef ,0xfefe ,0x7ffe ,0xfefd ,0x7ffd ,0xfefb ,0x7ffb ,0xfef7 ,0x7ff7 ,0xfeef ,0xdfdf ,0xfbbf ,0x1f7df,0xdfbf ,0x1efdf,0x1f7bf, 0x7fef ,0xfefe ,0x7ffe ,0xfefd ,0x7ffd ,0xfefb ,0x7ffb ,0xfef7 ,0x7ff7 ,0xfeef ,0xdfdf ,0xfbbf ,0x1f7df,0xdfbf ,0x1efdf,0x1f7bf,
//@ A B C D E F G H I J K L M N O //@ A B C D E F G H I J K L M N O
0xbfdf ,0xfbfd ,0xeff7 ,0xeffb ,0xfbfb ,0xbffd ,0xdffb ,0xfbf7 ,0xdff7 ,0xfdef ,0xfbef ,0xdfef ,0xfbdf ,0xefef ,0xf7ef ,0xbfef, 0xbfdf ,0xfbfd ,0xeff7 ,0xeffb ,0xfbfb ,0xbffd ,0xdffb ,0xfbf7 ,0xdff7 ,0xfdef ,0xfbef ,0xdfef ,0xfbdf ,0xefef ,0xf7ef ,0xbfef,
//P Q R S T U V W X Y Z [ \ ] ^ _ //P Q R S T U V W X Y Z [ \ ] ^ _
0xfddf ,0xbffe ,0xfdfb ,0xdffd ,0xbffb ,0xbff7 ,0xf7f7 ,0xfdfd ,0xf7fb ,0xfdf7 ,0xeffd ,0x1dfdf,0xffff ,0x1fbbf,0 ,0, 0xfddf ,0xbffe ,0xfdfb ,0xdffd ,0xbffb ,0xbff7 ,0xf7f7 ,0xfdfd ,0xf7fb ,0xfdf7 ,0xeffd ,0x1dfdf,0xffff ,0x1fbbf,0 ,0,
//' a c c d e f g h i j k l m n o //' a b c d e f g h i j k l m n o
0 ,0xfbfd ,0xeff7 ,0xeffb ,0xfbfb ,0xbffd ,0xdffb ,0xfbf7 ,0xdff7 ,0xfdef ,0xfbef ,0xdfef ,0xfbdf ,0xefef ,0xf7ef ,0xbfef, 0 ,0xfbfd ,0xeff7 ,0xeffb ,0xfbfb ,0xbffd ,0xdffb ,0xfbf7 ,0xdff7 ,0xfdef ,0xfbef ,0xdfef ,0xfbdf ,0xefef ,0xf7ef ,0xbfef,
//p q r s t u v w x y z { | } ~ DEL //p q r s t u v w x y z { | } ~ DEL
0xfddf ,0xbffe ,0xfdfb ,0xdffd ,0xbffb ,0xbff7 ,0xf7f7 ,0xfdfd ,0xf7fb ,0xfdf7 ,0xeffd ,0, 0 , 0, 0xfe7f ,0, 0xfddf ,0xbffe ,0xfdfb ,0xdffd ,0xbffb ,0xbff7 ,0xf7f7 ,0xfdfd ,0xf7fb ,0xfdf7 ,0xeffd ,0, 0 , 0, 0xfe7f ,0,
// 129:f1 f2 f3 f4 f5 f6 f7 f8 // f1 f2 f3 f4 f5 f6 f7 f8
0,0xef7f,0x1ef7f,0xdf7f,0x1df7f,0xbf7f,0x1bf7f,0x7f7f,0x17f7f,0,0,0,0,0,0,0, // 128-143 0, 0xef7f, 0x1ef7f, 0xdf7f,0x1df7f,0xbf7f, 0x1bf7f,0x7f7f,0x17f7f,0,0,0,0,0,0,0, // 128-143
// 150:right left down up 157:left // 150:right left down up
0,0,0,0,0,0, 0xfb7f,0x1fb7f,0xf77f,0x1f77f,0,0,0,0,0,0 // 144-159 0,0,0,0,0,0, 0xfb7f, 0x1fb7f, 0xf77f, 0x1f77f,0,0,0,0,0,0 // 144-159
}; };
@ -374,7 +373,9 @@ void v20_Step(void)
int hk=ihk; int hk=ihk;
if (iusbhk) hk = iusbhk; if (iusbhk) hk = iusbhk;
#ifdef TEECOMPUTER
if (hk) { if (hk) {
Serial.println(hk);
int scan = ascii2scan[hk]; int scan = ascii2scan[hk];
if (scan & 0x10000) mos6522.setShiftPressed(true); if (scan & 0x10000) mos6522.setShiftPressed(true);
else mos6522.setShiftPressed(false); else mos6522.setShiftPressed(false);
@ -384,12 +385,13 @@ void v20_Step(void)
mos6522.setShiftPressed(false); mos6522.setShiftPressed(false);
mos6522.setKeyPressed(0); mos6522.setKeyPressed(0);
} }
#endif
int k=ik; int k=ik;
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
// Ignore joypad if shift/fn is pressed!!! // Ignore joypad if shift/fn is pressed!!!
if ( !(k & MASK_KEY_USER1) && !(k & MASK_KEY_USER2) ) //if ( !(k & MASK_KEY_USER1) && !(k & MASK_KEY_USER2) )
if ( hk == 0 )
#endif #endif
{ {
if ( !(pik & MASK_JOY2_BTN) && (k & MASK_JOY2_BTN) ) { if ( !(pik & MASK_JOY2_BTN) && (k & MASK_JOY2_BTN) ) {
@ -411,17 +413,49 @@ void v20_Step(void)
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Down, false); mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Down, false);
} }
if ( !(pik & MASK_JOY2_RIGHT) && (k & MASK_JOY2_RIGHT) ) { if ( !(pik & MASK_JOY2_RIGHT) && (k & MASK_JOY2_RIGHT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Left, true);
}
else if ( (pik & MASK_JOY2_RIGHT) && !(k & MASK_JOY2_RIGHT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Left, false);
}
if ( !(pik & MASK_JOY2_LEFT) && (k & MASK_JOY2_LEFT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Right, true); mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Right, true);
} }
else if ( (pik & MASK_JOY2_LEFT) && !(k & MASK_JOY2_LEFT) ) { else if ( (pik & MASK_JOY2_RIGHT) && !(k & MASK_JOY2_RIGHT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Right, false); mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Right, false);
} }
if ( !(pik & MASK_JOY2_LEFT) && (k & MASK_JOY2_LEFT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Left, true);
}
else if ( (pik & MASK_JOY2_LEFT) && !(k & MASK_JOY2_LEFT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Left, false);
}
if ( !(pik & MASK_JOY1_BTN) && (k & MASK_JOY1_BTN) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Fire, true);
}
else if ( (pik & MASK_JOY1_BTN) && !(k & MASK_JOY1_BTN) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Fire, false);
}
if ( !(pik & MASK_JOY1_UP) && (k & MASK_JOY1_UP) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Up, true);
}
else if ( (pik & MASK_JOY1_UP) && !(k & MASK_JOY1_UP) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Up, false);
}
if ( !(pik & MASK_JOY1_DOWN) && (k & MASK_JOY1_DOWN) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Down, true);
}
else if ( (pik & MASK_JOY1_DOWN) && !(k & MASK_JOY1_DOWN) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Down, false);
}
if ( !(pik & MASK_JOY1_RIGHT) && (k & MASK_JOY1_RIGHT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Right, true);
}
else if ( (pik & MASK_JOY1_RIGHT) && !(k & MASK_JOY1_RIGHT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Right, false);
}
if ( !(pik & MASK_JOY1_LEFT) && (k & MASK_JOY1_LEFT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Left, true);
}
else if ( (pik & MASK_JOY1_LEFT) && !(k & MASK_JOY1_LEFT) ) {
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Left, false);
}
} }
#ifndef TEECOMPUTER #ifndef TEECOMPUTER

View file

@ -53,14 +53,7 @@
extern "C" { extern "C" {
#include "emuapi.h" #include "emuapi.h"
} }
#include <Arduino.h>
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
extern TFT_T_DMA tft;
void initMachine(); void initMachine();
void resetMachine() __attribute__ ((noreturn)); void resetMachine() __attribute__ ((noreturn));

4
MCUME_teensy41/teensy64/cpu.h Executable file → Normal file
View file

@ -49,7 +49,7 @@
#include "Teensy64.h" #include "Teensy64.h"
#include "roms.h" #include "roms.h"
#include "patches.h" #include "patches.h"
#include "util.h" #include "timerutil.h"
#include "pla.h" #include "pla.h"
#include "vic.h" #include "vic.h"
#include "keyboard.h" #include "keyboard.h"
@ -331,4 +331,4 @@ static inline uint8_t gpioRead(uint8_t pin)
} }
#endif #endif

View file

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#ifdef HAS_T4_VGA #include <Arduino.h>
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#ifdef HAS_USBKEY #ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info #include "USBHost_t36.h" // Read this header first for key info
USBHost myusb; USBHost myusb;
USBHub hub1(myusb); USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb); KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb); USBHIDParser hid1(myusb);
MouseController mouse1(myusb); MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb); MIDIDevice midi1(myusb);
#endif #endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void); static bool emu_writeConfig(void);
static bool emu_readConfig(void); static bool emu_readConfig(void);
static bool emu_eraseConfig(void); static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false; static bool mouseDetected = false;
static bool keyboardDetected = false; static bool keyboardDetected = false;
@ -34,12 +40,13 @@ static File file;
#define MAX_FILES 64 #define MAX_FILES 64
#define AUTORUN_FILENAME "autorun.txt" #define AUTORUN_FILENAME "autorun.txt"
#define GFX_CFG_FILENAME "gfxmode.txt"
#define MAX_FILENAME_SIZE 24 #define MAX_FILENAME_SIZE 34
#define MAX_MENULINES 9 #define MAX_MENULINES 9
#define TEXT_HEIGHT 16 #define TEXT_HEIGHT 16
#define TEXT_WIDTH 8 #define TEXT_WIDTH 8
#define MENU_FILE_XOFFSET (6*TEXT_WIDTH) #define MENU_FILE_XOFFSET (2*TEXT_WIDTH)
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT) #define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH) #define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT) #define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
@ -53,7 +60,8 @@ static File file;
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft; #include "t4_dsp.h"
T4_DSP tft;
static int nbFiles=0; static int nbFiles=0;
static int curFile=0; static int curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]=""; static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true; static bool menuRedraw=true;
static bool autorun=false; static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys; static const unsigned short * keys;
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
@ -158,6 +168,29 @@ void emu_Free(void * pt)
free(pt); free(pt);
} }
#define SMEMPOOL (0x800000)
EXTMEM static unsigned char slowmem[SMEMPOOL];
static int slowmempt = 0;
void * emu_SMalloc(unsigned int size)
{
void * mem = (void*)&slowmem[slowmempt];
slowmempt += size;
if ( slowmempt > SMEMPOOL ) {
mem = NULL;
emu_printf("failure to allocate slow");
}
else {
emu_printf("could allocate slow static ");
emu_printf(size);
}
return mem;
}
void emu_SFree(void * pt)
{
}
/******************************** /********************************
* Input and keyboard * Input and keyboard
********************************/ ********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif #endif
if ( row & 0x02 ) retval |= MASK_JOY2_BTN; if ( row & 0x02 ) retval |= MASK_JOY2_BTN;
#ifdef EXTPAD
if ( sh_pressed ) retval |= MASK_KEY_USER3;
if ( fn_pressed ) retval |= MASK_KEY_USER1;
digitalWrite(KLED, 0);
#else
// Handle LED flash // Handle LED flash
uint32_t time_ms=millis(); uint32_t time_ms=millis();
if ((time_ms-last_t_ms) > 100) { if ((time_ms-last_t_ms) > 100) {
@ -412,8 +451,9 @@ int emu_ReadKeys(void)
if ( key_fn ) retval |= MASK_KEY_USER2; if ( key_fn ) retval |= MASK_KEY_USER2;
if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1; if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) ) if ( (fn_pressed) && (sh_pressed) )
#else #else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) ) || (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) { while (true) {
; ;
} }
#endif #endif
} }
emu_GetJoystick();
return (retval); return (retval);
} }
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
} }
int emu_GetMouse(int *x, int *y, int *buts) { int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) { if (mouse1.available()) {
*buts = mouse1.getButtons(); *buts = mouse1.getButtons();
*x = mouse1.getMouseX(); *x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
return 0; return 0;
} }
#ifdef HAS_USBKEY int emu_GetJoystick(void) {
#if defined(HAS_USB) && (HAS_USBJOY)
for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++) {
if (joysticks[joystick_index].available()) {
uint64_t axis_mask = joysticks[joystick_index].axisMask();
uint64_t axis_changed_mask = joysticks[joystick_index].axisChangedMask();
uint32_t buttons = joysticks[joystick_index].getButtons();
Serial.printf("Joystick(%d): buttons = %x", joystick_index, buttons);
Serial.println();
}
}
return 1;
#endif
return 0;
}
#if defined(HAS_USB) && (HAS_USBKEY)
void OnPress(auto key) void OnPress(auto key)
{ {
keyboardDetected = true; keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0); return (keyboardDetected?1:0);
} }
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16]; static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0; static unsigned char midiLastCmd=0;
static int midiDataCnt=0; static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif #endif
void emu_MidiOnDataReceived(unsigned char value) { void emu_MidiOnDataReceived(unsigned char value) {
#if defined(HAS_USB) && (HAS_USBMIDI)
#ifdef HAS_USBKEY
//Serial.println(value, HEX); //Serial.println(value, HEX);
//10000000 = 128 = note off //10000000 = 128 = note off
//10010000 = 144 = note on //10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/******************************** /********************************
* Menu file loader UI * Menu file loader UI
********************************/ ********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) { static int readNbFiles(void) {
int totalFiles = 0; int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles; return totalFiles;
} }
void backgroundMenu(void) { void backgroundMenu(void) {
menuRedraw=true; menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick) int handleMenu(uint16_t bClick)
{ {
if (autorun) { if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1); return (ACTION_RUN1);
} }
int action = ACTION_NONE; int action = ACTION_NONE;
if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) ) { if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) || ( bClick & MASK_KEY_USER2 ) ) {
char newpath[MAX_FILENAME_PATH]; char newpath[MAX_FILENAME_PATH];
strcpy(newpath, selection); strcpy(newpath, selection);
strcat(newpath, "/"); strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection); File file = SD.open(selection);
if (file.isDirectory()) { if (file.isDirectory()) {
curFile = 0; curFile = 0;
nbFiles = readNbFiles(); nbFiles = readNbFiles();
menuRedraw=true;
} }
else { else
action = ACTION_RUN1; {
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
if (key_extmode) { if ( (key_extmode) || ( key_sh) ) {
emu_writeConfig(); emu_writeConfig();
} }
if ( tft.getMode() < MODE_VGA_320x240) {
if ( bClick & MASK_KEY_USER2 ) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
}
//emu_SwapJoysticks(0);
#endif #endif
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
} }
menuRedraw=true;
} }
else if ( bClick & MASK_KEY_USER1 ) { else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true; menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/"); strcat(second_selection, "/");
strcat(second_selection, second_selected_filename); strcat(second_selection, second_selected_filename);
action = ACTION_RUN2; action = ACTION_RUN2;
} }
else if ( bClick & MASK_KEY_USER2 ) {
menuRedraw=true;
//action = ACTION_RUN3;
emu_SwapJoysticks(0);
}
else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) { else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) {
if (curFile!=0) { if (curFile!=0) {
menuRedraw=true; menuRedraw=true;
curFile--; curFile--;
} }
} }
else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) { else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) {
if ((curFile-9)>=0) { if ((curFile-9)>=0) {
menuRedraw=true; menuRedraw=true;
curFile -= 9; curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
menuRedraw=true; menuRedraw=true;
} }
} }
else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) { else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) {
if ((curFile<(nbFiles-9)) && (nbFiles)) { if ((curFile<(nbFiles-9)) && (nbFiles)) {
curFile += 9; curFile += 9;
menuRedraw=true; menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action); return (action);
} }
bool menuActive(void) int menuActive(void)
{ {
return (menuOn); return (menuOn?1:0);
} }
void toggleMenu(bool on) { void toggleMenu(int on) {
if (on) { if (on) {
menuOn=true; menuOn=true;
backgroundMenu(); backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{ {
return (second_selection); return (second_selection);
} }
#endif
/******************************** /********************************
* OSKB handling * OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0}; char c[4] = {' ',0,' ',0};
const char * cpt = str; const char * cpt = str;
int i=0; int i=0;
int fb_width,fb_height,fb_stride; int fb_width,fb_height,fbstride;
tft.get_frame_buffer_size(&fb_width, &fb_height, &fb_stride);
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0); int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0); int line = row + (bottom?2:0);
while ((c[1] = *cpt++)) while ((c[1] = *cpt++))
@ -1150,7 +1218,7 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0); 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); else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff); if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false); tft.drawText(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false);
i++; i++;
} }
} }
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval; return retval;
} }
void toggleOSKB(bool forceon) { void toggleOSKB(int forceon) {
if (forceon) { if (forceon) {
oskbOn = true; oskbOn = true;
drawOSKB(); drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#endif #endif
} }
int emu_FileWrite(void * buf, int size, int handler)
{
// emu_printf("emu_FileWrite");
// emu_printi(handler);
#ifdef HCFH
return (file.write(buf, size));
#else
return (getFileHandler(handler).write(buf, size));
#endif
}
int emu_FileGetc(int handler) { int emu_FileGetc(int handler) {
// emu_printf("FileGetc"); // emu_printf("FileGetc");
// emu_printi(handler); // emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize); emu_printf(filesize);
lofile.close(); lofile.close();
} }
else {
emu_printf("filesize failed");
}
return(filesize); return(filesize);
} }
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
SD.remove (ROMSDIR "/" AUTORUN_FILENAME); SD.remove (ROMSDIR "/" AUTORUN_FILENAME);
} }
static bool emu_writeGfxConfig(char * display_type)
{
bool retval = false;
SD.remove ("/" GFX_CFG_FILENAME);
if (strcmp(display_type, "VGA")) {
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_CREAT | O_WRITE)))
{
if (lofile.write(display_type, strlen(display_type)) != strlen(display_type)) {
emu_printf("GFX config write failed");
}
else {
retval = true;
}
lofile.close();
}
}
return retval;
}
#define CFG_VGA 0
#define CFG_ILI 1
#define CFG_ST 2
static int emu_readGfxConfig(void)
{
int retval = CFG_VGA; // No file = VGA
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_READ)))
{
unsigned int filesize = lofile.size();
if (filesize == 2) // "ST"
{
retval = CFG_ST;
}
else if (filesize == 3) // "ILI"
{
retval = CFG_ILI;
}
lofile.close();
}
return retval;
}
/******************************** /********************************
* File IO compatibility * File IO compatibility
********************************/ ********************************/
@ -1670,62 +1794,249 @@ FRESULT f_mkdir (const char* path)
/******************************** /********************************
* Initialization * GFX wrapper
********************************/ ********************************/
void emu_init(void) static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
volatile boolean vgatimervsync=false;
static void (*vblCallback)(void) = nullptr;
static int skip=0;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if ( tft.getMode() >= MODE_VGA_320x240 ) {
if (vgatimervsync) {
while (vbl==vb) {};
}
else {
tft.waitSync();
}
}
else {
while (vbl==vb) {};
}
if (vblCallback != nullptr) {
vblCallback();
}
}
void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride)
{
if (skip == 0) {
tft.writeScreenPal(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
}
}
void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLinePal(width,height,line, VBuf, palette16);
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine(width,height,line, VBuf);
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine8(width,height,line, VBuf, palette16);
}
}
int emu_IsVga(void)
{
return (tft.getMode() >= MODE_VGA_320x240?1:0);
}
int emu_IsVgaHires(void)
{
return (tft.getMode() >= MODE_VGA_640x240?1:0);
}
int emu_FrameSkip(void)
{
return skip;
}
/********************************
* AUDIO wrapper
********************************/
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif
/********************************
* Initialization
********************************/
void emu_init(int hires)
{ {
Serial.begin(115200); Serial.begin(115200);
vgahires = hires;
#ifdef HAS_USBKEY #ifdef HAS_USB
myusb.begin(); myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress); keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease); keyboard1.attachRelease(OnRelease);
#endif #endif
#endif
while (!SD.begin(SD_CS)) #ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{ {
Serial.println("SD begin failed, retrying..."); Serial.println("No SD card detected");
delay(1000);
} }
strcpy(selection,ROMSDIR); strcpy(selection,ROMSDIR);
FileHandlersInit(); FileHandlersInit();
nbFiles = readNbFiles(); nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles); Serial.println(nbFiles);
#endif
emu_InitJoysticks(); emu_InitJoysticks();
#ifdef SWAP_JOYSTICK #ifdef SWAP_JOYSTICK
joySwapped = true; joySwapped = true;
#else #else
joySwapped = false; joySwapped = false;
#endif #endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
int keypressed = emu_ReadKeys(); int keypressed = emu_ReadKeys();
#ifdef HAS_T4_VGA
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
#else
int gfx_mode = CFG_VGA; // default
#ifdef FILEBROWSER
gfx_mode = emu_readGfxConfig();
#endif
// Force VGA if UP pressed
if (keypressed & MASK_JOY2_UP)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("VGA");
#endif
gfx_mode = CFG_VGA;
}
else {
if (keypressed & MASK_JOY2_LEFT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ST");
#endif
gfx_mode = CFG_ST;
}
else if (keypressed & MASK_JOY2_RIGHT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ILI");
#endif
gfx_mode = CFG_ILI;
}
}
if (gfx_mode == CFG_VGA) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
else
{
tft.begin(gfx_mode == CFG_ILI?MODE_TFTILI_320x240:MODE_TFTST_320x240);
}
#endif
if (keypressed & MASK_JOY2_DOWN) { if (keypressed & MASK_JOY2_DOWN) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig(); emu_eraseConfig();
delay(1000); delay(1000);
#endif
} }
else { else {
#ifdef FILEBROWSER
if (emu_readConfig()) { if (emu_readConfig()) {
autorun = true; autorun = true;
} }
#endif
} }
#ifdef FILEBROWSER
toggleMenu(true); toggleMenu(true);
#endif
} }
void emu_start(void) void emu_start(int vblms, void * callback, int forcetimervsync)
{ {
vgatimervsync = forcetimervsync?true:false;
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startRefresh();
if (callback != nullptr) {
vblCallback = callback;
}
myTimer.begin(vblCount, vblms);
#ifdef HAS_SND
emu_sndInit();
#endif
usbnavpad = 0; usbnavpad = 0;
} }

View file

@ -2,126 +2,14 @@
#define EMUAPI_H #define EMUAPI_H
#include "platform_config.h" #include "platform_config.h"
#include "emucfg.h"
#define CUSTOM_SND 1
//#define TIMER_REND 1
#define EXTRA_HEAP 0x10
// Title: < >
#define TITLE " C64 Emulator "
#define ROMSDIR "c64"
#define emu_Init(ROM) {c64_Start(ROM); c64_Init(); }
#define emu_Step(x) { c64_Step(); }
#define emu_Input(x) { c64_Input(x); }
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define R32(rgb) ((rgb>>16)&0xff)
#define G32(rgb) ((rgb>>8)&0xff)
#define B32(rgb) (rgb & 0xff)
#define ACTION_NONE 0 #define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16 #define ACTION_RUN1 1
#define ACTION_EXITKBD 128 #define ACTION_RUN2 2
#define ACTION_RUN1 129
#define ACTION_RUN2 130
#define ACTION_RUN3 131
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"QWERTYUIOP\x1a"
#define keylables_map0_1 (char *)" ASDFGHJKL\x19"
#define keylables_map0_2 (char *)" ZXCVBNM,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'Q','W','E','R','T','Y','U','I','O','P',127, //default C64 uppercase always
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
#define keylables_map1_3 (char *)" "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit 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,0,0,
0,0,' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
153,151,150,152, //U L R D
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
129,130,131,132,133,134,135,136,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,0,0,
0,0,' ',0
};
#define keylables_map4_0 (char *)"QWERTYUIOP@"
#define keylables_map4_1 (char *)" ASDFGHJKL\x19"
#define keylables_map4_2 (char *)" ZXCVBNM<>:?"
#define keylables_map4_3 (char *)" =\x10_"
const unsigned short key_map4[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M','<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#define FORCE_VGATIMERVSYNC 1
#define SUPPORT_HIRES 1
#define MASK_JOY2_RIGHT 0x0001 #define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002 #define MASK_JOY2_LEFT 0x0002
@ -138,22 +26,25 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_BTN 0x1000 #define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000 #define MASK_KEY_USER4 0x2000
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
extern void emu_init(int hires=0);
extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif #endif
extern void emu_init(void);
extern void emu_start(void);
extern void emu_printf(const char * text); extern void emu_printf(const char * text);
extern void emu_printi(int val); extern void emu_printi(int val);
extern void emu_printh(int val); extern void emu_printh(int val);
extern void * emu_Malloc(unsigned int size); extern void * emu_Malloc(unsigned int size);
extern void * emu_MallocI(unsigned int size); extern void * emu_MallocI(unsigned int size);
extern void emu_Free(void * pt); extern void emu_Free(void * pt);
extern void * emu_SMalloc(unsigned int size);
extern void emu_SFree(void * pt);
extern int emu_FileOpen(const char * filepath, const char * mode); extern int emu_FileOpen(const char * filepath, const char * mode);
extern int emu_FileRead(void * buf, int size, int handler); extern int emu_FileRead(void * buf, int size, int handler);
extern int emu_FileWrite(void * buf, int size, int handler);
extern int emu_FileGetc(int handler); extern int emu_FileGetc(int handler);
extern int emu_FileSeek(int handler, int seek, int origin); extern int emu_FileSeek(int handler, int seek, int origin);
extern int emu_FileTell(int handler); extern int emu_FileTell(int handler);
@ -164,24 +55,23 @@ extern unsigned int emu_LoadFile(const char * filepath, void * buf, int size);
extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek); extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek);
extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index); extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index);
extern void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride); extern void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line); extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line);
extern void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride);
extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line); extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line);
extern void emu_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void); extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void); extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line); extern int emu_IsVga(void);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta); extern int emu_IsVgaHires(void);
extern bool menuActive(void); extern int menuActive(void);
extern char * menuSelection(void); extern char * menuSelection(void);
extern char * menuSecondSelection(void); extern char * menuSecondSelection(void);
extern void toggleMenu(bool on); extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick); extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void); extern int handleOSKB(void);
extern void toggleOSKB(bool forceon); extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void); extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly); extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ extern int emu_ReadKeys(void);
extern int emu_GetPad(void); extern int emu_GetPad(void);
extern int emu_GetMouse(int *x, int *y, int *buts); extern int emu_GetMouse(int *x, int *y, int *buts);
extern int emu_MouseDetected(void); extern int emu_MouseDetected(void);
extern int emu_GetJoystick(void);
extern int emu_KeyboardDetected(void); extern int emu_KeyboardDetected(void);
extern int emu_ReadAnalogJoyX(int min, int max); extern int emu_ReadAnalogJoyX(int min, int max);
extern int emu_ReadAnalogJoyY(int min, int max); extern int emu_ReadAnalogJoyY(int min, int max);

View file

@ -0,0 +1,115 @@
#ifndef EMUCFG_H
#define EMUCFG_H
#include "wrapemu.h"
// Title: < >
#define TITLE " C64 Emulator "
#define ROMSDIR "c64"
#define emu_Init(ROM) {c64_Start(ROM); c64_Init(); }
#define emu_Step(x) { c64_Step(); }
#define emu_Input(x) { c64_Input(x); }
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 16
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define CUSTOM_SND 1
//#define TIMER_REND 1
//#define EXTPAD 1
#define EXTRA_HEAP 0x10
#define FILEBROWSER 1
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"QWERTYUIOP\x1a"
#define keylables_map0_1 (char *)" ASDFGHJKL\x19"
#define keylables_map0_2 (char *)" ZXCVBNM,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'Q','W','E','R','T','Y','U','I','O','P',127, //default C64 uppercase always
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
#define keylables_map1_3 (char *)" "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
153,151,150,152, //U L R D
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
129,130,131,132,133,134,135,136,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,0,0,
0,0,' ',0
};
#define keylables_map4_0 (char *)"QWERTYUIOP@"
#define keylables_map4_1 (char *)" ASDFGHJKL\x19"
#define keylables_map4_2 (char *)" ZXCVBNM<>:?"
#define keylables_map4_3 (char *)" =\x10_"
const unsigned short key_map4[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M','<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#endif

View file

@ -4,23 +4,26 @@
#define TEECOMPUTER 1 #define TEECOMPUTER 1
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
//#define ILI9341 1 #define TFTSPI1 1
//#define ST7789 1 //#define HAS_T4_VGA 1
//#define TFTSPI1 1
#define HAS_T4_VGA 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
#define INVX 1 //#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1 #define PT8211 1
#else #else
#define HAS_T4_VGA 1 #define HAS_T4_VGA 1
#define HIRES 1
//#define INVX 1 //#define INVX 1
#define INVY 1 #define INVY 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
/*
TFT/VGA driver
DMA TFT driver based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _T4_DSPH_
#define _T4_DSPH_
#ifdef __cplusplus
#include <Arduino.h>
#include <DMAChannel.h>
#endif
#include "platform_config.h"
#include "iopins.h"
#ifndef TFT_WIDTH
#define TFT_WIDTH 320
#endif
#define TFT_REALWIDTH 320
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 240
#endif
#define TFT_REALHEIGHT 240
typedef enum gfx_mode_t
{
MODE_UNDEFINED = 0,
MODE_TFTILI_320x240 = 1,
MODE_TFTST_320x240 = 2,
MODE_VGA_320x240 = 3,
MODE_VGA_320x480 = 4,
MODE_VGA_352x240 = 5,
MODE_VGA_352x480 = 6,
MODE_VGA_512x240 = 7,
MODE_VGA_512x480 = 8,
MODE_VGA_640x240 = 9,
MODE_VGA_640x480 = 10
} gfx_mode_t;
typedef enum gfx_error_t
{
GFX_OK = 0,
GFX_ERROR = -1
} gfx_error_t;
#ifdef __cplusplus
class T4_DSP
{
public:
T4_DSP();
gfx_error_t begin(gfx_mode_t mode);
gfx_mode_t getMode(void);
void startRefresh(void);
void stopRefresh();
int get_frame_buffer_size(int *width, int *height);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
// wait next Vsync
void waitSync();
void waitLine(int line);
// NoDMA functions
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
void writeLine(int width, int height, int y, uint16_t *buf);
void writeLinePal(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
void writeScreenPal(int width, int height, int stride, uint8_t *buf, uint16_t *palette16);
void writeLine8(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
protected:
static uint8_t _rst, _cs, _dc;
static uint8_t _mosi, _sclk;
static uint8_t _vsync_pin;
static DMAChannel flexio1DMA;
static DMAChannel flexio2DMA;
void tft_setup(bool isST);
static void TFT_isr(void);
static void QT3_isr(void);
};
#endif
#endif

View file

@ -3,134 +3,20 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#include "c64.h" #include "t4_dsp.h"
extern T4_DSP tft;
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
TFT_T_DMA tft;
#else
#include "tft_t_dma.h"
TFT_T_DMA tft = TFT_T_DMA(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO, TFT_TOUCH_CS, TFT_TOUCH_INT);
#endif
bool vgaMode = false;
static unsigned char palette8[PALETTE_SIZE];
static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
static int skip=0;
static elapsedMicros tius;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
//Serial.println("%d: %d %d %d\n", index, r,g,b);
palette8[index] = RGBVAL8(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.waitSync();
#else
while (vbl==vb) {};
#endif
}
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.writeLine(width,1,line, VBuf, palette8);
#else
tft.writeLine(width,1,line, VBuf, palette16);
#endif
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine16(width,height,line, VBuf);
#else
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8);
#else
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
#endif
}
}
}
int emu_FrameSkip(void)
{
return skip;
}
void * emu_LineBuffer(int line)
{
if (!vgaMode) {
return (void*)tft.getLineBuffer(line);
}
}
// **************************************************** // ****************************************************
// the setup() method runs once, when the sketch starts // the setup() method runs once, when the sketch starts
// **************************************************** // ****************************************************
void setup() { void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init(); emu_init();
} }
static void vbl(void) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
// **************************************************** // ****************************************************
// the loop() method runs continuously // the loop() method runs continuously
@ -141,58 +27,13 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick); int action = handleMenu(bClick);
char * filename = menuSelection(); char * filename = menuSelection();
if (action == ACTION_RUN1) { if (action == ACTION_RUN1) {
toggleMenu(false); emu_start(20000,vbl);
vgaMode = false; emu_Init(filename);
emu_start();
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 20000); //to run every 20ms
} }
delay(20); delay(20);
} }
else { else {
emu_Step(); emu_Step();
//delay(20);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// emu_Input(bClick);
//}
} }
} }
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,232 +0,0 @@
/*
Based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _TFT_T_DMAH_
#define _TFT_T_DMAH_
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include <DMAChannel.h>
#endif
#include "tft_t_dma_config.h"
#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b )
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define R16(rgb) ((rgb>>8)&0xf8)
#define G16(rgb) ((rgb>>3)&0xfc)
#define B16(rgb) ((rgb<<3)&0xf8)
#define PAL_COLOR_MASK 0xff
#ifdef LOHRES
#define TFT_WIDTH 240
#define TFT_REALWIDTH 240
#else
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#endif
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
//#define WIDTH 272
//#define HEIGHT 228
#define LINES_PER_BLOCK 64
#define NR_OF_BLOCK 4
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
#ifdef ILI9341
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0D
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_MH 0x04
#define TFT_CASET ILI9341_CASET
#define TFT_PASET ILI9341_PASET
#define TFT_RAMWR ILI9341_RAMWR
#define TFT_MADCTL ILI9341_MADCTL
#endif
#ifdef ST7789
#define ST7735_NOP 0x00
#define ST7735_SWRESET 0x01
#define ST7735_RDDID 0x04
#define ST7735_RDDST 0x09
#define ST7735_SLPIN 0x10
#define ST7735_SLPOUT 0x11
#define ST7735_PTLON 0x12
#define ST7735_NORON 0x13
#define ST7735_INVOFF 0x20
#define ST7735_INVON 0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_RAMRD 0x2E
#define ST7735_PTLAR 0x30
#define ST7735_COLMOD 0x3A
#define ST7735_MADCTL 0x36
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_DISSET5 0xB6
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_RDID1 0xDA
#define ST7735_RDID2 0xDB
#define ST7735_RDID3 0xDC
#define ST7735_RDID4 0xDD
#define ST7735_PWCTR6 0xFC
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_MADCTL_BGR 0x08
#define ST77XX_MADCTL_MH 0x04
#define TFT_CASET ST7735_CASET
#define TFT_PASET ST7735_RASET
#define TFT_RAMWR ST7735_RAMWR
#define TFT_MADCTL ST7735_MADCTL
#endif
#ifdef __cplusplus
class TFT_T_DMA
{
public:
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
void begin(void);
void flipscreen(bool flip);
boolean isflipped(void);
void startDMA(void);
void stopDMA();
int get_frame_buffer_size(int *width, int *height, int *stride);
// Touch screen functions
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
// NoDMA functions
void writeScreenNoDma(const uint16_t *pcolors);
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
uint16_t * getLineBuffer(int j);
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int y, uint16_t *buf);
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
protected:
uint8_t _rst, _cs, _dc;
uint8_t _miso, _mosi, _sclk;
uint8_t _touch_irq=255, _touch_cs=255;
bool flipped=false;
void wait(void);
void enableTouchIrq();
};
#endif
#endif

View file

@ -1,14 +0,0 @@
#include "platform_config.h"
//#define ST7789 1
//#define ILI9341 1
#define TFT_LINEARINT 1
#define LINEARINT_HACK 1
//#define FLIP_SCREEN 1
//#define TFT_DEBUG 1
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
//#define TFT_STATICFB 1
#endif

View file

@ -34,7 +34,7 @@ Copyright Frank Bösing, 2017
*/ */
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "util.h" #include "timerutil.h"
//Attention, don't use WFI-instruction - the CPU does not count cycles during sleep //Attention, don't use WFI-instruction - the CPU does not count cycles during sleep
void enableCycleCounter(void) { void enableCycleCounter(void) {
@ -68,4 +68,4 @@ void setAudioOn(void) {
void listInterrupts() { void listInterrupts() {
} }

View file

@ -1,53 +0,0 @@
/*
Wrapping class to extend VGA_T4 to TFT_T_DMA
*/
#ifndef _VGA_T_DMAH_
#define _VGA_T_DMAH_
#ifdef __cplusplus
#include <VGA_t4.h>
#endif
#define RGBVAL16(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
#ifdef __cplusplus
class TFT_T_DMA: public VGA_T4
{
public:
// Fake touch screen functions
bool isTouching(void) { return false; }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { }
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { };
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax) { }
// fake DMA functions
void startDMA(void) { };
void stopDMA(void) { };
// fake no DMA functions
void writeScreenNoDma(const vga_pixel *pcolors) { writeScreen(pcolors); }
void fillScreenNoDma(vga_pixel color) { clear(color); }
void drawTextNoDma(int16_t x, int16_t y, const char * text, vga_pixel fgcolor, vga_pixel bgcolor, bool doublesize) { drawText(x,y,text,fgcolor,bgcolor,doublesize); }
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, vga_pixel color) { drawRect(x, y, w, h, color); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap) { drawSprite(x, y, bitmap); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh) { drawSprite(x, y, bitmap, croparx, cropary, croparw, croparh); }
};
#endif
#endif

View file

@ -69,11 +69,7 @@
#define BORDER_LEFT 0 #define BORDER_LEFT 0
#define BORDER_RIGHT 0 #define BORDER_RIGHT 0
#ifdef HAS_T4_VGA
typedef uint8_t tpixel;
#else
typedef uint16_t tpixel; typedef uint16_t tpixel;
#endif
#define MAXCYCLESSPRITES0_2 3 #define MAXCYCLESSPRITES0_2 3
#define MAXCYCLESSPRITES3_7 5 #define MAXCYCLESSPRITES3_7 5
@ -1606,12 +1602,7 @@ g-Zugriff
} }
#ifdef HAS_T4_VGA
emu_DrawLine8(&linebuffer[0], SCREEN_WIDTH, SCREEN_HEIGHT, (r - FIRSTDISPLAYLINE));
#else
emu_DrawLine16(&linebuffer[0], SCREEN_WIDTH, SCREEN_HEIGHT, (r - FIRSTDISPLAYLINE)); emu_DrawLine16(&linebuffer[0], SCREEN_WIDTH, SCREEN_HEIGHT, (r - FIRSTDISPLAYLINE));
#endif

View file

@ -198,14 +198,14 @@ uint8_t cia1PORTA(void) {
if (keys & MASK_JOY2_BTN) v &= 0xEF; if (keys & MASK_JOY2_BTN) v &= 0xEF;
if (keys & MASK_JOY2_UP) v &= 0xFE; if (keys & MASK_JOY2_UP) v &= 0xFE;
if (keys & MASK_JOY2_DOWN) v &= 0xFD; if (keys & MASK_JOY2_DOWN) v &= 0xFD;
if (keys & MASK_JOY2_RIGHT) v &= 0xFB; if (keys & MASK_JOY2_LEFT) v &= 0xFB;
if (keys & MASK_JOY2_LEFT) v &= 0xF7; if (keys & MASK_JOY2_RIGHT) v &= 0xF7;
} else { } else {
if (keys & MASK_JOY1_BTN) v &= 0xEF; if (keys & MASK_JOY1_BTN) v &= 0xEF;
if (keys & MASK_JOY1_UP) v &= 0xFE; if (keys & MASK_JOY1_UP) v &= 0xFE;
if (keys & MASK_JOY1_DOWN) v &= 0xFD; if (keys & MASK_JOY1_DOWN) v &= 0xFD;
if (keys & MASK_JOY1_RIGHT) v &= 0xFB; if (keys & MASK_JOY1_LEFT) v &= 0xFB;
if (keys & MASK_JOY1_LEFT) v &= 0xF7; if (keys & MASK_JOY1_RIGHT) v &= 0xF7;
} }
if (!kbdData.kv) return v; //Keine Taste gedrückt if (!kbdData.kv) return v; //Keine Taste gedrückt

View file

@ -41,7 +41,7 @@ UWORD Screen_atari[ATARI_WIDTH / 2]; // = NULL;
#define DRAWLINE() \ #define DRAWLINE() \
if ( (ANTIC_ypos > 8) && (ANTIC_ypos < 248)) { \ if ( (ANTIC_ypos > 8) && (ANTIC_ypos < 248)) { \
emu_DrawLine((unsigned char *)&Screen_atari[32/sizeof(Screen_atari[0])], 320, 240, ANTIC_ypos-8); \ emu_DrawLinePal16((unsigned char *)&Screen_atari[32/sizeof(Screen_atari[0])], 320, 240, ANTIC_ypos-8); \
} }

View file

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#ifdef HAS_T4_VGA #include <Arduino.h>
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#ifdef HAS_USBKEY #ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info #include "USBHost_t36.h" // Read this header first for key info
USBHost myusb; USBHost myusb;
USBHub hub1(myusb); USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb); KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb); USBHIDParser hid1(myusb);
MouseController mouse1(myusb); MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb); MIDIDevice midi1(myusb);
#endif #endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void); static bool emu_writeConfig(void);
static bool emu_readConfig(void); static bool emu_readConfig(void);
static bool emu_eraseConfig(void); static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false; static bool mouseDetected = false;
static bool keyboardDetected = false; static bool keyboardDetected = false;
@ -34,8 +40,9 @@ static File file;
#define MAX_FILES 64 #define MAX_FILES 64
#define AUTORUN_FILENAME "autorun.txt" #define AUTORUN_FILENAME "autorun.txt"
#define GFX_CFG_FILENAME "gfxmode.txt"
#define MAX_FILENAME_SIZE 24 #define MAX_FILENAME_SIZE 34
#define MAX_MENULINES 9 #define MAX_MENULINES 9
#define TEXT_HEIGHT 16 #define TEXT_HEIGHT 16
#define TEXT_WIDTH 8 #define TEXT_WIDTH 8
@ -53,7 +60,8 @@ static File file;
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft; #include "t4_dsp.h"
T4_DSP tft;
static int nbFiles=0; static int nbFiles=0;
static int curFile=0; static int curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]=""; static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true; static bool menuRedraw=true;
static bool autorun=false; static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys; static const unsigned short * keys;
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
@ -103,7 +113,7 @@ void emu_printf(int val)
void emu_printi(int val) void emu_printi(int val)
{ {
Serial.println(val); Serial.println(val,HEX);
} }
void emu_printh(int val) void emu_printh(int val)
@ -158,6 +168,29 @@ void emu_Free(void * pt)
free(pt); free(pt);
} }
#define SMEMPOOL (0x800000)
EXTMEM static unsigned char slowmem[SMEMPOOL];
static int slowmempt = 0;
void * emu_SMalloc(unsigned int size)
{
void * mem = (void*)&slowmem[slowmempt];
slowmempt += size;
if ( slowmempt > SMEMPOOL ) {
mem = NULL;
emu_printf("failure to allocate slow");
}
else {
emu_printf("could allocate slow static ");
emu_printf(size);
}
return mem;
}
void emu_SFree(void * pt)
{
}
/******************************** /********************************
* Input and keyboard * Input and keyboard
********************************/ ********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif #endif
if ( row & 0x02 ) retval |= MASK_JOY2_BTN; if ( row & 0x02 ) retval |= MASK_JOY2_BTN;
#ifdef EXTPAD
if ( sh_pressed ) retval |= MASK_KEY_USER3;
if ( fn_pressed ) retval |= MASK_KEY_USER1;
digitalWrite(KLED, 0);
#else
// Handle LED flash // Handle LED flash
uint32_t time_ms=millis(); uint32_t time_ms=millis();
if ((time_ms-last_t_ms) > 100) { if ((time_ms-last_t_ms) > 100) {
@ -412,8 +451,9 @@ int emu_ReadKeys(void)
if ( key_fn ) retval |= MASK_KEY_USER2; if ( key_fn ) retval |= MASK_KEY_USER2;
if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1; if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) ) if ( (fn_pressed) && (sh_pressed) )
#else #else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) ) || (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) { while (true) {
; ;
} }
#endif #endif
} }
emu_GetJoystick();
return (retval); return (retval);
} }
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
} }
int emu_GetMouse(int *x, int *y, int *buts) { int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) { if (mouse1.available()) {
*buts = mouse1.getButtons(); *buts = mouse1.getButtons();
*x = mouse1.getMouseX(); *x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
return 0; return 0;
} }
#ifdef HAS_USBKEY int emu_GetJoystick(void) {
#if defined(HAS_USB) && (HAS_USBJOY)
for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++) {
if (joysticks[joystick_index].available()) {
uint64_t axis_mask = joysticks[joystick_index].axisMask();
uint64_t axis_changed_mask = joysticks[joystick_index].axisChangedMask();
uint32_t buttons = joysticks[joystick_index].getButtons();
Serial.printf("Joystick(%d): buttons = %x", joystick_index, buttons);
Serial.println();
}
}
return 1;
#endif
return 0;
}
#if defined(HAS_USB) && (HAS_USBKEY)
void OnPress(auto key) void OnPress(auto key)
{ {
keyboardDetected = true; keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0); return (keyboardDetected?1:0);
} }
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16]; static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0; static unsigned char midiLastCmd=0;
static int midiDataCnt=0; static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif #endif
void emu_MidiOnDataReceived(unsigned char value) { void emu_MidiOnDataReceived(unsigned char value) {
#if defined(HAS_USB) && (HAS_USBMIDI)
#ifdef HAS_USBKEY
//Serial.println(value, HEX); //Serial.println(value, HEX);
//10000000 = 128 = note off //10000000 = 128 = note off
//10010000 = 144 = note on //10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/******************************** /********************************
* Menu file loader UI * Menu file loader UI
********************************/ ********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) { static int readNbFiles(void) {
int totalFiles = 0; int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles; return totalFiles;
} }
void backgroundMenu(void) { void backgroundMenu(void) {
menuRedraw=true; menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick) int handleMenu(uint16_t bClick)
{ {
if (autorun) { if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1); return (ACTION_RUN1);
} }
int action = ACTION_NONE; int action = ACTION_NONE;
if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) ) { if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) || ( bClick & MASK_KEY_USER2 ) ) {
char newpath[MAX_FILENAME_PATH]; char newpath[MAX_FILENAME_PATH];
strcpy(newpath, selection); strcpy(newpath, selection);
strcat(newpath, "/"); strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection); File file = SD.open(selection);
if (file.isDirectory()) { if (file.isDirectory()) {
curFile = 0; curFile = 0;
nbFiles = readNbFiles(); nbFiles = readNbFiles();
menuRedraw=true;
} }
else { else
action = ACTION_RUN1; {
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
if (key_extmode) { if ( (key_extmode) || ( key_sh) ) {
emu_writeConfig(); emu_writeConfig();
} }
if ( tft.getMode() < MODE_VGA_320x240) {
if ( bClick & MASK_KEY_USER2 ) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
}
//emu_SwapJoysticks(0);
#endif #endif
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
} }
menuRedraw=true;
} }
else if ( bClick & MASK_KEY_USER1 ) { else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true; menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/"); strcat(second_selection, "/");
strcat(second_selection, second_selected_filename); strcat(second_selection, second_selected_filename);
action = ACTION_RUN2; action = ACTION_RUN2;
} }
else if ( bClick & MASK_KEY_USER2 ) {
menuRedraw=true;
//action = ACTION_RUN3;
emu_SwapJoysticks(0);
}
else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) { else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) {
if (curFile!=0) { if (curFile!=0) {
menuRedraw=true; menuRedraw=true;
curFile--; curFile--;
} }
} }
else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) { else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) {
if ((curFile-9)>=0) { if ((curFile-9)>=0) {
menuRedraw=true; menuRedraw=true;
curFile -= 9; curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
menuRedraw=true; menuRedraw=true;
} }
} }
else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) { else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) {
if ((curFile<(nbFiles-9)) && (nbFiles)) { if ((curFile<(nbFiles-9)) && (nbFiles)) {
curFile += 9; curFile += 9;
menuRedraw=true; menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action); return (action);
} }
bool menuActive(void) int menuActive(void)
{ {
return (menuOn); return (menuOn?1:0);
} }
void toggleMenu(bool on) { void toggleMenu(int on) {
if (on) { if (on) {
menuOn=true; menuOn=true;
backgroundMenu(); backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{ {
return (second_selection); return (second_selection);
} }
#endif
/******************************** /********************************
* OSKB handling * OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0}; char c[4] = {' ',0,' ',0};
const char * cpt = str; const char * cpt = str;
int i=0; int i=0;
int fb_width,fb_height; int fb_width,fb_height,fbstride;
tft.get_frame_buffer_size(&fb_width, &fb_height);
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0); int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0); int line = row + (bottom?2:0);
while ((c[1] = *cpt++)) while ((c[1] = *cpt++))
@ -1150,7 +1218,7 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0); 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); else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff); if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false); tft.drawText(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false);
i++; i++;
} }
} }
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval; return retval;
} }
void toggleOSKB(bool forceon) { void toggleOSKB(int forceon) {
if (forceon) { if (forceon) {
oskbOn = true; oskbOn = true;
drawOSKB(); drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#endif #endif
} }
int emu_FileWrite(void * buf, int size, int handler)
{
// emu_printf("emu_FileWrite");
// emu_printi(handler);
#ifdef HCFH
return (file.write(buf, size));
#else
return (getFileHandler(handler).write(buf, size));
#endif
}
int emu_FileGetc(int handler) { int emu_FileGetc(int handler) {
// emu_printf("FileGetc"); // emu_printf("FileGetc");
// emu_printi(handler); // emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize); emu_printf(filesize);
lofile.close(); lofile.close();
} }
else {
emu_printf("filesize failed");
}
return(filesize); return(filesize);
} }
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
SD.remove (ROMSDIR "/" AUTORUN_FILENAME); SD.remove (ROMSDIR "/" AUTORUN_FILENAME);
} }
static bool emu_writeGfxConfig(char * display_type)
{
bool retval = false;
SD.remove ("/" GFX_CFG_FILENAME);
if (strcmp(display_type, "VGA")) {
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_CREAT | O_WRITE)))
{
if (lofile.write(display_type, strlen(display_type)) != strlen(display_type)) {
emu_printf("GFX config write failed");
}
else {
retval = true;
}
lofile.close();
}
}
return retval;
}
#define CFG_VGA 0
#define CFG_ILI 1
#define CFG_ST 2
static int emu_readGfxConfig(void)
{
int retval = CFG_VGA; // No file = VGA
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_READ)))
{
unsigned int filesize = lofile.size();
if (filesize == 2) // "ST"
{
retval = CFG_ST;
}
else if (filesize == 3) // "ILI"
{
retval = CFG_ILI;
}
lofile.close();
}
return retval;
}
/******************************** /********************************
* File IO compatibility * File IO compatibility
********************************/ ********************************/
@ -1670,62 +1794,249 @@ FRESULT f_mkdir (const char* path)
/******************************** /********************************
* Initialization * GFX wrapper
********************************/ ********************************/
void emu_init(void) static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
volatile boolean vgatimervsync=false;
static void (*vblCallback)(void) = nullptr;
static int skip=0;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if ( tft.getMode() >= MODE_VGA_320x240 ) {
if (vgatimervsync) {
while (vbl==vb) {};
}
else {
tft.waitSync();
}
}
else {
while (vbl==vb) {};
}
if (vblCallback != nullptr) {
vblCallback();
}
}
void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride)
{
if (skip == 0) {
tft.writeScreenPal(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
}
}
void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLinePal(width,height,line, VBuf, palette16);
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine(width,height,line, VBuf);
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine8(width,height,line, VBuf, palette16);
}
}
int emu_IsVga(void)
{
return (tft.getMode() >= MODE_VGA_320x240?1:0);
}
int emu_IsVgaHires(void)
{
return (tft.getMode() >= MODE_VGA_640x240?1:0);
}
int emu_FrameSkip(void)
{
return skip;
}
/********************************
* AUDIO wrapper
********************************/
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif
/********************************
* Initialization
********************************/
void emu_init(int hires)
{ {
Serial.begin(115200); Serial.begin(115200);
vgahires = hires;
#ifdef HAS_USBKEY #ifdef HAS_USB
myusb.begin(); myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress); keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease); keyboard1.attachRelease(OnRelease);
#endif #endif
#endif
while (!SD.begin(SD_CS)) #ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{ {
Serial.println("SD begin failed, retrying..."); Serial.println("No SD card detected");
delay(1000);
} }
strcpy(selection,ROMSDIR); strcpy(selection,ROMSDIR);
FileHandlersInit(); FileHandlersInit();
nbFiles = readNbFiles(); nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles); Serial.println(nbFiles);
#endif
emu_InitJoysticks(); emu_InitJoysticks();
#ifdef SWAP_JOYSTICK #ifdef SWAP_JOYSTICK
joySwapped = true; joySwapped = true;
#else #else
joySwapped = false; joySwapped = false;
#endif #endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
int keypressed = emu_ReadKeys(); int keypressed = emu_ReadKeys();
#ifdef HAS_T4_VGA
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
#else
int gfx_mode = CFG_VGA; // default
#ifdef FILEBROWSER
gfx_mode = emu_readGfxConfig();
#endif
// Force VGA if UP pressed
if (keypressed & MASK_JOY2_UP)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("VGA");
#endif
gfx_mode = CFG_VGA;
}
else {
if (keypressed & MASK_JOY2_LEFT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ST");
#endif
gfx_mode = CFG_ST;
}
else if (keypressed & MASK_JOY2_RIGHT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ILI");
#endif
gfx_mode = CFG_ILI;
}
}
if (gfx_mode == CFG_VGA) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
else
{
tft.begin(gfx_mode == CFG_ILI?MODE_TFTILI_320x240:MODE_TFTST_320x240);
}
#endif
if (keypressed & MASK_JOY2_DOWN) { if (keypressed & MASK_JOY2_DOWN) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig(); emu_eraseConfig();
delay(1000); delay(1000);
#endif
} }
else { else {
#ifdef FILEBROWSER
if (emu_readConfig()) { if (emu_readConfig()) {
autorun = true; autorun = true;
} }
#endif
} }
#ifdef FILEBROWSER
toggleMenu(true); toggleMenu(true);
#endif
} }
void emu_start(void) void emu_start(int vblms, void * callback, int forcetimervsync)
{ {
vgatimervsync = forcetimervsync?true:false;
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startRefresh();
if (callback != nullptr) {
vblCallback = callback;
}
myTimer.begin(vblCount, vblms);
#ifdef HAS_SND
emu_sndInit();
#endif
usbnavpad = 0; usbnavpad = 0;
} }

View file

@ -2,124 +2,14 @@
#define EMUAPI_H #define EMUAPI_H
#include "platform_config.h" #include "platform_config.h"
#include "emucfg.h"
#define CUSTOM_SND 1
//#define TIMER_REND 1
#define EXTRA_HEAP 0x10
// Title: < >
#define TITLE " Atari 800 Emulator"
#define ROMSDIR "800"
#define emu_Init(ROM) {at8_Init(); at8_Start(ROM);}
#define emu_Step(x) {at8_Step();}
#define emu_Input(x) {at8_Input(x);}
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define R32(rgb) ((rgb>>16)&0xff)
#define G32(rgb) ((rgb>>8)&0xff)
#define B32(rgb) (rgb & 0xff)
#define ACTION_NONE 0 #define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16 #define ACTION_RUN1 1
#define ACTION_EXITKBD 128 #define ACTION_RUN2 2
#define ACTION_RUN1 129
#define ACTION_RUN2 130
#define ACTION_RUN3 131
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"qwertyuiop\x1a"
#define keylables_map0_1 (char *)" asdfghjkl\x19"
#define keylables_map0_2 (char *)" zxcvbnm,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'q','w','e','r','t','y','u','i','o','p',127, //lowecase
0,'a','s','d','f','g','h','j','k','l',10,
0,'z','x','c','v','b','n','m',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)" \x1a"
#define keylables_map1_1 (char *)" \x19"
#define keylables_map1_2 (char *)" <>:?"
#define keylables_map1_3 (char *)" =\x10 "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',127, // digit keys
0, 0,0,0,0,0,0,0,0,0,10,
0, 0,0,0,0,0,0,0,'<','>',':','?',
154,152,151,153, //U L R D
0,'=',' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" \x19"
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10 "
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
9, 0,0,0,0,0,0,0,0,0,10,
0, 0,0,0,0,0,0,0,'<','>',':','?',
154,152,151,153, //U L R D
0,'=',' ',0
};
#define keylables_map3_0 (char *)"1234567890 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
154,152,151,153, //U L R D
0,0,' ',0
};
#define keylables_map4_0 (char *)" "
#define keylables_map4_1 (char *)" "
#define keylables_map4_2 (char *)" "
#define keylables_map4_3 (char *)" "
const unsigned short key_map4[] = {
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,
154,152,151,153, //U L R D
0,0,' ',0
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
154,152,151,153, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#define FORCE_VGATIMERVSYNC 1
#define SUPPORT_HIRES 1
#define MASK_JOY2_RIGHT 0x0001 #define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002 #define MASK_JOY2_LEFT 0x0002
@ -136,24 +26,25 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_BTN 0x1000 #define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000 #define MASK_KEY_USER4 0x2000
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#else extern void emu_init(int hires=0);
#define bool unsigned char extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif #endif
extern void emu_init(void);
extern void emu_start(void);
extern void emu_printf(const char * text); extern void emu_printf(const char * text);
extern void emu_printi(int val); extern void emu_printi(int val);
extern void emu_printh(int val); extern void emu_printh(int val);
extern void * emu_Malloc(unsigned int size); extern void * emu_Malloc(unsigned int size);
extern void * emu_MallocI(unsigned int size); extern void * emu_MallocI(unsigned int size);
extern void emu_Free(void * pt); extern void emu_Free(void * pt);
extern void * emu_SMalloc(unsigned int size);
extern void emu_SFree(void * pt);
extern int emu_FileOpen(const char * filepath, const char * mode); extern int emu_FileOpen(const char * filepath, const char * mode);
extern int emu_FileRead(void * buf, int size, int handler); extern int emu_FileRead(void * buf, int size, int handler);
extern int emu_FileWrite(void * buf, int size, int handler);
extern int emu_FileGetc(int handler); extern int emu_FileGetc(int handler);
extern int emu_FileSeek(int handler, int seek, int origin); extern int emu_FileSeek(int handler, int seek, int origin);
extern int emu_FileTell(int handler); extern int emu_FileTell(int handler);
@ -164,24 +55,23 @@ extern unsigned int emu_LoadFile(const char * filepath, void * buf, int size);
extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek); extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek);
extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index); extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index);
extern void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride); extern void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line); extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line);
extern void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride);
extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line); extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line);
extern void emu_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void); extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void); extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line); extern int emu_IsVga(void);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta); extern int emu_IsVgaHires(void);
extern bool menuActive(void); extern int menuActive(void);
extern char * menuSelection(void); extern char * menuSelection(void);
extern char * menuSecondSelection(void); extern char * menuSecondSelection(void);
extern void toggleMenu(bool on); extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick); extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void); extern int handleOSKB(void);
extern void toggleOSKB(bool forceon); extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void); extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly); extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ extern int emu_ReadKeys(void);
extern int emu_GetPad(void); extern int emu_GetPad(void);
extern int emu_GetMouse(int *x, int *y, int *buts); extern int emu_GetMouse(int *x, int *y, int *buts);
extern int emu_MouseDetected(void); extern int emu_MouseDetected(void);
extern int emu_GetJoystick(void);
extern int emu_KeyboardDetected(void); extern int emu_KeyboardDetected(void);
extern int emu_ReadAnalogJoyX(int min, int max); extern int emu_ReadAnalogJoyX(int min, int max);
extern int emu_ReadAnalogJoyY(int min, int max); extern int emu_ReadAnalogJoyY(int min, int max);

View file

@ -0,0 +1,115 @@
#ifndef EMUCFG_H
#define EMUCFG_H
#include "wrapemu.h"
// Title: < >
#define TITLE " Atari 800 Emulator"
#define ROMSDIR "800"
#define emu_Init(ROM) {at8_Init(); at8_Start(ROM);}
#define emu_Step(x) {at8_Step();}
#define emu_Input(x) {at8_Input(x);}
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define CUSTOM_SND 1
//#define TIMER_REND 1
//#define EXTPAD 1
#define EXTRA_HEAP 0x10
#define FILEBROWSER 1
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"qwertyuiop\x1a"
#define keylables_map0_1 (char *)" asdfghjkl\x19"
#define keylables_map0_2 (char *)" zxcvbnm,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'q','w','e','r','t','y','u','i','o','p',127, //lowecase
0,'a','s','d','f','g','h','j','k','l',10,
0,'z','x','c','v','b','n','m',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)" \x1a"
#define keylables_map1_1 (char *)" \x19"
#define keylables_map1_2 (char *)" <>:?"
#define keylables_map1_3 (char *)" =\x10 "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',127, // digit keys
0, 0,0,0,0,0,0,0,0,0,10,
0, 0,0,0,0,0,0,0,'<','>',':','?',
154,152,151,153, //U L R D
0,'=',' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" \x19"
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10 "
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
9, 0,0,0,0,0,0,0,0,0,10,
0, 0,0,0,0,0,0,0,'<','>',':','?',
154,152,151,153, //U L R D
0,'=',' ',0
};
#define keylables_map3_0 (char *)"1234567890 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
154,152,151,153, //U L R D
0,0,' ',0
};
#define keylables_map4_0 (char *)" "
#define keylables_map4_1 (char *)" "
#define keylables_map4_2 (char *)" "
#define keylables_map4_3 (char *)" "
const unsigned short key_map4[] = {
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,
154,152,151,153, //U L R D
0,0,' ',0
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
154,152,151,153, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#endif

View file

@ -4,13 +4,13 @@
#define TEECOMPUTER 1 #define TEECOMPUTER 1
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
//#define ILI9341 1 #define TFTSPI1 1
//#define ST7789 1 //#define HAS_T4_VGA 1
//#define TFTSPI1 1
#define HAS_T4_VGA 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
#define INVX 1 //#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1 #define PT8211 1
#else #else
@ -19,7 +19,11 @@
//#define INVX 1 //#define INVX 1
#define INVY 1 #define INVY 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
/*
TFT/VGA driver
DMA TFT driver based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _T4_DSPH_
#define _T4_DSPH_
#ifdef __cplusplus
#include <Arduino.h>
#include <DMAChannel.h>
#endif
#include "platform_config.h"
#include "iopins.h"
#ifndef TFT_WIDTH
#define TFT_WIDTH 320
#endif
#define TFT_REALWIDTH 320
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 240
#endif
#define TFT_REALHEIGHT 240
typedef enum gfx_mode_t
{
MODE_UNDEFINED = 0,
MODE_TFTILI_320x240 = 1,
MODE_TFTST_320x240 = 2,
MODE_VGA_320x240 = 3,
MODE_VGA_320x480 = 4,
MODE_VGA_352x240 = 5,
MODE_VGA_352x480 = 6,
MODE_VGA_512x240 = 7,
MODE_VGA_512x480 = 8,
MODE_VGA_640x240 = 9,
MODE_VGA_640x480 = 10
} gfx_mode_t;
typedef enum gfx_error_t
{
GFX_OK = 0,
GFX_ERROR = -1
} gfx_error_t;
#ifdef __cplusplus
class T4_DSP
{
public:
T4_DSP();
gfx_error_t begin(gfx_mode_t mode);
gfx_mode_t getMode(void);
void startRefresh(void);
void stopRefresh();
int get_frame_buffer_size(int *width, int *height);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
// wait next Vsync
void waitSync();
void waitLine(int line);
// NoDMA functions
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
void writeLine(int width, int height, int y, uint16_t *buf);
void writeLinePal(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
void writeScreenPal(int width, int height, int stride, uint8_t *buf, uint16_t *palette16);
void writeLine8(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
protected:
static uint8_t _rst, _cs, _dc;
static uint8_t _mosi, _sclk;
static uint8_t _vsync_pin;
static DMAChannel flexio1DMA;
static DMAChannel flexio2DMA;
void tft_setup(bool isST);
static void TFT_isr(void);
static void QT3_isr(void);
};
#endif
#endif

View file

@ -3,135 +3,20 @@ extern "C" {
#include "emuapi.h" #include "emuapi.h"
} }
extern "C" { #include "t4_dsp.h"
#include "atari800.h" extern T4_DSP tft;
}
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
TFT_T_DMA tft;
#else
#include "tft_t_dma.h"
TFT_T_DMA tft = TFT_T_DMA(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO, TFT_TOUCH_CS, TFT_TOUCH_INT);
#endif
bool vgaMode = false;
static unsigned char palette8[PALETTE_SIZE];
static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
static int skip=0;
static elapsedMicros tius;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
//Serial.println("%d: %d %d %d\n", index, r,g,b);
palette8[index] = RGBVAL8(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if (!vgaMode) {
#ifdef HAS_T4_VGA
// tft.waitSync();
#else
// while (vbl==vb) {};
#endif
while (vbl==vb) {};
}
}
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.writeLine(width,1,line, VBuf, palette8);
#else
tft.writeLine(width,1,line, VBuf, palette16);
#endif
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine16(width,height,line, VBuf);
#else
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8);
#else
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
#endif
}
}
}
int emu_FrameSkip(void)
{
return skip;
}
void * emu_LineBuffer(int line)
{
if (!vgaMode) {
return (void*)tft.getLineBuffer(line);
}
}
// **************************************************** // ****************************************************
// the setup() method runs once, when the sketch starts // the setup() method runs once, when the sketch starts
// **************************************************** // ****************************************************
void setup() { void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init(); emu_init();
} }
static void vbl(void) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
// **************************************************** // ****************************************************
// the loop() method runs continuously // the loop() method runs continuously
@ -142,55 +27,15 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick); int action = handleMenu(bClick);
char * filename = menuSelection(); char * filename = menuSelection();
if (action == ACTION_RUN1) { if (action == ACTION_RUN1) {
toggleMenu(false); emu_start(10000,nullptr,FORCE_VGATIMERVSYNC);
vgaMode = false;
emu_start();
emu_Init(filename); emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 10000/*16666*/); //to run every 16.666ms
} }
delay(20); delay(20);
} }
else { else {
emu_Step();
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick); emu_Input(bClick);
emu_Step();
} }
} }
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
//mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,232 +0,0 @@
/*
Based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _TFT_T_DMAH_
#define _TFT_T_DMAH_
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include <DMAChannel.h>
#endif
#include "tft_t_dma_config.h"
#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b )
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define R16(rgb) ((rgb>>8)&0xf8)
#define G16(rgb) ((rgb>>3)&0xfc)
#define B16(rgb) ((rgb<<3)&0xf8)
#define PAL_COLOR_MASK 0xff
#ifdef LOHRES
#define TFT_WIDTH 240
#define TFT_REALWIDTH 240
#else
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#endif
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
//#define WIDTH 272
//#define HEIGHT 228
#define LINES_PER_BLOCK 64
#define NR_OF_BLOCK 4
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
#ifdef ILI9341
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0D
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_MH 0x04
#define TFT_CASET ILI9341_CASET
#define TFT_PASET ILI9341_PASET
#define TFT_RAMWR ILI9341_RAMWR
#define TFT_MADCTL ILI9341_MADCTL
#endif
#ifdef ST7789
#define ST7735_NOP 0x00
#define ST7735_SWRESET 0x01
#define ST7735_RDDID 0x04
#define ST7735_RDDST 0x09
#define ST7735_SLPIN 0x10
#define ST7735_SLPOUT 0x11
#define ST7735_PTLON 0x12
#define ST7735_NORON 0x13
#define ST7735_INVOFF 0x20
#define ST7735_INVON 0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_RAMRD 0x2E
#define ST7735_PTLAR 0x30
#define ST7735_COLMOD 0x3A
#define ST7735_MADCTL 0x36
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_DISSET5 0xB6
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_RDID1 0xDA
#define ST7735_RDID2 0xDB
#define ST7735_RDID3 0xDC
#define ST7735_RDID4 0xDD
#define ST7735_PWCTR6 0xFC
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_MADCTL_BGR 0x08
#define ST77XX_MADCTL_MH 0x04
#define TFT_CASET ST7735_CASET
#define TFT_PASET ST7735_RASET
#define TFT_RAMWR ST7735_RAMWR
#define TFT_MADCTL ST7735_MADCTL
#endif
#ifdef __cplusplus
class TFT_T_DMA
{
public:
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
void begin(void);
void flipscreen(bool flip);
boolean isflipped(void);
void startDMA(void);
void stopDMA();
int get_frame_buffer_size(int *width, int *height);
// Touch screen functions
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
// NoDMA functions
void writeScreenNoDma(const uint16_t *pcolors);
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
uint16_t * getLineBuffer(int j);
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int y, uint16_t *buf);
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
protected:
uint8_t _rst, _cs, _dc;
uint8_t _miso, _mosi, _sclk;
uint8_t _touch_irq=255, _touch_cs=255;
bool flipped=false;
void wait(void);
void enableTouchIrq();
};
#endif
#endif

View file

@ -1,13 +0,0 @@
#include "platform_config.h"
//#define ST7789 1
//#define ILI9341 1
#define TFT_LINEARINT 1
#define LINEARINT_HACK 1
//#define FLIP_SCREEN 1
//#define TFT_DEBUG 1
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
//#define TFT_STATICFB 1
#endif

View file

@ -1,53 +0,0 @@
/*
Wrapping class to extend VGA_T4 to TFT_T_DMA
*/
#ifndef _VGA_T_DMAH_
#define _VGA_T_DMAH_
#ifdef __cplusplus
#include <VGA_t4.h>
#endif
#define RGBVAL16(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
#ifdef __cplusplus
class TFT_T_DMA: public VGA_T4
{
public:
// Fake touch screen functions
bool isTouching(void) { return false; }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { }
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { };
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax) { }
// fake DMA functions
void startDMA(void) { };
void stopDMA(void) { };
// fake no DMA functions
void writeScreenNoDma(const vga_pixel *pcolors) { writeScreen(pcolors); }
void fillScreenNoDma(vga_pixel color) { clear(color); }
void drawTextNoDma(int16_t x, int16_t y, const char * text, vga_pixel fgcolor, vga_pixel bgcolor, bool doublesize) { drawText(x,y,text,fgcolor,bgcolor,doublesize); }
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, vga_pixel color) { drawRect(x, y, w, h, color); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap) { drawSprite(x, y, bitmap); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh) { drawSprite(x, y, bitmap, croparx, cropary, croparw, croparh); }
};
#endif
#endif

View file

@ -1,4 +1,4 @@
#include "atari800.h" #include "wrapemu.h"
#include <string.h> #include <string.h>
#include "memory.h" #include "memory.h"
#include "cpu.h" #include "cpu.h"
@ -18,6 +18,9 @@
#include "pokeysnd.h" #include "pokeysnd.h"
#endif #endif
#define R32(rgb) ((rgb>>16)&0xff)
#define G32(rgb) ((rgb>>8)&0xff)
#define B32(rgb) (rgb & 0xff)
// Controllers // Controllers
typedef struct typedef struct
@ -508,23 +511,23 @@ void at8_Step(void)
INPUT_Frame(); INPUT_Frame();
// Joystick side button, trigger and directions // Joystick side button, trigger and directions
if (k & MASK_JOY2_BTN) if ( (k & MASK_JOY2_BTN) || (k & MASK_JOY1_BTN) )
which->trig = 1; which->trig = 1;
else else
which->trig = 0; which->trig = 0;
if (k & MASK_JOY2_DOWN) if ( (k & MASK_JOY2_DOWN) || (k & MASK_JOY1_DOWN) )
which->down = 1; which->down = 1;
else else
which->down = 0; which->down = 0;
if (k & MASK_JOY2_UP) if ( (k & MASK_JOY2_UP) || (k & MASK_JOY1_UP) )
which->up = 1; which->up = 1;
else else
which->up = 0; which->up = 0;
if (k & MASK_JOY2_RIGHT) if ( (k & MASK_JOY2_LEFT) || (k & MASK_JOY1_LEFT) )
which->left = 1; which->left = 1;
else else
which->left = 0; which->left = 0;
if (k & MASK_JOY2_LEFT) if ( (k & MASK_JOY2_RIGHT) || (k & MASK_JOY1_RIGHT) )
which->right = 1; which->right = 1;
else else
which->right = 0; which->right = 0;

View file

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#ifdef HAS_T4_VGA #include <Arduino.h>
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#ifdef HAS_USBKEY #ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info #include "USBHost_t36.h" // Read this header first for key info
USBHost myusb; USBHost myusb;
USBHub hub1(myusb); USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb); KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb); USBHIDParser hid1(myusb);
MouseController mouse1(myusb); MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb); MIDIDevice midi1(myusb);
#endif #endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void); static bool emu_writeConfig(void);
static bool emu_readConfig(void); static bool emu_readConfig(void);
static bool emu_eraseConfig(void); static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false; static bool mouseDetected = false;
static bool keyboardDetected = false; static bool keyboardDetected = false;
@ -34,8 +40,9 @@ static File file;
#define MAX_FILES 64 #define MAX_FILES 64
#define AUTORUN_FILENAME "autorun.txt" #define AUTORUN_FILENAME "autorun.txt"
#define GFX_CFG_FILENAME "gfxmode.txt"
#define MAX_FILENAME_SIZE 24 #define MAX_FILENAME_SIZE 34
#define MAX_MENULINES 9 #define MAX_MENULINES 9
#define TEXT_HEIGHT 16 #define TEXT_HEIGHT 16
#define TEXT_WIDTH 8 #define TEXT_WIDTH 8
@ -53,7 +60,8 @@ static File file;
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft; #include "t4_dsp.h"
T4_DSP tft;
static int nbFiles=0; static int nbFiles=0;
static int curFile=0; static int curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]=""; static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true; static bool menuRedraw=true;
static bool autorun=false; static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys; static const unsigned short * keys;
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
@ -103,7 +113,7 @@ void emu_printf(int val)
void emu_printi(int val) void emu_printi(int val)
{ {
Serial.println(val); Serial.println(val,HEX);
} }
void emu_printh(int val) void emu_printh(int val)
@ -158,6 +168,29 @@ void emu_Free(void * pt)
free(pt); free(pt);
} }
#define SMEMPOOL (0x800000)
EXTMEM static unsigned char slowmem[SMEMPOOL];
static int slowmempt = 0;
void * emu_SMalloc(unsigned int size)
{
void * mem = (void*)&slowmem[slowmempt];
slowmempt += size;
if ( slowmempt > SMEMPOOL ) {
mem = NULL;
emu_printf("failure to allocate slow");
}
else {
emu_printf("could allocate slow static ");
emu_printf(size);
}
return mem;
}
void emu_SFree(void * pt)
{
}
/******************************** /********************************
* Input and keyboard * Input and keyboard
********************************/ ********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif #endif
if ( row & 0x02 ) retval |= MASK_JOY2_BTN; if ( row & 0x02 ) retval |= MASK_JOY2_BTN;
#ifdef EXTPAD
if ( sh_pressed ) retval |= MASK_KEY_USER3;
if ( fn_pressed ) retval |= MASK_KEY_USER1;
digitalWrite(KLED, 0);
#else
// Handle LED flash // Handle LED flash
uint32_t time_ms=millis(); uint32_t time_ms=millis();
if ((time_ms-last_t_ms) > 100) { if ((time_ms-last_t_ms) > 100) {
@ -412,8 +451,9 @@ int emu_ReadKeys(void)
if ( key_fn ) retval |= MASK_KEY_USER2; if ( key_fn ) retval |= MASK_KEY_USER2;
if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1; if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) ) if ( (fn_pressed) && (sh_pressed) )
#else #else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) ) || (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) { while (true) {
; ;
} }
#endif #endif
} }
emu_GetJoystick();
return (retval); return (retval);
} }
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
} }
int emu_GetMouse(int *x, int *y, int *buts) { int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) { if (mouse1.available()) {
*buts = mouse1.getButtons(); *buts = mouse1.getButtons();
*x = mouse1.getMouseX(); *x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
return 0; return 0;
} }
#ifdef HAS_USBKEY int emu_GetJoystick(void) {
#if defined(HAS_USB) && (HAS_USBJOY)
for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++) {
if (joysticks[joystick_index].available()) {
uint64_t axis_mask = joysticks[joystick_index].axisMask();
uint64_t axis_changed_mask = joysticks[joystick_index].axisChangedMask();
uint32_t buttons = joysticks[joystick_index].getButtons();
Serial.printf("Joystick(%d): buttons = %x", joystick_index, buttons);
Serial.println();
}
}
return 1;
#endif
return 0;
}
#if defined(HAS_USB) && (HAS_USBKEY)
void OnPress(auto key) void OnPress(auto key)
{ {
keyboardDetected = true; keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0); return (keyboardDetected?1:0);
} }
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16]; static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0; static unsigned char midiLastCmd=0;
static int midiDataCnt=0; static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif #endif
void emu_MidiOnDataReceived(unsigned char value) { void emu_MidiOnDataReceived(unsigned char value) {
#if defined(HAS_USB) && (HAS_USBMIDI)
#ifdef HAS_USBKEY
//Serial.println(value, HEX); //Serial.println(value, HEX);
//10000000 = 128 = note off //10000000 = 128 = note off
//10010000 = 144 = note on //10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/******************************** /********************************
* Menu file loader UI * Menu file loader UI
********************************/ ********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) { static int readNbFiles(void) {
int totalFiles = 0; int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles; return totalFiles;
} }
void backgroundMenu(void) { void backgroundMenu(void) {
menuRedraw=true; menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick) int handleMenu(uint16_t bClick)
{ {
if (autorun) { if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1); return (ACTION_RUN1);
} }
int action = ACTION_NONE; int action = ACTION_NONE;
if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) ) { if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) || ( bClick & MASK_KEY_USER2 ) ) {
char newpath[MAX_FILENAME_PATH]; char newpath[MAX_FILENAME_PATH];
strcpy(newpath, selection); strcpy(newpath, selection);
strcat(newpath, "/"); strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection); File file = SD.open(selection);
if (file.isDirectory()) { if (file.isDirectory()) {
curFile = 0; curFile = 0;
nbFiles = readNbFiles(); nbFiles = readNbFiles();
menuRedraw=true;
} }
else { else
action = ACTION_RUN1; {
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
if (key_extmode) { if ( (key_extmode) || ( key_sh) ) {
emu_writeConfig(); emu_writeConfig();
} }
if ( tft.getMode() < MODE_VGA_320x240) {
if ( bClick & MASK_KEY_USER2 ) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
}
//emu_SwapJoysticks(0);
#endif #endif
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
} }
menuRedraw=true;
} }
else if ( bClick & MASK_KEY_USER1 ) { else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true; menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/"); strcat(second_selection, "/");
strcat(second_selection, second_selected_filename); strcat(second_selection, second_selected_filename);
action = ACTION_RUN2; action = ACTION_RUN2;
} }
else if ( bClick & MASK_KEY_USER2 ) {
menuRedraw=true;
//action = ACTION_RUN3;
emu_SwapJoysticks(0);
}
else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) { else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) {
if (curFile!=0) { if (curFile!=0) {
menuRedraw=true; menuRedraw=true;
curFile--; curFile--;
} }
} }
else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) { else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) {
if ((curFile-9)>=0) { if ((curFile-9)>=0) {
menuRedraw=true; menuRedraw=true;
curFile -= 9; curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
menuRedraw=true; menuRedraw=true;
} }
} }
else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) { else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) {
if ((curFile<(nbFiles-9)) && (nbFiles)) { if ((curFile<(nbFiles-9)) && (nbFiles)) {
curFile += 9; curFile += 9;
menuRedraw=true; menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action); return (action);
} }
bool menuActive(void) int menuActive(void)
{ {
return (menuOn); return (menuOn?1:0);
} }
void toggleMenu(bool on) { void toggleMenu(int on) {
if (on) { if (on) {
menuOn=true; menuOn=true;
backgroundMenu(); backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{ {
return (second_selection); return (second_selection);
} }
#endif
/******************************** /********************************
* OSKB handling * OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0}; char c[4] = {' ',0,' ',0};
const char * cpt = str; const char * cpt = str;
int i=0; int i=0;
int fb_width,fb_height; int fb_width,fb_height,fbstride;
tft.get_frame_buffer_size(&fb_width, &fb_height);
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0); int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0); int line = row + (bottom?2:0);
while ((c[1] = *cpt++)) while ((c[1] = *cpt++))
@ -1150,7 +1218,7 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0); 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); else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff); if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false); tft.drawText(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false);
i++; i++;
} }
} }
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval; return retval;
} }
void toggleOSKB(bool forceon) { void toggleOSKB(int forceon) {
if (forceon) { if (forceon) {
oskbOn = true; oskbOn = true;
drawOSKB(); drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#endif #endif
} }
int emu_FileWrite(void * buf, int size, int handler)
{
// emu_printf("emu_FileWrite");
// emu_printi(handler);
#ifdef HCFH
return (file.write(buf, size));
#else
return (getFileHandler(handler).write(buf, size));
#endif
}
int emu_FileGetc(int handler) { int emu_FileGetc(int handler) {
// emu_printf("FileGetc"); // emu_printf("FileGetc");
// emu_printi(handler); // emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize); emu_printf(filesize);
lofile.close(); lofile.close();
} }
else {
emu_printf("filesize failed");
}
return(filesize); return(filesize);
} }
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
SD.remove (ROMSDIR "/" AUTORUN_FILENAME); SD.remove (ROMSDIR "/" AUTORUN_FILENAME);
} }
static bool emu_writeGfxConfig(char * display_type)
{
bool retval = false;
SD.remove ("/" GFX_CFG_FILENAME);
if (strcmp(display_type, "VGA")) {
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_CREAT | O_WRITE)))
{
if (lofile.write(display_type, strlen(display_type)) != strlen(display_type)) {
emu_printf("GFX config write failed");
}
else {
retval = true;
}
lofile.close();
}
}
return retval;
}
#define CFG_VGA 0
#define CFG_ILI 1
#define CFG_ST 2
static int emu_readGfxConfig(void)
{
int retval = CFG_VGA; // No file = VGA
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_READ)))
{
unsigned int filesize = lofile.size();
if (filesize == 2) // "ST"
{
retval = CFG_ST;
}
else if (filesize == 3) // "ILI"
{
retval = CFG_ILI;
}
lofile.close();
}
return retval;
}
/******************************** /********************************
* File IO compatibility * File IO compatibility
********************************/ ********************************/
@ -1670,62 +1794,249 @@ FRESULT f_mkdir (const char* path)
/******************************** /********************************
* Initialization * GFX wrapper
********************************/ ********************************/
void emu_init(void) static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
volatile boolean vgatimervsync=false;
static void (*vblCallback)(void) = nullptr;
static int skip=0;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if ( tft.getMode() >= MODE_VGA_320x240 ) {
if (vgatimervsync) {
while (vbl==vb) {};
}
else {
tft.waitSync();
}
}
else {
while (vbl==vb) {};
}
if (vblCallback != nullptr) {
vblCallback();
}
}
void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride)
{
if (skip == 0) {
tft.writeScreenPal(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
}
}
void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLinePal(width,height,line, VBuf, palette16);
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine(width,height,line, VBuf);
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine8(width,height,line, VBuf, palette16);
}
}
int emu_IsVga(void)
{
return (tft.getMode() >= MODE_VGA_320x240?1:0);
}
int emu_IsVgaHires(void)
{
return (tft.getMode() >= MODE_VGA_640x240?1:0);
}
int emu_FrameSkip(void)
{
return skip;
}
/********************************
* AUDIO wrapper
********************************/
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif
/********************************
* Initialization
********************************/
void emu_init(int hires)
{ {
Serial.begin(115200); Serial.begin(115200);
vgahires = hires;
#ifdef HAS_USBKEY #ifdef HAS_USB
myusb.begin(); myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress); keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease); keyboard1.attachRelease(OnRelease);
#endif #endif
#endif
while (!SD.begin(SD_CS)) #ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{ {
Serial.println("SD begin failed, retrying..."); Serial.println("No SD card detected");
delay(1000);
} }
strcpy(selection,ROMSDIR); strcpy(selection,ROMSDIR);
FileHandlersInit(); FileHandlersInit();
nbFiles = readNbFiles(); nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles); Serial.println(nbFiles);
#endif
emu_InitJoysticks(); emu_InitJoysticks();
#ifdef SWAP_JOYSTICK #ifdef SWAP_JOYSTICK
joySwapped = true; joySwapped = true;
#else #else
joySwapped = false; joySwapped = false;
#endif #endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
int keypressed = emu_ReadKeys(); int keypressed = emu_ReadKeys();
#ifdef HAS_T4_VGA
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
#else
int gfx_mode = CFG_VGA; // default
#ifdef FILEBROWSER
gfx_mode = emu_readGfxConfig();
#endif
// Force VGA if UP pressed
if (keypressed & MASK_JOY2_UP)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("VGA");
#endif
gfx_mode = CFG_VGA;
}
else {
if (keypressed & MASK_JOY2_LEFT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ST");
#endif
gfx_mode = CFG_ST;
}
else if (keypressed & MASK_JOY2_RIGHT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ILI");
#endif
gfx_mode = CFG_ILI;
}
}
if (gfx_mode == CFG_VGA) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
else
{
tft.begin(gfx_mode == CFG_ILI?MODE_TFTILI_320x240:MODE_TFTST_320x240);
}
#endif
if (keypressed & MASK_JOY2_DOWN) { if (keypressed & MASK_JOY2_DOWN) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig(); emu_eraseConfig();
delay(1000); delay(1000);
#endif
} }
else { else {
#ifdef FILEBROWSER
if (emu_readConfig()) { if (emu_readConfig()) {
autorun = true; autorun = true;
} }
#endif
} }
#ifdef FILEBROWSER
toggleMenu(true); toggleMenu(true);
#endif
} }
void emu_start(void) void emu_start(int vblms, void * callback, int forcetimervsync)
{ {
vgatimervsync = forcetimervsync?true:false;
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startRefresh();
if (callback != nullptr) {
vblCallback = callback;
}
myTimer.begin(vblCount, vblms);
#ifdef HAS_SND
emu_sndInit();
#endif
usbnavpad = 0; usbnavpad = 0;
} }

View file

@ -2,123 +2,14 @@
#define EMUAPI_H #define EMUAPI_H
#include "platform_config.h" #include "platform_config.h"
#include "emucfg.h"
//#define TIMER_REND 1
#define EXTRA_HEAP 0x10
// Title: < >
#define TITLE " ZX81/ZX80 Emulator"
#define ROMSDIR "z81"
#define emu_Init(ROM) {z81_Start(ROM); z81_Init(); }
#define emu_Step(x) {z81_Step();}
#define emu_Input(x) {z81_Input(x);}
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 2
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define R32(rgb) ((rgb>>16)&0xff)
#define G32(rgb) ((rgb>>8)&0xff)
#define B32(rgb) (rgb & 0xff)
#define ACTION_NONE 0 #define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16 #define ACTION_RUN1 1
#define ACTION_EXITKBD 128 #define ACTION_RUN2 2
#define ACTION_RUN1 129
#define ACTION_RUN2 130
#define ACTION_RUN3 131
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"qwertyuiop\x1a"
#define keylables_map0_1 (char *)" asdfghjkl\x19"
#define keylables_map0_2 (char *)" zxcvbnm,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'q','w','e','r','t','y','u','i','o','p',127, //lowecase
0,'a','s','d','f','g','h','j','k','l',10,
0,'z','x','c','v','b','n','m',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)" \x1a"
#define keylables_map1_1 (char *)" \x19"
#define keylables_map1_2 (char *)" <>:?"
#define keylables_map1_3 (char *)" =\x10 "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',127, // digit keys
0, 0,0,0,0,0,0,0,0,0,10,
0, 0,0,0,0,0,0,0,'<','>',':','?',
154,152,151,153, //U L R D
0,'=',' ',0
};
#define keylables_map2_0 (char *)" \" $ *()\x1a"
#define keylables_map2_1 (char *)" \x19"
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10 "
const unsigned short key_map2[] = {
0,'"',0,'$',0,0,0,'*','(',')',127, // shiftothers
0, 0,0,0,0,0,0,0,0,0,10,
0, 0,0,0,0,0,0,0,'<','>',':','?',
154,152,151,153, //U L R D
0,'=',' ',0
};
#define keylables_map3_0 (char *)"1234567890 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
154,152,151,153, //U L R D
0,0,' ',0
};
#define keylables_map4_0 (char *)" "
#define keylables_map4_1 (char *)" "
#define keylables_map4_2 (char *)" "
#define keylables_map4_3 (char *)" "
const unsigned short key_map4[] = {
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,
154,152,151,153, //U L R D
0,0,' ',0
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
154,152,151,153, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#define FORCE_VGATIMERVSYNC 1
#define SUPPORT_HIRES 1
#define MASK_JOY2_RIGHT 0x0001 #define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002 #define MASK_JOY2_LEFT 0x0002
@ -135,24 +26,25 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_BTN 0x1000 #define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000 #define MASK_KEY_USER4 0x2000
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#else extern void emu_init(int hires=0);
#define bool unsigned char extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif #endif
extern void emu_init(void);
extern void emu_start(void);
extern void emu_printf(const char * text); extern void emu_printf(const char * text);
extern void emu_printi(int val); extern void emu_printi(int val);
extern void emu_printh(int val); extern void emu_printh(int val);
extern void * emu_Malloc(unsigned int size); extern void * emu_Malloc(unsigned int size);
extern void * emu_MallocI(unsigned int size); extern void * emu_MallocI(unsigned int size);
extern void emu_Free(void * pt); extern void emu_Free(void * pt);
extern void * emu_SMalloc(unsigned int size);
extern void emu_SFree(void * pt);
extern int emu_FileOpen(const char * filepath, const char * mode); extern int emu_FileOpen(const char * filepath, const char * mode);
extern int emu_FileRead(void * buf, int size, int handler); extern int emu_FileRead(void * buf, int size, int handler);
extern int emu_FileWrite(void * buf, int size, int handler);
extern int emu_FileGetc(int handler); extern int emu_FileGetc(int handler);
extern int emu_FileSeek(int handler, int seek, int origin); extern int emu_FileSeek(int handler, int seek, int origin);
extern int emu_FileTell(int handler); extern int emu_FileTell(int handler);
@ -163,24 +55,23 @@ extern unsigned int emu_LoadFile(const char * filepath, void * buf, int size);
extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek); extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek);
extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index); extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index);
extern void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride); extern void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line); extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line);
extern void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride);
extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line); extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line);
extern void emu_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void); extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void); extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line); extern int emu_IsVga(void);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta); extern int emu_IsVgaHires(void);
extern bool menuActive(void); extern int menuActive(void);
extern char * menuSelection(void); extern char * menuSelection(void);
extern char * menuSecondSelection(void); extern char * menuSecondSelection(void);
extern void toggleMenu(bool on); extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick); extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void); extern int handleOSKB(void);
extern void toggleOSKB(bool forceon); extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void); extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly); extern int emu_SwapJoysticks(int statusOnly);
@ -189,6 +80,7 @@ extern int emu_ReadKeys(void);
extern int emu_GetPad(void); extern int emu_GetPad(void);
extern int emu_GetMouse(int *x, int *y, int *buts); extern int emu_GetMouse(int *x, int *y, int *buts);
extern int emu_MouseDetected(void); extern int emu_MouseDetected(void);
extern int emu_GetJoystick(void);
extern int emu_KeyboardDetected(void); extern int emu_KeyboardDetected(void);
extern int emu_ReadAnalogJoyX(int min, int max); extern int emu_ReadAnalogJoyX(int min, int max);
extern int emu_ReadAnalogJoyY(int min, int max); extern int emu_ReadAnalogJoyY(int min, int max);

View file

@ -0,0 +1,115 @@
#ifndef EMUCFG_H
#define EMUCFG_H
#include "wrapemu.h"
// Title: < >
#define TITLE " ZX81/ZX80 Emulator"
#define ROMSDIR "z81"
#define emu_Init(ROM) {z81_Start(ROM); z81_Init(); }
#define emu_Step(x) {z81_Step();}
#define emu_Input(x) {z81_Input(x);}
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 2
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
//#define CUSTOM_SND 1
//#define TIMER_REND 1
//#define EXTPAD 1
#define EXTRA_HEAP 0x10
#define FILEBROWSER 1
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"qwertyuiop\x1a"
#define keylables_map0_1 (char *)" asdfghjkl\x19"
#define keylables_map0_2 (char *)" zxcvbnm,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'q','w','e','r','t','y','u','i','o','p',127, //lowecase
0,'a','s','d','f','g','h','j','k','l',10,
0,'z','x','c','v','b','n','m',',','.',';','/',
0,0,0,0,
0,'+',' ','-'
};
#define keylables_map1_0 (char *)" \x1a"
#define keylables_map1_1 (char *)" \x19"
#define keylables_map1_2 (char *)" <>:?"
#define keylables_map1_3 (char *)" =\x10 "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',127, // digit keys
0, 0,0,0,0,0,0,0,0,0,10,
0, 0,0,0,0,0,0,0,'<','>',':','?',
154,152,151,153, //U L R D
0,'=',' ',0
};
#define keylables_map2_0 (char *)" \" $ *()\x1a"
#define keylables_map2_1 (char *)" \x19"
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10 "
const unsigned short key_map2[] = {
0,'"',0,'$',0,0,0,'*','(',')',127, // shiftothers
0, 0,0,0,0,0,0,0,0,0,10,
0, 0,0,0,0,0,0,0,'<','>',':','?',
154,152,151,153, //U L R D
0,'=',' ',0
};
#define keylables_map3_0 (char *)"1234567890 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
154,152,151,153, //U L R D
0,0,' ',0
};
#define keylables_map4_0 (char *)" "
#define keylables_map4_1 (char *)" "
#define keylables_map4_2 (char *)" "
#define keylables_map4_3 (char *)" "
const unsigned short key_map4[] = {
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,
154,152,151,153, //U L R D
0,0,' ',0
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
154,152,151,153, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#endif

View file

@ -4,13 +4,13 @@
#define TEECOMPUTER 1 #define TEECOMPUTER 1
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
//#define ILI9341 1 #define TFTSPI1 1
//#define ST7789 1 //#define HAS_T4_VGA 1
//#define TFTSPI1 1
#define HAS_T4_VGA 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
#define INVX 1 //#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1 #define PT8211 1
#else #else
@ -19,7 +19,11 @@
//#define INVX 1 //#define INVX 1
#define INVY 1 #define INVY 1
#define HAS_SND 1 #define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
/*
TFT/VGA driver
DMA TFT driver based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _T4_DSPH_
#define _T4_DSPH_
#ifdef __cplusplus
#include <Arduino.h>
#include <DMAChannel.h>
#endif
#include "platform_config.h"
#include "iopins.h"
#ifndef TFT_WIDTH
#define TFT_WIDTH 320
#endif
#define TFT_REALWIDTH 320
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 240
#endif
#define TFT_REALHEIGHT 240
typedef enum gfx_mode_t
{
MODE_UNDEFINED = 0,
MODE_TFTILI_320x240 = 1,
MODE_TFTST_320x240 = 2,
MODE_VGA_320x240 = 3,
MODE_VGA_320x480 = 4,
MODE_VGA_352x240 = 5,
MODE_VGA_352x480 = 6,
MODE_VGA_512x240 = 7,
MODE_VGA_512x480 = 8,
MODE_VGA_640x240 = 9,
MODE_VGA_640x480 = 10
} gfx_mode_t;
typedef enum gfx_error_t
{
GFX_OK = 0,
GFX_ERROR = -1
} gfx_error_t;
#ifdef __cplusplus
class T4_DSP
{
public:
T4_DSP();
gfx_error_t begin(gfx_mode_t mode);
gfx_mode_t getMode(void);
void startRefresh(void);
void stopRefresh();
int get_frame_buffer_size(int *width, int *height);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
// wait next Vsync
void waitSync();
void waitLine(int line);
// NoDMA functions
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
void writeLine(int width, int height, int y, uint16_t *buf);
void writeLinePal(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
void writeScreenPal(int width, int height, int stride, uint8_t *buf, uint16_t *palette16);
void writeLine8(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
protected:
static uint8_t _rst, _cs, _dc;
static uint8_t _mosi, _sclk;
static uint8_t _vsync_pin;
static DMAChannel flexio1DMA;
static DMAChannel flexio2DMA;
void tft_setup(bool isST);
static void TFT_isr(void);
static void QT3_isr(void);
};
#endif
#endif

View file

@ -3,134 +3,21 @@ extern "C" {
#include "emuapi.h" #include "emuapi.h"
} }
extern "C" {
#include "zx81.h"
}
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
TFT_T_DMA tft;
#else
#include "tft_t_dma.h"
TFT_T_DMA tft = TFT_T_DMA(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO, TFT_TOUCH_CS, TFT_TOUCH_INT);
#endif
bool vgaMode = false;
static unsigned char palette8[PALETTE_SIZE];
static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
static int skip=0;
static elapsedMicros tius;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
//Serial.println("%d: %d %d %d\n", index, r,g,b);
palette8[index] = RGBVAL8(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.waitSync();
#else
while (vbl==vb) {};
#endif
}
}
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.writeLine(width,1,line, VBuf, palette8);
#else
tft.writeLine(width,1,line, VBuf, palette16);
#endif
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine16(width,height,line, VBuf);
#else
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8);
#else
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
#endif
}
}
}
int emu_FrameSkip(void)
{
return skip;
}
void * emu_LineBuffer(int line)
{
if (!vgaMode) {
return (void*)tft.getLineBuffer(line);
}
}
#include "t4_dsp.h"
extern T4_DSP tft;
// **************************************************** // ****************************************************
// the setup() method runs once, when the sketch starts // the setup() method runs once, when the sketch starts
// **************************************************** // ****************************************************
void setup() { void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init(); emu_init();
} }
static void vbl(void) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
// **************************************************** // ****************************************************
// the loop() method runs continuously // the loop() method runs continuously
@ -141,60 +28,15 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick); int action = handleMenu(bClick);
char * filename = menuSelection(); char * filename = menuSelection();
if (action == ACTION_RUN1) { if (action == ACTION_RUN1) {
toggleMenu(false); emu_start(16666,nullptr);
vgaMode = false;
emu_start();
emu_Init(filename); emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 16666); //to run every 16.666ms
} }
delay(20); delay(20);
} }
else { else {
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick); emu_Input(bClick);
emu_Step(); emu_Step();
delay(10);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// emu_Input(bClick);
//}
} }
} }
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
//mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,232 +0,0 @@
/*
Based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _TFT_T_DMAH_
#define _TFT_T_DMAH_
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include <DMAChannel.h>
#endif
#include "tft_t_dma_config.h"
#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b )
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define R16(rgb) ((rgb>>8)&0xf8)
#define G16(rgb) ((rgb>>3)&0xfc)
#define B16(rgb) ((rgb<<3)&0xf8)
#define PAL_COLOR_MASK 0xff
#ifdef LOHRES
#define TFT_WIDTH 240
#define TFT_REALWIDTH 240
#else
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#endif
#define TFT_HEIGHT 192
#define TFT_REALHEIGHT 240
//#define WIDTH 272
//#define HEIGHT 228
#define LINES_PER_BLOCK 64
#define NR_OF_BLOCK 4
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
#ifdef ILI9341
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0D
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_MH 0x04
#define TFT_CASET ILI9341_CASET
#define TFT_PASET ILI9341_PASET
#define TFT_RAMWR ILI9341_RAMWR
#define TFT_MADCTL ILI9341_MADCTL
#endif
#ifdef ST7789
#define ST7735_NOP 0x00
#define ST7735_SWRESET 0x01
#define ST7735_RDDID 0x04
#define ST7735_RDDST 0x09
#define ST7735_SLPIN 0x10
#define ST7735_SLPOUT 0x11
#define ST7735_PTLON 0x12
#define ST7735_NORON 0x13
#define ST7735_INVOFF 0x20
#define ST7735_INVON 0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_RAMRD 0x2E
#define ST7735_PTLAR 0x30
#define ST7735_COLMOD 0x3A
#define ST7735_MADCTL 0x36
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_DISSET5 0xB6
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_RDID1 0xDA
#define ST7735_RDID2 0xDB
#define ST7735_RDID3 0xDC
#define ST7735_RDID4 0xDD
#define ST7735_PWCTR6 0xFC
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_MADCTL_BGR 0x08
#define ST77XX_MADCTL_MH 0x04
#define TFT_CASET ST7735_CASET
#define TFT_PASET ST7735_RASET
#define TFT_RAMWR ST7735_RAMWR
#define TFT_MADCTL ST7735_MADCTL
#endif
#ifdef __cplusplus
class TFT_T_DMA
{
public:
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
void begin(void);
void flipscreen(bool flip);
boolean isflipped(void);
void startDMA(void);
void stopDMA();
int get_frame_buffer_size(int *width, int *height);
// Touch screen functions
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
// NoDMA functions
void writeScreenNoDma(const uint16_t *pcolors);
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
uint16_t * getLineBuffer(int j);
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int y, uint16_t *buf);
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
protected:
uint8_t _rst, _cs, _dc;
uint8_t _miso, _mosi, _sclk;
uint8_t _touch_irq=255, _touch_cs=255;
bool flipped=false;
void wait(void);
void enableTouchIrq();
};
#endif
#endif

View file

@ -1,13 +0,0 @@
#include "platform_config.h"
//#define ST7789 1
//#define ILI9341 1
#define TFT_LINEARINT 1
#define LINEARINT_HACK 1
//#define FLIP_SCREEN 1
//#define TFT_DEBUG 1
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
//#define TFT_STATICFB 1
#endif

View file

@ -1,53 +0,0 @@
/*
Wrapping class to extend VGA_T4 to TFT_T_DMA
*/
#ifndef _VGA_T_DMAH_
#define _VGA_T_DMAH_
#ifdef __cplusplus
#include <VGA_t4.h>
#endif
#define RGBVAL16(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
#ifdef __cplusplus
class TFT_T_DMA: public VGA_T4
{
public:
// Fake touch screen functions
bool isTouching(void) { return false; }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { }
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { };
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax) { }
// fake DMA functions
void startDMA(void) { };
void stopDMA(void) { };
// fake no DMA functions
void writeScreenNoDma(const vga_pixel *pcolors) { writeScreen(pcolors); }
void fillScreenNoDma(vga_pixel color) { clear(color); }
void drawTextNoDma(int16_t x, int16_t y, const char * text, vga_pixel fgcolor, vga_pixel bgcolor, bool doublesize) { drawText(x,y,text,fgcolor,bgcolor,doublesize); }
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, vga_pixel color) { drawRect(x, y, w, h, color); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap) { drawSprite(x, y, bitmap); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh) { drawSprite(x, y, bitmap, croparx, cropary, croparw, croparh); }
};
#endif
#endif

View file

@ -28,7 +28,7 @@ int zx80=0;
int autoload=1; int autoload=1;
struct { unsigned char R,G,B; } Palette[16] = { struct { unsigned char R,G,B; } Palette[2] = {
{ 0, 0, 0}, { 0, 0, 0},
{ 255, 255, 255} { 255, 255, 255}
}; };
@ -225,7 +225,7 @@ emu_DrawVsync();
d <<= 1; d <<= 1;
} }
} }
emu_DrawLine(&XBuf[0], WIDTH, HEIGHT, y); emu_DrawLinePal16(&XBuf[0], WIDTH, HEIGHT, y);
buf += (ZX_VID_FULLWIDTH/8); buf += (ZX_VID_FULLWIDTH/8);
} }
} }

View file

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#ifdef HAS_T4_VGA #include <Arduino.h>
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#ifdef HAS_USBKEY #ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info #include "USBHost_t36.h" // Read this header first for key info
USBHost myusb; USBHost myusb;
USBHub hub1(myusb); USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb); KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb); USBHIDParser hid1(myusb);
MouseController mouse1(myusb); MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb); MIDIDevice midi1(myusb);
#endif #endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void); static bool emu_writeConfig(void);
static bool emu_readConfig(void); static bool emu_readConfig(void);
static bool emu_eraseConfig(void); static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false; static bool mouseDetected = false;
static bool keyboardDetected = false; static bool keyboardDetected = false;
@ -34,12 +40,13 @@ static File file;
#define MAX_FILES 64 #define MAX_FILES 64
#define AUTORUN_FILENAME "autorun.txt" #define AUTORUN_FILENAME "autorun.txt"
#define GFX_CFG_FILENAME "gfxmode.txt"
#define MAX_FILENAME_SIZE 24 #define MAX_FILENAME_SIZE 34
#define MAX_MENULINES 9 #define MAX_MENULINES 9
#define TEXT_HEIGHT 16 #define TEXT_HEIGHT 16
#define TEXT_WIDTH 8 #define TEXT_WIDTH 8
#define MENU_FILE_XOFFSET (6*TEXT_WIDTH) #define MENU_FILE_XOFFSET (2*TEXT_WIDTH)
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT) #define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH) #define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT) #define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
@ -53,7 +60,8 @@ static File file;
#define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8) #define MENU_VGA_XOFFSET (MENU_FILE_XOFFSET+MENU_FILE_W+8)
#define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37) #define MENU_VGA_YOFFSET (MENU_VBAR_YOFFSET+MENU_FILE_H-32-37)
extern TFT_T_DMA tft; #include "t4_dsp.h"
T4_DSP tft;
static int nbFiles=0; static int nbFiles=0;
static int curFile=0; static int curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]=""; static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true; static bool menuRedraw=true;
static bool autorun=false; static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys; static const unsigned short * keys;
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
@ -158,6 +168,29 @@ void emu_Free(void * pt)
free(pt); free(pt);
} }
#define SMEMPOOL (0x800000)
EXTMEM static unsigned char slowmem[SMEMPOOL];
static int slowmempt = 0;
void * emu_SMalloc(unsigned int size)
{
void * mem = (void*)&slowmem[slowmempt];
slowmempt += size;
if ( slowmempt > SMEMPOOL ) {
mem = NULL;
emu_printf("failure to allocate slow");
}
else {
emu_printf("could allocate slow static ");
emu_printf(size);
}
return mem;
}
void emu_SFree(void * pt)
{
}
/******************************** /********************************
* Input and keyboard * Input and keyboard
********************************/ ********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif #endif
if ( row & 0x02 ) retval |= MASK_JOY2_BTN; if ( row & 0x02 ) retval |= MASK_JOY2_BTN;
#ifdef EXTPAD
if ( sh_pressed ) retval |= MASK_KEY_USER3;
if ( fn_pressed ) retval |= MASK_KEY_USER1;
digitalWrite(KLED, 0);
#else
// Handle LED flash // Handle LED flash
uint32_t time_ms=millis(); uint32_t time_ms=millis();
if ((time_ms-last_t_ms) > 100) { if ((time_ms-last_t_ms) > 100) {
@ -412,8 +451,9 @@ int emu_ReadKeys(void)
if ( key_fn ) retval |= MASK_KEY_USER2; if ( key_fn ) retval |= MASK_KEY_USER2;
if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1; if ( ( key_fn ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) ) if ( (fn_pressed) && (sh_pressed) )
#else #else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) ) || (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) { while (true) {
; ;
} }
#endif #endif
} }
emu_GetJoystick();
return (retval); return (retval);
} }
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
} }
int emu_GetMouse(int *x, int *y, int *buts) { int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) { if (mouse1.available()) {
*buts = mouse1.getButtons(); *buts = mouse1.getButtons();
*x = mouse1.getMouseX(); *x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
return 0; return 0;
} }
#ifdef HAS_USBKEY int emu_GetJoystick(void) {
#if defined(HAS_USB) && (HAS_USBJOY)
for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++) {
if (joysticks[joystick_index].available()) {
uint64_t axis_mask = joysticks[joystick_index].axisMask();
uint64_t axis_changed_mask = joysticks[joystick_index].axisChangedMask();
uint32_t buttons = joysticks[joystick_index].getButtons();
Serial.printf("Joystick(%d): buttons = %x", joystick_index, buttons);
Serial.println();
}
}
return 1;
#endif
return 0;
}
#if defined(HAS_USB) && (HAS_USBKEY)
void OnPress(auto key) void OnPress(auto key)
{ {
keyboardDetected = true; keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0); return (keyboardDetected?1:0);
} }
#ifdef HAS_USBKEY #if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16]; static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0; static unsigned char midiLastCmd=0;
static int midiDataCnt=0; static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif #endif
void emu_MidiOnDataReceived(unsigned char value) { void emu_MidiOnDataReceived(unsigned char value) {
#if defined(HAS_USB) && (HAS_USBMIDI)
#ifdef HAS_USBKEY
//Serial.println(value, HEX); //Serial.println(value, HEX);
//10000000 = 128 = note off //10000000 = 128 = note off
//10010000 = 144 = note on //10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/******************************** /********************************
* Menu file loader UI * Menu file loader UI
********************************/ ********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) { static int readNbFiles(void) {
int totalFiles = 0; int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles; return totalFiles;
} }
void backgroundMenu(void) { void backgroundMenu(void) {
menuRedraw=true; menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00)); tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick) int handleMenu(uint16_t bClick)
{ {
if (autorun) { if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1); return (ACTION_RUN1);
} }
int action = ACTION_NONE; int action = ACTION_NONE;
if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) ) { if ( (bClick & MASK_JOY2_BTN) || (bClick & MASK_JOY1_BTN) || ( bClick & MASK_KEY_USER2 ) ) {
char newpath[MAX_FILENAME_PATH]; char newpath[MAX_FILENAME_PATH];
strcpy(newpath, selection); strcpy(newpath, selection);
strcat(newpath, "/"); strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection); File file = SD.open(selection);
if (file.isDirectory()) { if (file.isDirectory()) {
curFile = 0; curFile = 0;
nbFiles = readNbFiles(); nbFiles = readNbFiles();
menuRedraw=true;
} }
else { else
action = ACTION_RUN1; {
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
if (key_extmode) { if ( (key_extmode) || ( key_sh) ) {
emu_writeConfig(); emu_writeConfig();
} }
if ( tft.getMode() < MODE_VGA_320x240) {
if ( bClick & MASK_KEY_USER2 ) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
}
//emu_SwapJoysticks(0);
#endif #endif
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
} }
menuRedraw=true;
} }
else if ( bClick & MASK_KEY_USER1 ) { else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true; menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/"); strcat(second_selection, "/");
strcat(second_selection, second_selected_filename); strcat(second_selection, second_selected_filename);
action = ACTION_RUN2; action = ACTION_RUN2;
} }
else if ( bClick & MASK_KEY_USER2 ) {
menuRedraw=true;
//action = ACTION_RUN3;
emu_SwapJoysticks(0);
}
else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) { else if ( (bClick & MASK_JOY2_UP) || (bClick & MASK_JOY1_UP) ) {
if (curFile!=0) { if (curFile!=0) {
menuRedraw=true; menuRedraw=true;
curFile--; curFile--;
} }
} }
else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) { else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) {
if ((curFile-9)>=0) { if ((curFile-9)>=0) {
menuRedraw=true; menuRedraw=true;
curFile -= 9; curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
menuRedraw=true; menuRedraw=true;
} }
} }
else if ( (bClick & MASK_JOY2_LEFT) || (bClick & MASK_JOY1_LEFT) ) { else if ( (bClick & MASK_JOY2_RIGHT) || (bClick & MASK_JOY1_RIGHT) ) {
if ((curFile<(nbFiles-9)) && (nbFiles)) { if ((curFile<(nbFiles-9)) && (nbFiles)) {
curFile += 9; curFile += 9;
menuRedraw=true; menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action); return (action);
} }
bool menuActive(void) int menuActive(void)
{ {
return (menuOn); return (menuOn?1:0);
} }
void toggleMenu(bool on) { void toggleMenu(int on) {
if (on) { if (on) {
menuOn=true; menuOn=true;
backgroundMenu(); backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{ {
return (second_selection); return (second_selection);
} }
#endif
/******************************** /********************************
* OSKB handling * OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0}; char c[4] = {' ',0,' ',0};
const char * cpt = str; const char * cpt = str;
int i=0; int i=0;
int fb_width,fb_height; int fb_width,fb_height,fbstride;
tft.get_frame_buffer_size(&fb_width, &fb_height);
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0); int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0); int line = row + (bottom?2:0);
while ((c[1] = *cpt++)) while ((c[1] = *cpt++))
@ -1150,7 +1218,7 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
if (row&1) bg = (i&1)?RGBVAL16(0xff,0xff,0xff):RGBVAL16(0xe0,0xe0,0xe0); 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); else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,0xff,0xff);
if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff); if ( (cxpos == i) && (cypos == line) ) bg = RGBVAL16(0x00,0xff,0xff);
tft.drawTextNoDma(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false); tft.drawText(OSKBXOFF+xoff+24*i,OSKBYOFF+ypos+8*row , &c[0], RGBVAL16(0x00,0x00,0x00), bg, false);
i++; i++;
} }
} }
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval; return retval;
} }
void toggleOSKB(bool forceon) { void toggleOSKB(int forceon) {
if (forceon) { if (forceon) {
oskbOn = true; oskbOn = true;
drawOSKB(); drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#endif #endif
} }
int emu_FileWrite(void * buf, int size, int handler)
{
// emu_printf("emu_FileWrite");
// emu_printi(handler);
#ifdef HCFH
return (file.write(buf, size));
#else
return (getFileHandler(handler).write(buf, size));
#endif
}
int emu_FileGetc(int handler) { int emu_FileGetc(int handler) {
// emu_printf("FileGetc"); // emu_printf("FileGetc");
// emu_printi(handler); // emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize); emu_printf(filesize);
lofile.close(); lofile.close();
} }
else {
emu_printf("filesize failed");
}
return(filesize); return(filesize);
} }
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
SD.remove (ROMSDIR "/" AUTORUN_FILENAME); SD.remove (ROMSDIR "/" AUTORUN_FILENAME);
} }
static bool emu_writeGfxConfig(char * display_type)
{
bool retval = false;
SD.remove ("/" GFX_CFG_FILENAME);
if (strcmp(display_type, "VGA")) {
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_CREAT | O_WRITE)))
{
if (lofile.write(display_type, strlen(display_type)) != strlen(display_type)) {
emu_printf("GFX config write failed");
}
else {
retval = true;
}
lofile.close();
}
}
return retval;
}
#define CFG_VGA 0
#define CFG_ILI 1
#define CFG_ST 2
static int emu_readGfxConfig(void)
{
int retval = CFG_VGA; // No file = VGA
if ((lofile = SD.open("/" GFX_CFG_FILENAME, O_READ)))
{
unsigned int filesize = lofile.size();
if (filesize == 2) // "ST"
{
retval = CFG_ST;
}
else if (filesize == 3) // "ILI"
{
retval = CFG_ILI;
}
lofile.close();
}
return retval;
}
/******************************** /********************************
* File IO compatibility * File IO compatibility
********************************/ ********************************/
@ -1670,62 +1794,249 @@ FRESULT f_mkdir (const char* path)
/******************************** /********************************
* Initialization * GFX wrapper
********************************/ ********************************/
void emu_init(void) static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
volatile boolean vgatimervsync=false;
static void (*vblCallback)(void) = nullptr;
static int skip=0;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if ( tft.getMode() >= MODE_VGA_320x240 ) {
if (vgatimervsync) {
while (vbl==vb) {};
}
else {
tft.waitSync();
}
}
else {
while (vbl==vb) {};
}
if (vblCallback != nullptr) {
vblCallback();
}
}
void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride)
{
if (skip == 0) {
tft.writeScreenPal(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
}
}
void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLinePal(width,height,line, VBuf, palette16);
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine(width,height,line, VBuf);
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (skip == 0) {
tft.writeLine8(width,height,line, VBuf, palette16);
}
}
int emu_IsVga(void)
{
return (tft.getMode() >= MODE_VGA_320x240?1:0);
}
int emu_IsVgaHires(void)
{
return (tft.getMode() >= MODE_VGA_640x240?1:0);
}
int emu_FrameSkip(void)
{
return skip;
}
/********************************
* AUDIO wrapper
********************************/
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif
/********************************
* Initialization
********************************/
void emu_init(int hires)
{ {
Serial.begin(115200); Serial.begin(115200);
vgahires = hires;
#ifdef HAS_USBKEY #ifdef HAS_USB
myusb.begin(); myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress); keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease); keyboard1.attachRelease(OnRelease);
#endif #endif
#endif
while (!SD.begin(SD_CS)) #ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{ {
Serial.println("SD begin failed, retrying..."); Serial.println("No SD card detected");
delay(1000);
} }
strcpy(selection,ROMSDIR); strcpy(selection,ROMSDIR);
FileHandlersInit(); FileHandlersInit();
nbFiles = readNbFiles(); nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles); Serial.println(nbFiles);
#endif
emu_InitJoysticks(); emu_InitJoysticks();
#ifdef SWAP_JOYSTICK #ifdef SWAP_JOYSTICK
joySwapped = true; joySwapped = true;
#else #else
joySwapped = false; joySwapped = false;
#endif #endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
int keypressed = emu_ReadKeys(); int keypressed = emu_ReadKeys();
#ifdef HAS_T4_VGA
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
#else
int gfx_mode = CFG_VGA; // default
#ifdef FILEBROWSER
gfx_mode = emu_readGfxConfig();
#endif
// Force VGA if UP pressed
if (keypressed & MASK_JOY2_UP)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("VGA");
#endif
gfx_mode = CFG_VGA;
}
else {
if (keypressed & MASK_JOY2_LEFT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ST");
#endif
gfx_mode = CFG_ST;
}
else if (keypressed & MASK_JOY2_RIGHT)
{
#ifdef FILEBROWSER
emu_writeGfxConfig("ILI");
#endif
gfx_mode = CFG_ILI;
}
}
if (gfx_mode == CFG_VGA) {
if (vgahires) {
tft.begin(MODE_VGA_640x480);
}
else {
tft.begin(MODE_VGA_320x240);
}
}
else
{
tft.begin(gfx_mode == CFG_ILI?MODE_TFTILI_320x240:MODE_TFTST_320x240);
}
#endif
if (keypressed & MASK_JOY2_DOWN) { if (keypressed & MASK_JOY2_DOWN) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) ); tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true); tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig(); emu_eraseConfig();
delay(1000); delay(1000);
#endif
} }
else { else {
#ifdef FILEBROWSER
if (emu_readConfig()) { if (emu_readConfig()) {
autorun = true; autorun = true;
} }
#endif
} }
#ifdef FILEBROWSER
toggleMenu(true); toggleMenu(true);
#endif
} }
void emu_start(void) void emu_start(int vblms, void * callback, int forcetimervsync)
{ {
vgatimervsync = forcetimervsync?true:false;
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startRefresh();
if (callback != nullptr) {
vblCallback = callback;
}
myTimer.begin(vblCount, vblms);
#ifdef HAS_SND
emu_sndInit();
#endif
usbnavpad = 0; usbnavpad = 0;
} }

View file

@ -2,126 +2,14 @@
#define EMUAPI_H #define EMUAPI_H
#include "platform_config.h" #include "platform_config.h"
#include "emucfg.h"
#define CUSTOM_SND 1
//#define TIMER_REND 1
#define EXTRA_HEAP 0x10
// Title: < >
#define TITLE " Apple2 Emulator "
#define ROMSDIR "apple2"
#define emu_Init(ROM) { aiie_Init(); aiie_Start(ROM);}
#define emu_Step(x) { aiie_Step(); }
#define emu_Input(x) { aiie_Input(x); }
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define R32(rgb) ((rgb>>16)&0xff)
#define G32(rgb) ((rgb>>8)&0xff)
#define B32(rgb) (rgb & 0xff)
#define ACTION_NONE 0 #define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16 #define ACTION_RUN1 1
#define ACTION_EXITKBD 128 #define ACTION_RUN2 2
#define ACTION_RUN1 129
#define ACTION_RUN2 130
#define ACTION_RUN3 131
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"qwertyuiop\x1a"
#define keylables_map0_1 (char *)" asdfghjkl\x19"
#define keylables_map0_2 (char *)" zxcvbnm,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'q','w','e','r','t','y','u','i','o','p',127, //lowecase
0,'a','s','d','f','g','h','j','k','l',10,
0,'z','x','c','v','b','n','m',',','.',';','/',
0,0,0,0, //U L R D
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
#define keylables_map1_3 (char *)" "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit 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,0,0,
0,0,' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
153,151,150,152, //U L R D
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
129,130,131,132,133,134,135,136,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,0,0,
0,0,' ',0
};
#define keylables_map4_0 (char *)"QWERTYUIOP@"
#define keylables_map4_1 (char *)" ASDFGHJKL\x19"
#define keylables_map4_2 (char *)" ZXCVBNM<>:?"
#define keylables_map4_3 (char *)" =\x10_"
const unsigned short key_map4[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M','<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#define FORCE_VGATIMERVSYNC 1
#define SUPPORT_HIRES 1
#define MASK_JOY2_RIGHT 0x0001 #define MASK_JOY2_RIGHT 0x0001
#define MASK_JOY2_LEFT 0x0002 #define MASK_JOY2_LEFT 0x0002
@ -138,22 +26,25 @@ const unsigned short matkeys[] = {
#define MASK_JOY1_BTN 0x1000 #define MASK_JOY1_BTN 0x1000
#define MASK_KEY_USER4 0x2000 #define MASK_KEY_USER4 0x2000
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
extern void emu_init(int hires=0);
extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif #endif
extern void emu_init(void);
extern void emu_start(void);
extern void emu_printf(const char * text); extern void emu_printf(const char * text);
extern void emu_printi(int val); extern void emu_printi(int val);
extern void emu_printh(int val); extern void emu_printh(int val);
extern void * emu_Malloc(unsigned int size); extern void * emu_Malloc(unsigned int size);
extern void * emu_MallocI(unsigned int size); extern void * emu_MallocI(unsigned int size);
extern void emu_Free(void * pt); extern void emu_Free(void * pt);
extern void * emu_SMalloc(unsigned int size);
extern void emu_SFree(void * pt);
extern int emu_FileOpen(const char * filepath, const char * mode); extern int emu_FileOpen(const char * filepath, const char * mode);
extern int emu_FileRead(void * buf, int size, int handler); extern int emu_FileRead(void * buf, int size, int handler);
extern int emu_FileWrite(void * buf, int size, int handler);
extern int emu_FileGetc(int handler); extern int emu_FileGetc(int handler);
extern int emu_FileSeek(int handler, int seek, int origin); extern int emu_FileSeek(int handler, int seek, int origin);
extern int emu_FileTell(int handler); extern int emu_FileTell(int handler);
@ -164,24 +55,23 @@ extern unsigned int emu_LoadFile(const char * filepath, void * buf, int size);
extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek); extern unsigned int emu_LoadFileSeek(const char * filepath, void * buf, int size, int seek);
extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index); extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index);
extern void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride); extern void emu_DrawLinePal16(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine(unsigned char * VBuf, int width, int height, int line);
extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line); extern void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line);
extern void emu_DrawScreenPal16(unsigned char * VBuf, int width, int height, int stride);
extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line); extern void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line);
extern void emu_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void); extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void); extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line); extern int emu_IsVga(void);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta); extern int emu_IsVgaHires(void);
extern bool menuActive(void); extern int menuActive(void);
extern char * menuSelection(void); extern char * menuSelection(void);
extern char * menuSecondSelection(void); extern char * menuSecondSelection(void);
extern void toggleMenu(bool on); extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick); extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void); extern int handleOSKB(void);
extern void toggleOSKB(bool forceon); extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void); extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly); extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ extern int emu_ReadKeys(void);
extern int emu_GetPad(void); extern int emu_GetPad(void);
extern int emu_GetMouse(int *x, int *y, int *buts); extern int emu_GetMouse(int *x, int *y, int *buts);
extern int emu_MouseDetected(void); extern int emu_MouseDetected(void);
extern int emu_GetJoystick(void);
extern int emu_KeyboardDetected(void); extern int emu_KeyboardDetected(void);
extern int emu_ReadAnalogJoyX(int min, int max); extern int emu_ReadAnalogJoyX(int min, int max);
extern int emu_ReadAnalogJoyY(int min, int max); extern int emu_ReadAnalogJoyY(int min, int max);

View file

@ -0,0 +1,115 @@
#ifndef EMUCFG_H
#define EMUCFG_H
#include "wrapemu.h"
// Title: < >
#define TITLE " Apple2 Emulator "
#define ROMSDIR "apple2"
#define emu_Init(ROM) { aiie_Init(); aiie_Start(ROM);}
#define emu_Step(x) { aiie_Step(); }
#define emu_Input(x) { aiie_Input(x); }
#define MAX_FILENAME_PATH 64
#define NB_FILE_HANDLER 4
#define PALETTE_SIZE 256
#define VID_FRAME_SKIP 0x0
#define TFT_VBUFFER_YCROP 0
#define SINGLELINE_RENDERING 1
#define CUSTOM_SND 1
//#define TIMER_REND 1
//#define EXTPAD 1
#define EXTRA_HEAP 0x10
#define FILEBROWSER 1
#ifdef KEYMAP_PRESENT
#define keylables_map0_0 (char *)"qwertyuiop\x1a"
#define keylables_map0_1 (char *)" asdfghjkl\x19"
#define keylables_map0_2 (char *)" zxcvbnm,.;/"
#define keylables_map0_3 (char *)" +\x10-"
const unsigned short key_map0[] = {
'q','w','e','r','t','y','u','i','o','p',127, //lowecase
0,'a','s','d','f','g','h','j','k','l',10,
0,'z','x','c','v','b','n','m',',','.',';','/',
0,0,0,0, //U L R D
0,'+',' ','-'
};
#define keylables_map1_0 (char *)"1234567890 "
#define keylables_map1_1 (char *)" "
#define keylables_map1_2 (char *)" "
#define keylables_map1_3 (char *)" "
const unsigned short key_map1[] = {
'1','2','3','4','5','6','7','8','9','0',0, // digit 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,0,0,
0,0,' ',0
};
#define keylables_map2_0 (char *)"!\"#$%^&*()@"
#define keylables_map2_1 (char *)" "
#define keylables_map2_2 (char *)" <>:?"
#define keylables_map2_3 (char *)" =\x10_"
const unsigned short key_map2[] = {
'!','"','#','$','%','^','&','*','(',')','@', // shiftothers
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,'<','>',':','?',
153,151,150,152, //U L R D
0,'=',' ','_'
};
#define keylables_map3_0 (char *)"\x11\x12\x13\x14\x15\x16\x17\x18 "
#define keylables_map3_1 (char *)" "
#define keylables_map3_2 (char *)" "
#define keylables_map3_3 (char *)" "
const unsigned short key_map3[] = {
129,130,131,132,133,134,135,136,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,0,0,
0,0,' ',0
};
#define keylables_map4_0 (char *)"QWERTYUIOP@"
#define keylables_map4_1 (char *)" ASDFGHJKL\x19"
#define keylables_map4_2 (char *)" ZXCVBNM<>:?"
#define keylables_map4_3 (char *)" =\x10_"
const unsigned short key_map4[] = {
'Q','W','E','R','T','Y','U','I','O','P','@', //shift uppercase
0,'A','S','D','F','G','H','J','K','L',10,
0,'Z','X','C','V','B','N','M','<','>',':','?',
0,0,0,0,
0,'=',' ','_'
};
#define keylables_map5_0 (char *)" "
#define keylables_map5_1 (char *)" "
#define keylables_map5_2 (char *)" "
#define keylables_map5_3 (char *)" "
const unsigned short key_map5[] = {
0,0,0,0,0,0,0,0,0,0,0, // extra keys
0, 0,0,0,0,0,0,0,0,0,0,
0, 0,0,0,0,0,0,0,0,0,0,0,
153,151,150,152, //U L R D
0,0,' ',0
};
const unsigned short matkeys[] = {
0x004,0x008,0x108,0x104,0x208,0x204,0x308,0x304,0x408,0x404,0x410, // row 1
0x502,0x002,0x020,0x102,0x120,0x202,0x220,0x302,0x320,0x402,0x420, // row 2
0x508,0x001,0x040,0x101,0x140,0x201,0x240,0x210,0x340,0x301,0x401,0x440, // row 3
0x504,0x520,0x540,0x501, // UP LEFT RIGHT DOWN
0x510,0x010,0x110,0x310, // row 4
};
#endif
#endif

View file

@ -4,13 +4,13 @@
#define TEECOMPUTER 1 #define TEECOMPUTER 1
#ifdef TEECOMPUTER #ifdef TEECOMPUTER
//#define ILI9341 1 #define TFTSPI1 1
//#define ST7789 1 //#define HAS_T4_VGA 1
//#define TFTSPI1 1
#define HAS_T4_VGA 1
//#define HAS_SND 1 //#define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
#define INVX 1 //#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1 #define PT8211 1
#else #else
@ -18,8 +18,12 @@
#define HAS_T4_VGA 1 #define HAS_T4_VGA 1
//#define INVX 1 //#define INVX 1
#define INVY 1 #define INVY 1
#define HAS_SND 1 //#define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1 #define HAS_USBKEY 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1
#endif #endif

View file

@ -7,15 +7,8 @@ extern "C" {
#include <Arduino.h> #include <Arduino.h>
#include "bios-font.h" #include "bios-font.h"
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
typedef uint8_t Pixel;
#define RGBVAL(r,g,b) RGBVAL8(r,g,b)
#else
#include "tft_t_dma.h"
typedef uint16_t Pixel; typedef uint16_t Pixel;
#define RGBVAL(r,g,b) RGBVAL16(r,g,b) #define RGBVAL(r,g,b) RGBVAL16(r,g,b)
#endif
#include "globals.h" #include "globals.h"
#include "applevm.h" #include "applevm.h"
@ -83,14 +76,15 @@ void PlfDisplay::redraw()
{ {
} }
static Pixel linebuffer[DISPLAYWIDTH];
void PlfDisplay::blit(AiieRect r) void PlfDisplay::blit(AiieRect r)
{ {
uint8_t *videoBuffer = g_vm->videoBuffer; // FIXME: poking deep uint8_t *videoBuffer = g_vm->videoBuffer; // FIXME: poking deep
uint16_t pixel; uint16_t pixel;
for (uint8_t y=r.top; y<=r.bottom; y++) { for (uint8_t y=r.top; y<=r.bottom; y++) {
Pixel * scrlinept = (Pixel *)emu_LineBuffer(y); Pixel * scrlinept = &linebuffer[0]; // (Pixel *)emu_LineBuffer(y);
scrlinept += (TFT_WIDTH - (r.right - r.left))/2; scrlinept += (DISPLAYWIDTH - (r.right - r.left))/2;
for (uint16_t x=r.left; x<=r.right; x++) { for (uint16_t x=r.left; x<=r.right; x++) {
pixel = y * (DISPLAYRUN >> 1) + (x >> 1); pixel = y * (DISPLAYRUN >> 1) + (x >> 1);
uint8_t colorIdx; uint8_t colorIdx;
@ -101,6 +95,7 @@ void PlfDisplay::blit(AiieRect r)
} }
scrlinept[x] = loresPixelColors[colorIdx]; scrlinept[x] = loresPixelColors[colorIdx];
} }
emu_DrawLine16(&linebuffer[0], DISPLAYWIDTH, 200 /*DISPLAYHEIGHT*/, y);
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
/*
TFT/VGA driver
DMA TFT driver based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _T4_DSPH_
#define _T4_DSPH_
#ifdef __cplusplus
#include <Arduino.h>
#include <DMAChannel.h>
#endif
#include "platform_config.h"
#include "iopins.h"
#ifndef TFT_WIDTH
#define TFT_WIDTH 320
#endif
#define TFT_REALWIDTH 320
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 240
#endif
#define TFT_REALHEIGHT 240
typedef enum gfx_mode_t
{
MODE_UNDEFINED = 0,
MODE_TFTILI_320x240 = 1,
MODE_TFTST_320x240 = 2,
MODE_VGA_320x240 = 3,
MODE_VGA_320x480 = 4,
MODE_VGA_352x240 = 5,
MODE_VGA_352x480 = 6,
MODE_VGA_512x240 = 7,
MODE_VGA_512x480 = 8,
MODE_VGA_640x240 = 9,
MODE_VGA_640x480 = 10
} gfx_mode_t;
typedef enum gfx_error_t
{
GFX_OK = 0,
GFX_ERROR = -1
} gfx_error_t;
#ifdef __cplusplus
class T4_DSP
{
public:
T4_DSP();
gfx_error_t begin(gfx_mode_t mode);
gfx_mode_t getMode(void);
void startRefresh(void);
void stopRefresh();
int get_frame_buffer_size(int *width, int *height);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
// wait next Vsync
void waitSync();
void waitLine(int line);
// NoDMA functions
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
void writeLine(int width, int height, int y, uint16_t *buf);
void writeLinePal(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
void writeScreenPal(int width, int height, int stride, uint8_t *buf, uint16_t *palette16);
void writeLine8(int width, int height, int y, uint8_t *buf, uint16_t *palette16);
protected:
static uint8_t _rst, _cs, _dc;
static uint8_t _mosi, _sclk;
static uint8_t _vsync_pin;
static DMAChannel flexio1DMA;
static DMAChannel flexio2DMA;
void tft_setup(bool isST);
static void TFT_isr(void);
static void QT3_isr(void);
};
#endif
#endif

View file

@ -3,132 +3,20 @@ extern "C" {
#include "iopins.h" #include "iopins.h"
} }
#include "aiie.h" #include "t4_dsp.h"
extern T4_DSP tft;
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
TFT_T_DMA tft;
#else
#include "tft_t_dma.h"
TFT_T_DMA tft = TFT_T_DMA(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO, TFT_TOUCH_CS, TFT_TOUCH_INT);
#endif
bool vgaMode = false;
static unsigned char palette8[PALETTE_SIZE];
static unsigned short palette16[PALETTE_SIZE];
static IntervalTimer myTimer;
volatile boolean vbl=true;
static int skip=0;
static elapsedMicros tius;
static void vblCount() {
if (vbl) {
vbl = false;
} else {
vbl = true;
}
}
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
{
if (index<PALETTE_SIZE) {
//Serial.println("%d: %d %d %d\n", index, r,g,b);
palette8[index] = RGBVAL8(r,g,b);
palette16[index] = RGBVAL16(r,g,b);
}
}
void emu_DrawVsync(void)
{
volatile boolean vb=vbl;
skip += 1;
skip &= VID_FRAME_SKIP;
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.waitSync();
#else
while (vbl==vb) {};
#endif
}
}
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
#ifdef HAS_T4_VGA
tft.writeLine(width,1,line, VBuf, palette8);
#else
tft.writeLine(width,1,line, VBuf, palette16);
#endif
}
}
void emu_DrawLine8(unsigned char * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeLine16(width,height,line, VBuf);
#else
tft.writeLine(width,height,line, VBuf);
#endif
}
}
}
void emu_DrawScreen(unsigned char * VBuf, int width, int height, int stride)
{
if (!vgaMode) {
if (skip==0) {
#ifdef HAS_T4_VGA
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette8);
#else
tft.writeScreen(width,height-TFT_VBUFFER_YCROP,stride, VBuf+(TFT_VBUFFER_YCROP/2)*stride, palette16);
#endif
}
}
}
int emu_FrameSkip(void)
{
return skip;
}
void * emu_LineBuffer(int line)
{
if (!vgaMode) {
return (void*)tft.getLineBuffer(line);
}
}
// **************************************************** // ****************************************************
// the setup() method runs once, when the sketch starts // the setup() method runs once, when the sketch starts
// **************************************************** // ****************************************************
void setup() { void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init(); emu_init();
} }
static void vbl(void) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
// **************************************************** // ****************************************************
// the loop() method runs continuously // the loop() method runs continuously
@ -139,60 +27,15 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick); int action = handleMenu(bClick);
char * filename = menuSelection(); char * filename = menuSelection();
if (action == ACTION_RUN1) { if (action == ACTION_RUN1) {
toggleMenu(false); emu_start(20000,nullptr);
vgaMode = false;
emu_start();
emu_Init(filename); emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 20000); //to run every 20ms
} }
delay(20); delay(20);
} }
else { else {
uint16_t bClick = emu_DebounceLocalKeys(); uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick); emu_Input(bClick);
emu_Step(); emu_Step();
delay(10);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// emu_Input(bClick);
//}
} }
} }
#ifdef HAS_SND
#include "AudioPlaySystem.h"
AudioPlaySystem mymixer;
void emu_sndInit() {
Serial.println("sound init");
mymixer.begin_audio(256, mymixer.snd_Mixer);
mymixer.start();
}
void emu_sndPlaySound(int chan, int volume, int freq)
{
if (chan < 6) {
mymixer.sound(chan, freq, volume);
}
/*
Serial.print(chan);
Serial.print(":" );
Serial.print(volume);
Serial.print(":" );
Serial.println(freq);
*/
}
void emu_sndPlayBuzz(int size, int val) {
mymixer.buzz(size,val);
//Serial.print((val==1)?1:0);
//Serial.print(":");
//Serial.println(size);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,234 +0,0 @@
/*
Based on C64 ILI9341 dma driver from Frank Bösing, 2017
*/
#ifndef _TFT_T_DMAH_
#define _TFT_T_DMAH_
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include <DMAChannel.h>
#endif
#include "tft_t_dma_config.h"
#define RGBVAL32(r,g,b) ( (r<<16) | (g<<8) | b )
#define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define R16(rgb) ((rgb>>8)&0xf8)
#define G16(rgb) ((rgb>>3)&0xfc)
#define B16(rgb) ((rgb<<3)&0xf8)
#define PAL_COLOR_MASK 0xff
#ifdef LOHRES
#define TFT_WIDTH 240
#define TFT_REALWIDTH 240
#else
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#endif
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
//#define WIDTH 272
//#define HEIGHT 228
#define LINES_PER_BLOCK 64
#define NR_OF_BLOCK 4
#define SCREEN_DMA_NUM_SETTINGS NR_OF_BLOCK
#ifdef ILI9341
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0D
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_MH 0x04
#define TFT_CASET ILI9341_CASET
#define TFT_PASET ILI9341_PASET
#define TFT_RAMWR ILI9341_RAMWR
#define TFT_MADCTL ILI9341_MADCTL
#endif
#ifdef ST7789
#define ST7735_NOP 0x00
#define ST7735_SWRESET 0x01
#define ST7735_RDDID 0x04
#define ST7735_RDDST 0x09
#define ST7735_SLPIN 0x10
#define ST7735_SLPOUT 0x11
#define ST7735_PTLON 0x12
#define ST7735_NORON 0x13
#define ST7735_INVOFF 0x20
#define ST7735_INVON 0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_RAMRD 0x2E
#define ST7735_PTLAR 0x30
#define ST7735_COLMOD 0x3A
#define ST7735_MADCTL 0x36
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_DISSET5 0xB6
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_RDID1 0xDA
#define ST7735_RDID2 0xDB
#define ST7735_RDID3 0xDC
#define ST7735_RDID4 0xDD
#define ST7735_PWCTR6 0xFC
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_MADCTL_BGR 0x08
#define ST77XX_MADCTL_MH 0x04
#define TFT_CASET ST7735_CASET
#define TFT_PASET ST7735_RASET
#define TFT_RAMWR ST7735_RAMWR
#define TFT_MADCTL ST7735_MADCTL
#endif
#ifdef __cplusplus
class TFT_T_DMA
{
public:
TFT_T_DMA(uint8_t _CS, uint8_t _DC, uint8_t _RST = 255, uint8_t _MOSI=11, uint8_t _SCLK=13, uint8_t _MISO=12, uint8_t touch_cs=38, uint8_t touch_irq=37);
void setArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);
void begin(void);
void flipscreen(bool flip);
boolean isflipped(void);
void startDMA(void);
void stopDMA();
int get_frame_buffer_size(int *width, int *height);
// Touch screen functions
#define TOUCH_ENABLED() ((_touch_cs != 255) && (_touch_irq != 255))
bool isTouching(void) { return ((!TOUCH_ENABLED())?false:(digitalRead(_touch_irq) == LOW)); }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ);
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax);
// NoDMA functions
void writeScreenNoDma(const uint16_t *pcolors);
void fillScreenNoDma(uint16_t color);
void drawTextNoDma(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
// DMA functions
uint16_t * getLineBuffer(int j);
void writeScreen(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int stride, uint8_t *buffer, uint16_t *palette16);
void writeLine(int width, int height, int y, uint16_t *buf);
void fillScreen(uint16_t color);
void drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap);
void drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh);
protected:
uint8_t _rst, _cs, _dc;
uint8_t _miso, _mosi, _sclk;
uint8_t _touch_irq=255, _touch_cs=255;
bool flipped=false;
void wait(void);
void enableTouchIrq();
};
#endif
#endif

View file

@ -1,14 +0,0 @@
#include "platform_config.h"
//#define ST7789 1
//#define ILI9341 1
#define TFT_LINEARINT 1
#define LINEARINT_HACK 1
//#define FLIP_SCREEN 1
//#define TFT_DEBUG 1
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
//#define TFT_STATICFB 1
#endif

View file

@ -1,53 +0,0 @@
/*
Wrapping class to extend VGA_T4 to TFT_T_DMA
*/
#ifndef _VGA_T_DMAH_
#define _VGA_T_DMAH_
#ifdef __cplusplus
#include <VGA_t4.h>
#endif
#define RGBVAL16(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define RGBVAL8(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
#define TFT_WIDTH 320
#define TFT_REALWIDTH 320
#define TFT_HEIGHT 240
#define TFT_REALHEIGHT 240
#ifdef __cplusplus
class TFT_T_DMA: public VGA_T4
{
public:
// Fake touch screen functions
bool isTouching(void) { return false; }
void readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { }
void readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ) { };
void callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax) { }
// fake DMA functions
void startDMA(void) { };
void stopDMA(void) { };
// fake no DMA functions
void writeScreenNoDma(const vga_pixel *pcolors) { writeScreen(pcolors); }
void fillScreenNoDma(vga_pixel color) { clear(color); }
void drawTextNoDma(int16_t x, int16_t y, const char * text, vga_pixel fgcolor, vga_pixel bgcolor, bool doublesize) { drawText(x,y,text,fgcolor,bgcolor,doublesize); }
void drawRectNoDma(int16_t x, int16_t y, int16_t w, int16_t h, vga_pixel color) { drawRect(x, y, w, h, color); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap) { drawSprite(x, y, bitmap); }
void drawSpriteNoDma(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh) { drawSprite(x, y, bitmap, croparx, cropary, croparw, croparh); }
};
#endif
#endif

View file

@ -174,39 +174,44 @@ void aiie_Step(void)
#endif #endif
{ {
if ( !(pik & MASK_JOY2_BTN) && (k & MASK_JOY2_BTN) ) { if ( !(pik & MASK_JOY2_BTN) && (k & MASK_JOY2_BTN) ) {
g_keyboard->onPress(RA);
g_keyboard->onPress(LA); g_keyboard->onPress(LA);
} }
else if ( (pik & MASK_JOY2_BTN) && !(k & MASK_JOY2_BTN) ) { else if ( (pik & MASK_JOY2_BTN) && !(k & MASK_JOY2_BTN) ) {
g_keyboard->onRelease(RA);
g_keyboard->onRelease(LA); g_keyboard->onRelease(LA);
} }
if ( !(pik & MASK_JOY1_BTN) && (k & MASK_JOY1_BTN) ) { if ( !(pik & MASK_JOY1_BTN) && (k & MASK_JOY1_BTN) ) {
g_keyboard->onPress(RA); g_keyboard->onPress(RA);
g_keyboard->onPress(LA);
} }
else if ( (pik & MASK_JOY1_BTN) && !(k & MASK_JOY1_BTN) ) { else if ( (pik & MASK_JOY1_BTN) && !(k & MASK_JOY1_BTN) ) {
g_keyboard->onRelease(RA); g_keyboard->onRelease(RA);
g_keyboard->onRelease(LA);
} }
if (k & MASK_JOY2_RIGHT) { if ( (k & MASK_JOY2_LEFT) || (k & MASK_JOY1_LEFT) ) {
if (padxinc < 0) padxinc = 0; if (padxinc < 0) padxinc = 0;
if (padxinc != +1) padxinc += 1; if (padxinc != +1) padxinc += 1;
if (padx != 255) padx += padxinc; if (padx != 255) padx += padxinc;
g_paddles->setPaddle0(padx); g_paddles->setPaddle0(padx);
} }
else if (k & MASK_JOY2_LEFT) { else if ( (k & MASK_JOY2_RIGHT) || (k & MASK_JOY1_RIGHT) ) {
if (padxinc > 0) padxinc = 0; if (padxinc > 0) padxinc = 0;
if (padxinc != -1) padxinc -= 1; if (padxinc != -1) padxinc -= 1;
if (padx != 0) padx += padxinc; if (padx != 0) padx += padxinc;
g_paddles->setPaddle0(padx); g_paddles->setPaddle0(padx);
} }
if (k & MASK_JOY2_UP) { if ( (k & MASK_JOY2_UP) || (k & MASK_JOY1_UP) ) {
if (padyinc < 0) padyinc = 0; if (padyinc < 0) padyinc = 0;
if (padyinc != 1) padyinc += 1; if (padyinc != 1) padyinc += 1;
if (pady != 255) pady += padyinc; if (pady != 255) pady += padyinc;
g_paddles->setPaddle1(pady); g_paddles->setPaddle1(pady);
} }
else if (k & MASK_JOY2_DOWN) { else if ( (k & MASK_JOY2_DOWN) || (k & MASK_JOY1_DOWN) ) {
if (padyinc > 0) padyinc = 0; if (padyinc > 0) padyinc = 0;
if (padyinc != -1) padyinc -= 1; if (padyinc != -1) padyinc -= 1;
if (pady != 0) pady += padyinc; if (pady != 0) pady += padyinc;

Some files were not shown because too many files have changed in this diff Show more