Porównaj commity

...

3 Commity

Autor SHA1 Wiadomość Data
Jean-MarcHarvengt 60f2df6113
Update README.md 2023-05-27 14:37:58 +00:00
Jean-MarcHarvengt 5b5b5a2ddd
Update README.md 2023-05-27 14:37:33 +00:00
jean-marcharvengt e664552ed1 Add multi display support to teensy41 2023-05-27 16:25:40 +02:00
322 zmienionych plików z 57556 dodań i 40442 usunięć

Wyświetl plik

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

Wyświetl plik

@ -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
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!

Wyświetl plik

@ -1,4 +1,4 @@
#include "platform_config.h"
#include "emuapi.h"
#ifdef HAS_SND
@ -176,7 +176,6 @@ void AudioPlaySystem::step(void) {
}
#ifndef HAS_T4_VGA
/*******************************************************************
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 */;
}
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];
@ -277,7 +326,6 @@ static uint32_t * i2s_tx_buffer __attribute__((aligned(32)));
static uint16_t * i2s_tx_buffer16;
static uint16_t * txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2);
FASTRUN void AudioPlaySystem::AUDIO_isr() {
*txreg = i2s_tx_buffer16[cnt];
@ -335,7 +383,14 @@ FLASHMEM void AudioPlaySystem::begin_audio(int samplesize, void (*callback)(shor
sampleBufferSize = samplesize;
#ifdef PT8211
txreg = (uint16_t *)((uint32_t)&I2S1_TDR0);
config_pt8211();
#else
txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2);
config_sai1();
#endif
attachInterruptVector(IRQ_SAI1, AUDIO_isr);
NVIC_ENABLE_IRQ(IRQ_SAI1);
NVIC_SET_PRIORITY(IRQ_QTIMER3, 0); // 0 highest priority, 255 = lowest priority
@ -358,4 +413,3 @@ FLASHMEM void AudioPlaySystem::end_audio()
}
#endif
#endif

Wyświetl plik

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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -1,8 +1,34 @@
#ifndef _PLATFORM_CONFIG_H_
#define _PLATFORM_CONFIG_H_
#define ST7789 1
#define TFTSPI1 1
// Will work on TEECOMPUTER as is
// NO TEECOMPUTER specific switch
#define HAS_T4_VGA 1
//#define INVX 1
#define INVY 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

Wyświetl plik

@ -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

Wyświetl plik

@ -1,73 +1,15 @@
extern "C" {
#include "iopins.h"
}
#include "emuapi.h"
#include "iopins.h"
#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);
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
#include "t4_dsp.h"
extern T4_DSP tft;
// ****************************************************
// the setup() method runs once, when the sketch starts
// ****************************************************
void setup() {
tft.begin();
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 20000); //to run every 20ms
#ifdef HAS_SND
emu_sndInit();
#endif
emu_init();
emu_start(20000,nullptr);
}
@ -97,12 +39,13 @@ void loop(void)
tft.fillScreen( RGBVAL16(colcomponent,0x00,0x00) );
colcomponent += 1;
colcomponent &= 0xff;
volatile boolean vb=vbl;
while (vbl==vb) {};
emu_DrawVsync();
notedelay += 1;
notedelay &= 0x07;
int note = notes[note_pos];
#ifdef HAS_SND
emu_sndPlaySound(1, notedelay<<4, note);
#endif
if ( !notedelay )
{
note_pos += 1;

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -176,7 +176,6 @@ void AudioPlaySystem::step(void) {
}
#ifndef HAS_T4_VGA
/*******************************************************************
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 */;
}
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];
@ -277,7 +326,6 @@ static uint32_t * i2s_tx_buffer __attribute__((aligned(32)));
static uint16_t * i2s_tx_buffer16;
static uint16_t * txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2);
FASTRUN void AudioPlaySystem::AUDIO_isr() {
*txreg = i2s_tx_buffer16[cnt];
@ -335,7 +383,14 @@ FLASHMEM void AudioPlaySystem::begin_audio(int samplesize, void (*callback)(shor
sampleBufferSize = samplesize;
#ifdef PT8211
txreg = (uint16_t *)((uint32_t)&I2S1_TDR0);
config_pt8211();
#else
txreg = (uint16_t *)((uint32_t)&I2S1_TDR0 + 2);
config_sai1();
#endif
attachInterruptVector(IRQ_SAI1, AUDIO_isr);
NVIC_ENABLE_IRQ(IRQ_SAI1);
NVIC_SET_PRIORITY(IRQ_QTIMER3, 0); // 0 highest priority, 255 = lowest priority
@ -358,4 +413,3 @@ FLASHMEM void AudioPlaySystem::end_audio()
}
#endif
#endif

Wyświetl plik

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

Wyświetl plik

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h"
}
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#include <Arduino.h>
#ifdef HAS_USBKEY
#ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info
USBHost myusb;
USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb);
MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb);
#endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void);
static bool emu_readConfig(void);
static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false;
static bool keyboardDetected = false;
@ -34,12 +40,13 @@ static File file;
#define MAX_FILES 64
#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 TEXT_HEIGHT 16
#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_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#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_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 curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true;
static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys;
#ifdef TEECOMPUTER
@ -158,6 +168,29 @@ void emu_Free(void * 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
********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif
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
uint32_t time_ms=millis();
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 ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) )
if ( (fn_pressed) && (sh_pressed) )
#else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) {
;
}
#endif
#endif
}
emu_GetJoystick();
return (retval);
}
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
}
int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) {
*buts = mouse1.getButtons();
*x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
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)
{
keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0);
}
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0;
static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif
void emu_MidiOnDataReceived(unsigned char value) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
//Serial.println(value, HEX);
//10000000 = 128 = note off
//10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/********************************
* Menu file loader UI
********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) {
int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles;
}
void backgroundMenu(void) {
menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick)
{
if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
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];
strcpy(newpath, selection);
strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection);
if (file.isDirectory()) {
curFile = 0;
nbFiles = readNbFiles();
nbFiles = readNbFiles();
menuRedraw=true;
}
else {
action = ACTION_RUN1;
else
{
#ifdef TEECOMPUTER
if (key_extmode) {
if ( (key_extmode) || ( key_sh) ) {
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
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
menuRedraw=true;
}
else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/");
strcat(second_selection, second_selected_filename);
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) ) {
if (curFile!=0) {
menuRedraw=true;
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) {
menuRedraw=true;
curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
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)) {
curFile += 9;
menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action);
}
bool menuActive(void)
int menuActive(void)
{
return (menuOn);
return (menuOn?1:0);
}
void toggleMenu(bool on) {
void toggleMenu(int on) {
if (on) {
menuOn=true;
backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{
return (second_selection);
}
#endif
/********************************
* OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0};
const char * cpt = str;
int i=0;
int fb_width,fb_height;
tft.get_frame_buffer_size(&fb_width, &fb_height);
int fb_width,fb_height,fbstride;
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0);
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);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,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++;
}
}
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval;
}
void toggleOSKB(bool forceon) {
void toggleOSKB(int forceon) {
if (forceon) {
oskbOn = true;
drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#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) {
// emu_printf("FileGetc");
// emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize);
lofile.close();
}
else {
emu_printf("filesize failed");
}
return(filesize);
}
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
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
********************************/
@ -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);
vgahires = hires;
#ifdef HAS_USBKEY
#ifdef HAS_USB
myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease);
#endif
#endif
while (!SD.begin(SD_CS))
#ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{
Serial.println("SD begin failed, retrying...");
delay(1000);
Serial.println("No SD card detected");
}
strcpy(selection,ROMSDIR);
FileHandlersInit();
nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles);
#endif
emu_InitJoysticks();
#ifdef SWAP_JOYSTICK
joySwapped = true;
joySwapped = true;
#else
joySwapped = false;
joySwapped = false;
#endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
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) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig();
delay(1000);
#endif
}
else {
#ifdef FILEBROWSER
if (emu_readConfig()) {
autorun = true;
}
#endif
}
#ifdef FILEBROWSER
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;
}

Wyświetl plik

@ -2,127 +2,14 @@
#define EMUAPI_H
#include "platform_config.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)
#include "emucfg.h"
#define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16
#define ACTION_EXITKBD 128
#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 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
@ -139,21 +26,25 @@ const unsigned short matkeys[] = {
#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_init(void);
extern void emu_start(void);
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);
@ -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 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_DrawLine(unsigned char * VBuf, int width, int height, int line);
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_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta);
extern int emu_IsVga(void);
extern int emu_IsVgaHires(void);
extern bool menuActive(void);
extern int menuActive(void);
extern char * menuSelection(void);
extern char * menuSecondSelection(void);
extern void toggleMenu(bool on);
extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void);
extern void toggleOSKB(bool forceon);
extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ 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);

Wyświetl plik

@ -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

Wyświetl plik

@ -4,27 +4,32 @@
#define TEECOMPUTER 1
#ifdef TEECOMPUTER
//#define ILI9341 1
//#define ST7789 1
//#define TFTSPI1 1
#define HAS_T4_VGA 1
//#define HIRES 1
//#define HAS_SND 1
#define TFTSPI1 1
//#define HAS_T4_VGA 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
#else
#define HAS_T4_VGA 1
#define HIRES 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
#endif
//#define FLIP_SCREEN 1
//#define ILI9341 1
//#define ST7789 1
//#define SWAP_JOYSTICK 1

Wyświetl plik

@ -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

Wyświetl plik

@ -1,217 +1,94 @@
#include "emuapi.h"
#include "iopins.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;
#include "t4_dsp.h"
extern T4_DSP tft;
#define BLUE RGBVAL16(0, 0, 170)
#define LIGHT_BLUE RGBVAL16(0, 136, 255)
static int fb_width, fb_height;
static const char * digits = "0123456789ABCDEF";
static int hk = 0;
static int prevhk = 0;
static int col=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
// ****************************************************
void setup() {
#ifdef HAS_T4_VGA
#ifdef HIRES
tft.begin(VGA_MODE_640x480);
#else
tft.begin(VGA_MODE_320x240);
#endif
//NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init();
emu_start();
tft.fillScreenNoDma(LIGHT_BLUE);
emu_init();
char * filename;
#ifdef FILEBROWSER
while (true) {
if (menuActive()) {
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
filename = menuSelection();
if (action == ACTION_RUN1) {
break;
}
delay(20);
}
}
#endif
emu_start(20000,nullptr,1);
tft.fillScreen(LIGHT_BLUE);
tft.get_frame_buffer_size(&fb_width, &fb_height);
tft.drawRectNoDma((fb_width-320)/2,(fb_height-200)/2, 320,200, BLUE);
myTimer.begin(vblCount, 20000); //to run every 20ms
tft.drawRect((fb_width-320)/2,(fb_height-200)/2, 320,200, BLUE);
toggleOSKB(true);
}
void loop(void)
{
char buf[5] = {0,0,0,0,0};
/*
uint16_t bClick = emu_GetPad();
buf[0] = digits[(bClick>>12)&0xf];
buf[1] = digits[(bClick>>8)&0xf];
buf[2] = digits[(bClick>>4)&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;
int key = emu_ReadI2CKeyboard();
buf[0] = digits[(key>>8)&0xf];
buf[1] = digits[(key>>4)&0xf];
buf[2] = digits[key&0xf];
tft.drawTextNoDma(4*8,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;
key = emu_ReadI2CKeyboard2(0);
buf[0] = digits[(key>>4)&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);
buf[0] = digits[(key>>4)&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);
buf[0] = digits[(key>>4)&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);
buf[0] = digits[(key>>4)&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);
buf[0] = digits[(key>>4)&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);
buf[0] = digits[(key>>4)&0xf];
buf[1] = digits[key&0xf];
tft.drawTextNoDma(9*8+5*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
*/
handleOSKB();
tft.drawText(9*8+5*24,0*8,buf,RGBVAL16(0x00,0x00,0x00),RGBVAL16(0xFF,0xFF,0xFF),true);
bClick = emu_DebounceLocalKeys();
int hk = hk = emu_ReadI2CKeyboard();
//handleOSKB();
if ( (hk != 0) && (hk < 128) ) {
buf[0] = (char)(hk&0xff);
buf[1] = 0;
tft.drawTextNoDma(col*8,(row+3)*8,buf,LIGHT_BLUE,BLUE,false);
tft.drawText(col*8,(row+3)*8,buf,LIGHT_BLUE,BLUE,false);
col += 1;
if (col >= 40) {
col=0;
@ -231,67 +108,3 @@ void loop(void)
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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

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

Wyświetl plik

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h"
}
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#include <Arduino.h>
#ifdef HAS_USBKEY
#ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info
USBHost myusb;
USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb);
MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb);
#endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void);
static bool emu_readConfig(void);
static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false;
static bool keyboardDetected = false;
@ -34,12 +40,13 @@ static File file;
#define MAX_FILES 64
#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 TEXT_HEIGHT 16
#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_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#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_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 curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true;
static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys;
#ifdef TEECOMPUTER
@ -158,6 +168,29 @@ void emu_Free(void * 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
********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif
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
uint32_t time_ms=millis();
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 ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) )
if ( (fn_pressed) && (sh_pressed) )
#else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) {
;
}
#endif
#endif
}
emu_GetJoystick();
return (retval);
}
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
}
int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) {
*buts = mouse1.getButtons();
*x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
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)
{
keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0);
}
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0;
static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif
void emu_MidiOnDataReceived(unsigned char value) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
//Serial.println(value, HEX);
//10000000 = 128 = note off
//10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/********************************
* Menu file loader UI
********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) {
int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles;
}
void backgroundMenu(void) {
menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick)
{
if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
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];
strcpy(newpath, selection);
strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection);
if (file.isDirectory()) {
curFile = 0;
nbFiles = readNbFiles();
nbFiles = readNbFiles();
menuRedraw=true;
}
else {
action = ACTION_RUN1;
else
{
#ifdef TEECOMPUTER
if (key_extmode) {
if ( (key_extmode) || ( key_sh) ) {
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
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
menuRedraw=true;
}
else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/");
strcat(second_selection, second_selected_filename);
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) ) {
if (curFile!=0) {
menuRedraw=true;
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) {
menuRedraw=true;
curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
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)) {
curFile += 9;
menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action);
}
bool menuActive(void)
int menuActive(void)
{
return (menuOn);
return (menuOn?1:0);
}
void toggleMenu(bool on) {
void toggleMenu(int on) {
if (on) {
menuOn=true;
backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{
return (second_selection);
}
#endif
/********************************
* OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0};
const char * cpt = str;
int i=0;
int fb_width,fb_height;
tft.get_frame_buffer_size(&fb_width, &fb_height);
int fb_width,fb_height,fbstride;
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0);
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);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,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++;
}
}
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval;
}
void toggleOSKB(bool forceon) {
void toggleOSKB(int forceon) {
if (forceon) {
oskbOn = true;
drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#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) {
// emu_printf("FileGetc");
// emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize);
lofile.close();
}
else {
emu_printf("filesize failed");
}
return(filesize);
}
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
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
********************************/
@ -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);
vgahires = hires;
#ifdef HAS_USBKEY
#ifdef HAS_USB
myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease);
#endif
#endif
while (!SD.begin(SD_CS))
#ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{
Serial.println("SD begin failed, retrying...");
delay(1000);
Serial.println("No SD card detected");
}
strcpy(selection,ROMSDIR);
FileHandlersInit();
nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles);
#endif
emu_InitJoysticks();
#ifdef SWAP_JOYSTICK
joySwapped = true;
joySwapped = true;
#else
joySwapped = false;
joySwapped = false;
#endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
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) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig();
delay(1000);
#endif
}
else {
#ifdef FILEBROWSER
if (emu_readConfig()) {
autorun = true;
}
#endif
}
#ifdef FILEBROWSER
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;
}

Wyświetl plik

@ -2,126 +2,14 @@
#define EMUAPI_H
#include "platform_config.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)
#include "emucfg.h"
#define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16
#define ACTION_EXITKBD 128
#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 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
@ -138,22 +26,25 @@ const unsigned short matkeys[] = {
#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_init(void);
extern void emu_start(void);
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);
@ -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 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_DrawLine(unsigned char * VBuf, int width, int height, int line);
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_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta);
extern int emu_IsVga(void);
extern int emu_IsVgaHires(void);
extern bool menuActive(void);
extern int menuActive(void);
extern char * menuSelection(void);
extern char * menuSecondSelection(void);
extern void toggleMenu(bool on);
extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void);
extern void toggleOSKB(bool forceon);
extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ 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);

Wyświetl plik

@ -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

Wyświetl plik

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

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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

Wyświetl plik

@ -3,133 +3,16 @@ extern "C" {
#include "iopins.h"
}
#include "v20.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
// ****************************************************
void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init();
}
// ****************************************************
// the loop() method runs continuously
// ****************************************************
@ -139,14 +22,9 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
char * filename = menuSelection();
if (action == ACTION_RUN1) {
toggleMenu(false);
vgaMode = false;
emu_start();
if (action == ACTION_RUN1) {
emu_start(20000,nullptr);
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 20000); //to run every 20ms
}
delay(20);
}
@ -154,45 +32,6 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
emu_Step();
delay(10);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// emu_Input(bClick);
//}
delay(20);
}
}
#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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -176,25 +176,24 @@ __
const uint32_t ascii2scan[] = {
//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
// 31:RUNSTOP
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xf7fe,
0,0,0,0,0,0,0,0,0,0,0xfd7f,0,0,0xfd7f,0,0, // return
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xf7fe, //31:RUNSTOP
//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 : ; < = > ?
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
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 [ \ ] ^ _
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,
//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,
// 129: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
// 150:right left down up 157:left
0,0,0,0,0,0, 0xfb7f,0x1fb7f,0xf77f,0x1f77f,0,0,0,0,0,0 // 144-159
//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,
// 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
// 150:right left down up
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;
if (iusbhk) hk = iusbhk;
#ifdef TEECOMPUTER
if (hk) {
Serial.println(hk);
int scan = ascii2scan[hk];
if (scan & 0x10000) mos6522.setShiftPressed(true);
else mos6522.setShiftPressed(false);
@ -384,12 +385,13 @@ void v20_Step(void)
mos6522.setShiftPressed(false);
mos6522.setKeyPressed(0);
}
#endif
int k=ik;
#ifdef TEECOMPUTER
// 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
{
if ( !(pik & MASK_JOY2_BTN) && (k & MASK_JOY2_BTN) ) {
@ -411,17 +413,49 @@ void v20_Step(void)
mos6522.setJoyStickPressed(MOS6522::Vic20JoyStickButton::Down, false);
}
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);
}
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);
}
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

Wyświetl plik

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

4
MCUME_teensy41/teensy64/cpu.h 100755 → 100644
Wyświetl plik

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

Wyświetl plik

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h"
}
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#include <Arduino.h>
#ifdef HAS_USBKEY
#ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info
USBHost myusb;
USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb);
MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb);
#endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void);
static bool emu_readConfig(void);
static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false;
static bool keyboardDetected = false;
@ -34,12 +40,13 @@ static File file;
#define MAX_FILES 64
#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 TEXT_HEIGHT 16
#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_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#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_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 curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true;
static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys;
#ifdef TEECOMPUTER
@ -158,6 +168,29 @@ void emu_Free(void * 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
********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif
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
uint32_t time_ms=millis();
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 ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) )
if ( (fn_pressed) && (sh_pressed) )
#else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) {
;
}
#endif
#endif
}
emu_GetJoystick();
return (retval);
}
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
}
int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) {
*buts = mouse1.getButtons();
*x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
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)
{
keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0);
}
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0;
static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif
void emu_MidiOnDataReceived(unsigned char value) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
//Serial.println(value, HEX);
//10000000 = 128 = note off
//10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/********************************
* Menu file loader UI
********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) {
int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles;
}
void backgroundMenu(void) {
menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick)
{
if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
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];
strcpy(newpath, selection);
strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection);
if (file.isDirectory()) {
curFile = 0;
nbFiles = readNbFiles();
nbFiles = readNbFiles();
menuRedraw=true;
}
else {
action = ACTION_RUN1;
else
{
#ifdef TEECOMPUTER
if (key_extmode) {
if ( (key_extmode) || ( key_sh) ) {
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
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
menuRedraw=true;
}
else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/");
strcat(second_selection, second_selected_filename);
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) ) {
if (curFile!=0) {
menuRedraw=true;
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) {
menuRedraw=true;
curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
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)) {
curFile += 9;
menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action);
}
bool menuActive(void)
int menuActive(void)
{
return (menuOn);
return (menuOn?1:0);
}
void toggleMenu(bool on) {
void toggleMenu(int on) {
if (on) {
menuOn=true;
backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{
return (second_selection);
}
#endif
/********************************
* OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0};
const char * cpt = str;
int i=0;
int fb_width,fb_height,fb_stride;
tft.get_frame_buffer_size(&fb_width, &fb_height, &fb_stride);
int fb_width,fb_height,fbstride;
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0);
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);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,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++;
}
}
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval;
}
void toggleOSKB(bool forceon) {
void toggleOSKB(int forceon) {
if (forceon) {
oskbOn = true;
drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#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) {
// emu_printf("FileGetc");
// emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize);
lofile.close();
}
else {
emu_printf("filesize failed");
}
return(filesize);
}
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
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
********************************/
@ -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);
vgahires = hires;
#ifdef HAS_USBKEY
#ifdef HAS_USB
myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease);
#endif
#endif
while (!SD.begin(SD_CS))
#ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{
Serial.println("SD begin failed, retrying...");
delay(1000);
Serial.println("No SD card detected");
}
strcpy(selection,ROMSDIR);
FileHandlersInit();
nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles);
#endif
emu_InitJoysticks();
#ifdef SWAP_JOYSTICK
joySwapped = true;
joySwapped = true;
#else
joySwapped = false;
joySwapped = false;
#endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
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) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig();
delay(1000);
#endif
}
else {
#ifdef FILEBROWSER
if (emu_readConfig()) {
autorun = true;
}
#endif
}
#ifdef FILEBROWSER
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;
}

Wyświetl plik

@ -2,126 +2,14 @@
#define EMUAPI_H
#include "platform_config.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)
#include "emucfg.h"
#define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16
#define ACTION_EXITKBD 128
#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 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
@ -138,22 +26,25 @@ const unsigned short matkeys[] = {
#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_init(void);
extern void emu_start(void);
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);
@ -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 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_DrawLine(unsigned char * VBuf, int width, int height, int line);
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_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta);
extern int emu_IsVga(void);
extern int emu_IsVgaHires(void);
extern bool menuActive(void);
extern int menuActive(void);
extern char * menuSelection(void);
extern char * menuSecondSelection(void);
extern void toggleMenu(bool on);
extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void);
extern void toggleOSKB(bool forceon);
extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ 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);

Wyświetl plik

@ -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

Wyświetl plik

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

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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

Wyświetl plik

@ -3,134 +3,20 @@ extern "C" {
#include "iopins.h"
}
#include "c64.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
}
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);
}
}
#include "t4_dsp.h"
extern T4_DSP tft;
// ****************************************************
// the setup() method runs once, when the sketch starts
// ****************************************************
void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init();
}
static void vbl(void) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
// ****************************************************
// the loop() method runs continuously
@ -141,58 +27,13 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
char * filename = menuSelection();
if (action == ACTION_RUN1) {
toggleMenu(false);
vgaMode = false;
emu_start();
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 20000); //to run every 20ms
if (action == ACTION_RUN1) {
emu_start(20000,vbl);
emu_Init(filename);
}
delay(20);
}
else {
emu_Step();
//delay(20);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// 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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

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

Wyświetl plik

@ -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

Wyświetl plik

@ -69,11 +69,7 @@
#define BORDER_LEFT 0
#define BORDER_RIGHT 0
#ifdef HAS_T4_VGA
typedef uint8_t tpixel;
#else
typedef uint16_t tpixel;
#endif
#define MAXCYCLESSPRITES0_2 3
#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));
#endif

Wyświetl plik

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

Wyświetl plik

@ -41,7 +41,7 @@ UWORD Screen_atari[ATARI_WIDTH / 2]; // = NULL;
#define DRAWLINE() \
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); \
}

Wyświetl plik

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h"
}
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#include <Arduino.h>
#ifdef HAS_USBKEY
#ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info
USBHost myusb;
USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb);
MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb);
#endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void);
static bool emu_readConfig(void);
static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false;
static bool keyboardDetected = false;
@ -34,8 +40,9 @@ static File file;
#define MAX_FILES 64
#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 TEXT_HEIGHT 16
#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_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 curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true;
static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys;
#ifdef TEECOMPUTER
@ -103,7 +113,7 @@ void emu_printf(int val)
void emu_printi(int val)
{
Serial.println(val);
Serial.println(val,HEX);
}
void emu_printh(int val)
@ -158,6 +168,29 @@ void emu_Free(void * 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
********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif
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
uint32_t time_ms=millis();
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 ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) )
if ( (fn_pressed) && (sh_pressed) )
#else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) {
;
}
#endif
#endif
}
emu_GetJoystick();
return (retval);
}
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
}
int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) {
*buts = mouse1.getButtons();
*x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
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)
{
keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0);
}
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0;
static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif
void emu_MidiOnDataReceived(unsigned char value) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
//Serial.println(value, HEX);
//10000000 = 128 = note off
//10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/********************************
* Menu file loader UI
********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) {
int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles;
}
void backgroundMenu(void) {
menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick)
{
if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
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];
strcpy(newpath, selection);
strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection);
if (file.isDirectory()) {
curFile = 0;
nbFiles = readNbFiles();
nbFiles = readNbFiles();
menuRedraw=true;
}
else {
action = ACTION_RUN1;
else
{
#ifdef TEECOMPUTER
if (key_extmode) {
if ( (key_extmode) || ( key_sh) ) {
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
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
menuRedraw=true;
}
else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/");
strcat(second_selection, second_selected_filename);
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) ) {
if (curFile!=0) {
menuRedraw=true;
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) {
menuRedraw=true;
curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
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)) {
curFile += 9;
menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action);
}
bool menuActive(void)
int menuActive(void)
{
return (menuOn);
return (menuOn?1:0);
}
void toggleMenu(bool on) {
void toggleMenu(int on) {
if (on) {
menuOn=true;
backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{
return (second_selection);
}
#endif
/********************************
* OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0};
const char * cpt = str;
int i=0;
int fb_width,fb_height;
tft.get_frame_buffer_size(&fb_width, &fb_height);
int fb_width,fb_height,fbstride;
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0);
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);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,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++;
}
}
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval;
}
void toggleOSKB(bool forceon) {
void toggleOSKB(int forceon) {
if (forceon) {
oskbOn = true;
drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#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) {
// emu_printf("FileGetc");
// emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize);
lofile.close();
}
else {
emu_printf("filesize failed");
}
return(filesize);
}
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
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
********************************/
@ -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);
vgahires = hires;
#ifdef HAS_USBKEY
#ifdef HAS_USB
myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease);
#endif
#endif
while (!SD.begin(SD_CS))
#ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{
Serial.println("SD begin failed, retrying...");
delay(1000);
Serial.println("No SD card detected");
}
strcpy(selection,ROMSDIR);
FileHandlersInit();
nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles);
#endif
emu_InitJoysticks();
#ifdef SWAP_JOYSTICK
joySwapped = true;
joySwapped = true;
#else
joySwapped = false;
joySwapped = false;
#endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
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) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig();
delay(1000);
#endif
}
else {
#ifdef FILEBROWSER
if (emu_readConfig()) {
autorun = true;
}
#endif
}
#ifdef FILEBROWSER
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;
}

Wyświetl plik

@ -2,124 +2,14 @@
#define EMUAPI_H
#include "platform_config.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)
#include "emucfg.h"
#define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16
#define ACTION_EXITKBD 128
#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 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
@ -136,24 +26,25 @@ const unsigned short matkeys[] = {
#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" {
#else
#define bool unsigned char
extern void emu_init(int hires=0);
extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif
extern void emu_init(void);
extern void emu_start(void);
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);
@ -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 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_DrawLine(unsigned char * VBuf, int width, int height, int line);
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_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta);
extern int emu_IsVga(void);
extern int emu_IsVgaHires(void);
extern bool menuActive(void);
extern int menuActive(void);
extern char * menuSelection(void);
extern char * menuSecondSelection(void);
extern void toggleMenu(bool on);
extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void);
extern void toggleOSKB(bool forceon);
extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ 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);

Wyświetl plik

@ -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

Wyświetl plik

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

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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

Wyświetl plik

@ -3,135 +3,20 @@ extern "C" {
#include "emuapi.h"
}
extern "C" {
#include "atari800.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
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);
}
}
#include "t4_dsp.h"
extern T4_DSP tft;
// ****************************************************
// the setup() method runs once, when the sketch starts
// ****************************************************
void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init();
}
static void vbl(void) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
// ****************************************************
// the loop() method runs continuously
@ -142,55 +27,15 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
char * filename = menuSelection();
if (action == ACTION_RUN1) {
toggleMenu(false);
vgaMode = false;
emu_start();
if (action == ACTION_RUN1) {
emu_start(10000,nullptr,FORCE_VGATIMERVSYNC);
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 10000/*16666*/); //to run every 16.666ms
}
delay(20);
}
else {
emu_Step();
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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

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

Wyświetl plik

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h"
}
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#include <Arduino.h>
#ifdef HAS_USBKEY
#ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info
USBHost myusb;
USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb);
MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb);
#endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void);
static bool emu_readConfig(void);
static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false;
static bool keyboardDetected = false;
@ -34,8 +40,9 @@ static File file;
#define MAX_FILES 64
#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 TEXT_HEIGHT 16
#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_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 curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true;
static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys;
#ifdef TEECOMPUTER
@ -103,7 +113,7 @@ void emu_printf(int val)
void emu_printi(int val)
{
Serial.println(val);
Serial.println(val,HEX);
}
void emu_printh(int val)
@ -158,6 +168,29 @@ void emu_Free(void * 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
********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif
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
uint32_t time_ms=millis();
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 ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) )
if ( (fn_pressed) && (sh_pressed) )
#else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) {
;
}
#endif
#endif
}
emu_GetJoystick();
return (retval);
}
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
}
int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) {
*buts = mouse1.getButtons();
*x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
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)
{
keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0);
}
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0;
static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif
void emu_MidiOnDataReceived(unsigned char value) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
//Serial.println(value, HEX);
//10000000 = 128 = note off
//10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/********************************
* Menu file loader UI
********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) {
int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles;
}
void backgroundMenu(void) {
menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick)
{
if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
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];
strcpy(newpath, selection);
strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection);
if (file.isDirectory()) {
curFile = 0;
nbFiles = readNbFiles();
nbFiles = readNbFiles();
menuRedraw=true;
}
else {
action = ACTION_RUN1;
else
{
#ifdef TEECOMPUTER
if (key_extmode) {
if ( (key_extmode) || ( key_sh) ) {
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
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
menuRedraw=true;
}
else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/");
strcat(second_selection, second_selected_filename);
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) ) {
if (curFile!=0) {
menuRedraw=true;
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) {
menuRedraw=true;
curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
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)) {
curFile += 9;
menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action);
}
bool menuActive(void)
int menuActive(void)
{
return (menuOn);
return (menuOn?1:0);
}
void toggleMenu(bool on) {
void toggleMenu(int on) {
if (on) {
menuOn=true;
backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{
return (second_selection);
}
#endif
/********************************
* OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0};
const char * cpt = str;
int i=0;
int fb_width,fb_height;
tft.get_frame_buffer_size(&fb_width, &fb_height);
int fb_width,fb_height,fbstride;
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0);
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);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,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++;
}
}
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval;
}
void toggleOSKB(bool forceon) {
void toggleOSKB(int forceon) {
if (forceon) {
oskbOn = true;
drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#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) {
// emu_printf("FileGetc");
// emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize);
lofile.close();
}
else {
emu_printf("filesize failed");
}
return(filesize);
}
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
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
********************************/
@ -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);
vgahires = hires;
#ifdef HAS_USBKEY
#ifdef HAS_USB
myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease);
#endif
#endif
while (!SD.begin(SD_CS))
#ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{
Serial.println("SD begin failed, retrying...");
delay(1000);
Serial.println("No SD card detected");
}
strcpy(selection,ROMSDIR);
FileHandlersInit();
nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles);
#endif
emu_InitJoysticks();
#ifdef SWAP_JOYSTICK
joySwapped = true;
joySwapped = true;
#else
joySwapped = false;
joySwapped = false;
#endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
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) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig();
delay(1000);
#endif
}
else {
#ifdef FILEBROWSER
if (emu_readConfig()) {
autorun = true;
}
#endif
}
#ifdef FILEBROWSER
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;
}

Wyświetl plik

@ -2,123 +2,14 @@
#define EMUAPI_H
#include "platform_config.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)
#include "emucfg.h"
#define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16
#define ACTION_EXITKBD 128
#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 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
@ -135,24 +26,25 @@ const unsigned short matkeys[] = {
#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" {
#else
#define bool unsigned char
extern void emu_init(int hires=0);
extern void emu_start(int vblms, void * callback, int forcetimervsync=0);
#endif
extern void emu_init(void);
extern void emu_start(void);
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);
@ -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 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_DrawLine(unsigned char * VBuf, int width, int height, int line);
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_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta);
extern int emu_IsVga(void);
extern int emu_IsVgaHires(void);
extern bool menuActive(void);
extern int menuActive(void);
extern char * menuSelection(void);
extern char * menuSecondSelection(void);
extern void toggleMenu(bool on);
extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void);
extern void toggleOSKB(bool forceon);
extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly);
@ -189,6 +80,7 @@ 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);

Wyświetl plik

@ -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

Wyświetl plik

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

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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

Wyświetl plik

@ -3,134 +3,21 @@ extern "C" {
#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
// ****************************************************
void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init();
}
static void vbl(void) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
// ****************************************************
// the loop() method runs continuously
@ -141,60 +28,15 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
char * filename = menuSelection();
if (action == ACTION_RUN1) {
toggleMenu(false);
vgaMode = false;
emu_start();
if (action == ACTION_RUN1) {
emu_start(16666,nullptr);
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 16666); //to run every 16.666ms
}
delay(20);
}
else {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
emu_Step();
delay(10);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// 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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

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

Wyświetl plik

@ -5,25 +5,31 @@ extern "C" {
#include "iopins.h"
}
#ifdef HAS_T4_VGA
#include "vga_t_dma.h"
#else
#include "tft_t_dma.h"
#endif
#include <Arduino.h>
#ifdef HAS_USBKEY
#ifdef HAS_USB
#include "USBHost_t36.h" // Read this header first for key info
USBHost myusb;
USBHub hub1(myusb);
#ifdef HAS_USBKEY
KeyboardController keyboard1(myusb);
USBHIDParser hid1(myusb);
MouseController mouse1(myusb);
#endif
#ifdef HAS_USBMIDI
MIDIDevice midi1(myusb);
#endif
#ifdef HAS_USBJOY
#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
#endif
#endif
static bool emu_writeConfig(void);
static bool emu_readConfig(void);
static bool emu_eraseConfig(void);
static bool emu_writeGfxConfig(char * display_type);
static int emu_readGfxConfig(void);
static bool mouseDetected = false;
static bool keyboardDetected = false;
@ -34,12 +40,13 @@ static File file;
#define MAX_FILES 64
#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 TEXT_HEIGHT 16
#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_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
#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_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 curFile=0;
@ -65,6 +73,8 @@ static char selected_filename[MAX_FILENAME_SIZE]="";
static char second_selected_filename[MAX_FILENAME_SIZE]="";
static bool menuRedraw=true;
static bool autorun=false;
static bool vgahires=false;
static const unsigned short * keys;
#ifdef TEECOMPUTER
@ -158,6 +168,29 @@ void emu_Free(void * 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
********************************/
@ -329,6 +362,12 @@ int emu_ReadKeys(void)
#endif
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
uint32_t time_ms=millis();
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 ) && (keymatrix[4] == 0x10 )) retval |= MASK_KEY_USER1;
#endif
if ( (key_fn) && (key_sh) )
if ( (fn_pressed) && (sh_pressed) )
#else
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|| (retval & MASK_KEY_USER4 ) )
@ -453,8 +493,10 @@ int emu_ReadKeys(void)
while (true) {
;
}
#endif
#endif
}
emu_GetJoystick();
return (retval);
}
@ -607,7 +649,7 @@ int emu_setKeymap(int index) {
}
int emu_GetMouse(int *x, int *y, int *buts) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBKEY)
if (mouse1.available()) {
*buts = mouse1.getButtons();
*x = mouse1.getMouseX();
@ -620,7 +662,23 @@ int emu_GetMouse(int *x, int *y, int *buts) {
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)
{
keyboardDetected = true;
@ -764,7 +822,7 @@ int emu_KeyboardDetected(void) {
return (keyboardDetected?1:0);
}
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
static unsigned char midiBuffer[16];
static unsigned char midiLastCmd=0;
static int midiDataCnt=0;
@ -772,8 +830,7 @@ static int midiCmdNbParam=0;
#endif
void emu_MidiOnDataReceived(unsigned char value) {
#ifdef HAS_USBKEY
#if defined(HAS_USB) && (HAS_USBMIDI)
//Serial.println(value, HEX);
//10000000 = 128 = note off
//10010000 = 144 = note on
@ -941,6 +998,7 @@ void emu_MidiOnDataReceived(unsigned char value) {
/********************************
* Menu file loader UI
********************************/
#ifdef FILEBROWSER
static int readNbFiles(void) {
int totalFiles = 0;
@ -970,8 +1028,6 @@ static int readNbFiles(void) {
return totalFiles;
}
void backgroundMenu(void) {
menuRedraw=true;
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
@ -981,11 +1037,13 @@ void backgroundMenu(void) {
int handleMenu(uint16_t bClick)
{
if (autorun) {
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
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];
strcpy(newpath, selection);
strcat(newpath, "/");
@ -996,17 +1054,31 @@ int handleMenu(uint16_t bClick)
File file = SD.open(selection);
if (file.isDirectory()) {
curFile = 0;
nbFiles = readNbFiles();
nbFiles = readNbFiles();
menuRedraw=true;
}
else {
action = ACTION_RUN1;
else
{
#ifdef TEECOMPUTER
if (key_extmode) {
if ( (key_extmode) || ( key_sh) ) {
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
toggleMenu(false);
menuRedraw=false;
return (ACTION_RUN1);
}
menuRedraw=true;
}
else if ( bClick & MASK_KEY_USER1 ) {
menuRedraw=true;
@ -1015,19 +1087,14 @@ int handleMenu(uint16_t bClick)
strcat(second_selection, "/");
strcat(second_selection, second_selected_filename);
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) ) {
if (curFile!=0) {
menuRedraw=true;
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) {
menuRedraw=true;
curFile -= 9;
@ -1042,7 +1109,7 @@ int handleMenu(uint16_t bClick)
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)) {
curFile += 9;
menuRedraw=true;
@ -1099,12 +1166,12 @@ int handleMenu(uint16_t bClick)
return (action);
}
bool menuActive(void)
int menuActive(void)
{
return (menuOn);
return (menuOn?1:0);
}
void toggleMenu(bool on) {
void toggleMenu(int on) {
if (on) {
menuOn=true;
backgroundMenu();
@ -1122,7 +1189,7 @@ char * menuSecondSelection(void)
{
return (second_selection);
}
#endif
/********************************
* OSKB handling
@ -1140,8 +1207,9 @@ static void lineOSKB(int xoff, bool bottom, char * str, int row)
char c[4] = {' ',0,' ',0};
const char * cpt = str;
int i=0;
int fb_width,fb_height;
tft.get_frame_buffer_size(&fb_width, &fb_height);
int fb_width,fb_height,fbstride;
fbstride = tft.get_frame_buffer_size(&fb_width, &fb_height);
int ypos = (bottom?(fb_height-2*8):0);
int line = row + (bottom?2:0);
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);
else bg = (i&1)?RGBVAL16(0xe0,0xe0,0xe0):RGBVAL16(0xff,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++;
}
}
@ -1248,7 +1316,7 @@ int handleOSKB(void) {
return retval;
}
void toggleOSKB(bool forceon) {
void toggleOSKB(int forceon) {
if (forceon) {
oskbOn = true;
drawOSKB();
@ -1332,6 +1400,17 @@ int emu_FileRead(void * buf, int size, int handler)
#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) {
// emu_printf("FileGetc");
// emu_printi(handler);
@ -1404,6 +1483,9 @@ unsigned int emu_FileSize(const char * filepath)
emu_printf(filesize);
lofile.close();
}
else {
emu_printf("filesize failed");
}
return(filesize);
}
@ -1489,6 +1571,48 @@ static bool emu_eraseConfig(void)
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
********************************/
@ -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);
vgahires = hires;
#ifdef HAS_USBKEY
#ifdef HAS_USB
myusb.begin();
#ifdef HAS_USBKEY
keyboard1.attachPress(OnPress);
keyboard1.attachRelease(OnRelease);
#endif
#endif
while (!SD.begin(SD_CS))
#ifdef FILEBROWSER
if (!SD.begin(SD_CS))
{
Serial.println("SD begin failed, retrying...");
delay(1000);
Serial.println("No SD card detected");
}
strcpy(selection,ROMSDIR);
FileHandlersInit();
nbFiles = readNbFiles();
Serial.print("SD initialized, files found: ");
Serial.println(nbFiles);
#endif
emu_InitJoysticks();
#ifdef SWAP_JOYSTICK
joySwapped = true;
joySwapped = true;
#else
joySwapped = false;
joySwapped = false;
#endif
#ifdef TEECOMPUTER
#ifndef HAS_T4_VGA
tft.flipscreen(false);
#endif
#endif
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) {
tft.fillScreenNoDma( RGBVAL16(0xff,0x00,0x00) );
tft.drawTextNoDma(64,48, (char*)" AUTURUN file erased", RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
#ifdef FILEBROWSER
emu_eraseConfig();
delay(1000);
#endif
}
else {
#ifdef FILEBROWSER
if (emu_readConfig()) {
autorun = true;
}
#endif
}
#ifdef FILEBROWSER
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;
}

Wyświetl plik

@ -2,126 +2,14 @@
#define EMUAPI_H
#include "platform_config.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)
#include "emucfg.h"
#define ACTION_NONE 0
#define ACTION_MAXKBDVAL 16
#define ACTION_EXITKBD 128
#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 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
@ -138,22 +26,25 @@ const unsigned short matkeys[] = {
#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_init(void);
extern void emu_start(void);
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);
@ -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 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_DrawLine(unsigned char * VBuf, int width, int height, int line);
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_CopyLine(int width, int height, int ysrc, int ydst);
extern void emu_DrawVsync(void);
extern int emu_FrameSkip(void);
extern void * emu_LineBuffer(int line);
extern void emu_tweakVideo(int shiftdelta, int numdelta, int denomdelta);
extern int emu_IsVga(void);
extern int emu_IsVgaHires(void);
extern bool menuActive(void);
extern int menuActive(void);
extern char * menuSelection(void);
extern char * menuSecondSelection(void);
extern void toggleMenu(bool on);
extern void toggleMenu(int on);
extern int handleMenu(unsigned short bClick);
extern int handleOSKB(void);
extern void toggleOSKB(bool forceon);
extern void toggleOSKB(int forceon);
extern void emu_InitJoysticks(void);
extern int emu_SwapJoysticks(int statusOnly);
@ -190,6 +80,7 @@ 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);

Wyświetl plik

@ -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

Wyświetl plik

@ -4,13 +4,13 @@
#define TEECOMPUTER 1
#ifdef TEECOMPUTER
//#define ILI9341 1
//#define ST7789 1
//#define TFTSPI1 1
#define HAS_T4_VGA 1
#define TFTSPI1 1
//#define HAS_T4_VGA 1
//#define HAS_SND 1
#define HAS_USB 1
#define HAS_USBKEY 1
#define INVX 1
//#define HAS_USBMOUSE 1
//#define HAS_USBMIDI 1
#define PT8211 1
#else
@ -18,8 +18,12 @@
#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 PT8211 1
#endif

Wyświetl plik

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

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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

Wyświetl plik

@ -3,132 +3,20 @@ extern "C" {
#include "iopins.h"
}
#include "aiie.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
// ****************************************************
void setup() {
#ifdef HAS_T4_VGA
tft.begin(VGA_MODE_320x240);
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
#else
tft.begin();
#endif
emu_init();
}
static void vbl(void) {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
}
// ****************************************************
// the loop() method runs continuously
@ -139,60 +27,15 @@ void loop(void)
uint16_t bClick = emu_DebounceLocalKeys();
int action = handleMenu(bClick);
char * filename = menuSelection();
if (action == ACTION_RUN1) {
toggleMenu(false);
vgaMode = false;
emu_start();
if (action == ACTION_RUN1) {
emu_start(20000,nullptr);
emu_Init(filename);
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
tft.startDMA();
myTimer.begin(vblCount, 20000); //to run every 20ms
}
delay(20);
}
else {
uint16_t bClick = emu_DebounceLocalKeys();
emu_Input(bClick);
emu_Step();
delay(10);
//uint16_t bClick = emu_DebounceLocalKeys();
//if (bClick & MASK_KEY_USER1) {
// 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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -174,39 +174,44 @@ void aiie_Step(void)
#endif
{
if ( !(pik & MASK_JOY2_BTN) && (k & MASK_JOY2_BTN) ) {
g_keyboard->onPress(RA);
g_keyboard->onPress(LA);
}
else if ( (pik & MASK_JOY2_BTN) && !(k & MASK_JOY2_BTN) ) {
g_keyboard->onRelease(RA);
g_keyboard->onRelease(LA);
}
}
if ( !(pik & MASK_JOY1_BTN) && (k & MASK_JOY1_BTN) ) {
g_keyboard->onPress(RA);
g_keyboard->onPress(LA);
}
else if ( (pik & MASK_JOY1_BTN) && !(k & MASK_JOY1_BTN) ) {
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 != +1) padxinc += 1;
if (padx != 255) padx += padxinc;
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 != -1) padxinc -= 1;
if (padx != 0) padx += padxinc;
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 != 1) padyinc += 1;
if (pady != 255) pady += padyinc;
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 != -1) padyinc -= 1;
if (pady != 0) pady += padyinc;

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