add T41 VGA supprt for all emus except st and amiga
This commit is contained in:
parent
b11ae4b91b
commit
cb094fe973
342 changed files with 19766 additions and 232327 deletions
Binary file not shown.
|
|
@ -195,4 +195,3 @@ void AudioPlaySystem::sound(int C, int F, int V) {
|
|||
void AudioPlaySystem::step(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -455,6 +455,13 @@ static void Initialise(void)
|
|||
cont2.analog_v = POT_CENTRE;
|
||||
}
|
||||
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
|
||||
void at5_Init(void)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -593,9 +600,3 @@ void at5_Start(char * cartname)
|
|||
|
||||
emu_printf("init done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,17 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const uint16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const uint16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
#include "logo.h"
|
||||
#endif
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -19,6 +28,13 @@ extern "C" {
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -84,7 +100,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -93,7 +109,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -113,13 +129,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -245,7 +258,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -272,13 +285,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -400,6 +429,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -575,7 +610,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -592,7 +627,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -637,7 +672,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -651,10 +686,6 @@ void handleVirtualkeyboard() {
|
|||
}
|
||||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -726,10 +757,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -839,7 +872,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -847,8 +880,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -1338,11 +1373,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1387,7 +1549,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1413,5 +1579,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#define CUSTOM_SND 1
|
||||
//#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
#define CUSTOM_SND 1
|
||||
//#define TIMER_REND 1
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
// Title: < >
|
||||
|
|
@ -68,7 +65,7 @@ const unsigned short keysw[] = {
|
|||
// [START] 12 [ 3 ] 13 [ 2 ] 14 [ 1 ] 15
|
||||
|
||||
|
||||
const unsigned short keys[] = {
|
||||
const unsigned short key_map1[] = {
|
||||
12+1,8+1,4+1,
|
||||
0,
|
||||
15+1,14+1,13+1,
|
||||
|
|
@ -108,6 +105,9 @@ const unsigned short i2ckeys[] = {
|
|||
|
||||
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
extern void emu_resetSD(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
extern void emu_printi(int val);
|
||||
extern void * emu_Malloc(int size);
|
||||
|
|
@ -128,6 +128,7 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
|
|
@ -141,6 +142,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -149,9 +153,11 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,21 @@
|
|||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
//#define OLD_LAYOUT 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
#define ILI9341 1
|
||||
#define HAS_SND 1
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_USBKEY 1
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ extern "C" {
|
|||
#include "emuapi.h"
|
||||
}
|
||||
#include "keyboard_osd.h"
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
extern "C" {
|
||||
#include "atari5200.h"
|
||||
|
|
@ -36,7 +35,14 @@ uVGA uvga;
|
|||
uint8_t * VGA_frame_buffer;
|
||||
#endif
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -60,7 +66,7 @@ void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int
|
|||
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);
|
||||
palette16[index] = RGBVAL16(r,g,b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +76,11 @@ void emu_DrawVsync(void)
|
|||
skip += 1;
|
||||
skip &= VID_FRAME_SKIP;
|
||||
if (!vgaMode) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.waitSync();
|
||||
#else
|
||||
while (vbl==vb) {};
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -82,7 +92,11 @@ void emu_DrawVsync(void)
|
|||
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
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -100,11 +114,43 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
|||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -154,8 +200,13 @@ void * emu_LineBuffer(int line)
|
|||
// the setup() method runs once, when the sketch starts
|
||||
// ****************************************************
|
||||
void setup() {
|
||||
tft.begin();
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_352x240);
|
||||
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
|
||||
#else
|
||||
tft.begin();
|
||||
#endif
|
||||
emu_init();
|
||||
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
|
|
@ -169,15 +220,16 @@ void loop(void)
|
|||
if (menuActive()) {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
int action = handleMenu(bClick);
|
||||
char * filename = menuSelection();
|
||||
char * filename = menuSelection();
|
||||
if (action == ACTION_RUNTFT) {
|
||||
toggleMenu(false);
|
||||
vgaMode = false;
|
||||
vgaMode = false;
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
//digitalWrite(TFT_CS, 1);
|
||||
//digitalWrite(SD_CS, 1);
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
tft.startDMA();
|
||||
tft.startDMA();
|
||||
}
|
||||
else if (action == ACTION_RUNVGA) {
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -185,6 +237,7 @@ void loop(void)
|
|||
vgaMode = true;
|
||||
VGA_frame_buffer = (uint8_t *)malloc((UVGA_YRES*(UVGA_XRES+UVGA_XRES_EXTRA))*sizeof(uint8_t));
|
||||
uvga.set_static_framebuffer(VGA_frame_buffer);
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
int retvga = uvga.begin(&modeline);
|
||||
Serial.println(retvga);
|
||||
|
|
@ -225,8 +278,15 @@ void loop(void)
|
|||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
|
|
@ -234,6 +294,10 @@ AudioConnection patchCord1(mymixer, dac1);
|
|||
|
||||
void emu_sndInit() {
|
||||
Serial.println("sound init");
|
||||
#ifdef HAS_T4_VGA
|
||||
sgtl5000_1.enable();
|
||||
sgtl5000_1.volume(0.6);
|
||||
#endif
|
||||
AudioMemory(16);
|
||||
mymixer.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
|
||||
|
||||
#define TFT_WIDTH 320 //640 //320
|
||||
#define TFT_REALWIDTH 320 //640 //320
|
||||
#define TFT_WIDTH 320
|
||||
#define TFT_REALWIDTH 320
|
||||
|
||||
#define TFT_HEIGHT 240
|
||||
#define TFT_REALHEIGHT 240
|
||||
|
|
@ -44,8 +44,8 @@ class TFT_T_DMA: public VGA_T4
|
|||
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 vga_pixel *bitmap) { drawSprite(x, y, bitmap); }
|
||||
void drawSpriteNoDma(int16_t x, int16_t y, const vga_pixel *bitmap, uint16_t croparx, uint16_t cropary, uint16_t croparw, uint16_t croparh) { drawSprite(x, y, bitmap, croparx, cropary, croparw, croparh); }
|
||||
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); }
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -50,13 +50,18 @@
|
|||
#define USBHOST (!PS2KEYBOARD)
|
||||
|
||||
|
||||
#include "tft_t_dma.h"
|
||||
extern TFT_T_DMA tft;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
void initMachine();
|
||||
void resetMachine() __attribute__ ((noreturn));
|
||||
void resetExternal();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
|
||||
extern "C" {
|
||||
#include "emuapi.h"
|
||||
#include "platform_config.h"
|
||||
}
|
||||
|
||||
#include "Teensy64.h"
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -251,7 +253,9 @@ void c64_Init(void)
|
|||
resetCia2();
|
||||
resetVic();
|
||||
cpu_reset();
|
||||
#ifdef HAS_SND
|
||||
emu_sndInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -307,6 +311,12 @@ void c64_Input(int bClick) {
|
|||
}
|
||||
}
|
||||
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
#ifdef HAS_SND
|
||||
void SND_Process( void * stream, int len )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,8 +5,17 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const uint16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const uint16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
#include "logo.h"
|
||||
#endif
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -19,6 +28,13 @@ extern "C" {
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -84,7 +100,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -93,7 +109,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -113,13 +129,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -245,7 +258,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -272,13 +285,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -400,6 +429,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -454,6 +489,7 @@ int emu_ReadKeys(void)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
|
@ -479,9 +515,9 @@ int emu_ReadI2CKeyboard(void) {
|
|||
if (b != 0xff) hitindex=i;
|
||||
msg[i++] = b;
|
||||
}
|
||||
|
||||
|
||||
if (hitindex >=0 ) {
|
||||
/*
|
||||
/*
|
||||
Serial.println(msg[0], BIN);
|
||||
Serial.println(msg[1], BIN);
|
||||
Serial.println(msg[2], BIN);
|
||||
|
|
@ -491,7 +527,7 @@ int emu_ReadI2CKeyboard(void) {
|
|||
Serial.println(msg[6], BIN);
|
||||
*/
|
||||
unsigned short match = (~msg[hitindex])&0x00FF | (hitindex<<8);
|
||||
Serial.println(match,HEX);
|
||||
//Serial.println(match,HEX);
|
||||
for (i=0; i<sizeof(i2ckeys); i++) {
|
||||
if (match == i2ckeys[i]) {
|
||||
//Serial.println((int)keys[i]);
|
||||
|
|
@ -574,7 +610,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -591,7 +627,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -636,7 +672,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -650,10 +686,6 @@ void handleVirtualkeyboard() {
|
|||
}
|
||||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -725,10 +757,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -838,7 +872,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -846,8 +880,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -1337,11 +1373,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1386,7 +1549,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1412,5 +1579,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
#define CUSTOM_SND 1
|
||||
#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
// Title: < >
|
||||
#define TITLE " NES Emulator "
|
||||
#define TITLE " C64 Emulator "
|
||||
#define ROMSDIR "c64"
|
||||
|
||||
#define emu_Init(ROM) {c64_Start(ROM); c64_Init(); }
|
||||
|
|
@ -51,7 +49,7 @@ const unsigned short keysw[] = {
|
|||
TAREA_NEW_ROW,40,40,
|
||||
TAREA_END};
|
||||
|
||||
const unsigned short keys[] = {
|
||||
const unsigned short key_map1[] = {
|
||||
2,3};
|
||||
|
||||
#ifdef HAS_I2CKBD
|
||||
|
|
@ -80,6 +78,7 @@ const unsigned short i2ckeys[] = {
|
|||
|
||||
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
extern void emu_resetSD(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
|
|
@ -102,6 +101,7 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
|
|
@ -115,6 +115,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -123,9 +126,10 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "patches.h"
|
||||
#include "emuapi.h"
|
||||
#include "platform_config.h"
|
||||
|
||||
|
||||
#define DIRECTORY ROMSDIR + "/\0"
|
||||
|
|
@ -191,13 +192,17 @@ uint16_t addr,size;
|
|||
|
||||
Serial.println("loading");
|
||||
//printf("%s,%d,%d:", filename, device, secondaryAddress);
|
||||
#ifdef EXTERNAL_SD
|
||||
tft.stopDMA();
|
||||
//emu_resetSD();
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
#endif
|
||||
if (emu_FileOpen(filename) == 0) {
|
||||
//Serial.println("not found");
|
||||
cpu.pc = 0xf530; //Jump to $F530
|
||||
#ifdef EXTERNAL_SD
|
||||
tft.startDMA();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -214,8 +219,9 @@ uint16_t addr,size;
|
|||
cpu.y = 0x49; //Offset for "LOADING"
|
||||
cpu.pc = 0xF12B; //Print and return
|
||||
emu_printf("loaded");
|
||||
#ifdef EXTERNAL_SD
|
||||
tft.startDMA();
|
||||
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,22 @@
|
|||
|
||||
//#define OLD_LAYOUT 1
|
||||
|
||||
#define ILI9341 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
//#define INVX 1
|
||||
#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#define HAS_USBKEY 1
|
||||
//#define HAS_I2CKBD 1
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -2,12 +2,10 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
}
|
||||
#include "keyboard_osd.h"
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
//extern "C" {
|
||||
#include "keyboard_osd.h"
|
||||
|
||||
#include "c64.h"
|
||||
//}
|
||||
|
||||
#ifdef HAS_VGA
|
||||
#include <uVGA.h>
|
||||
|
|
@ -36,7 +34,13 @@ uVGA uvga;
|
|||
uint8_t * VGA_frame_buffer;
|
||||
#endif
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -47,17 +51,12 @@ volatile boolean vbl=true;
|
|||
static int skip=0;
|
||||
static elapsedMicros tius;
|
||||
|
||||
volatile int16_t mClick=0;
|
||||
static void vblCount() {
|
||||
if (vbl) {
|
||||
vbl = false;
|
||||
} else {
|
||||
vbl = true;
|
||||
}
|
||||
emu_Input(mClick);
|
||||
if (mClick) {
|
||||
mClick = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index)
|
||||
|
|
@ -75,19 +74,29 @@ void emu_DrawVsync(void)
|
|||
skip += 1;
|
||||
skip &= VID_FRAME_SKIP;
|
||||
if (!vgaMode) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.waitSync();
|
||||
#else
|
||||
while (vbl==vb) {};
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
while (vbl==vb) {};
|
||||
}
|
||||
#endif
|
||||
#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
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -105,12 +114,29 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
|||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#endif
|
||||
}
|
||||
|
||||
void emu_DrawLine16(unsigned short * VBuf, int width, int height, int line)
|
||||
{
|
||||
if (!vgaMode) {
|
||||
//if (skip==0) {
|
||||
if (skip==0) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.writeLine16(width,height,line, VBuf);
|
||||
#else
|
||||
tft.writeLine(width,height,line, VBuf);
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#endif
|
||||
|
|
@ -120,7 +146,11 @@ 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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -166,15 +196,23 @@ void * emu_LineBuffer(int line)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************
|
||||
// the setup() method runs once, when the sketch starts
|
||||
// ****************************************************
|
||||
void setup() {
|
||||
tft.begin();
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_320x240);
|
||||
NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
|
||||
#else
|
||||
tft.begin();
|
||||
#endif
|
||||
|
||||
emu_init();
|
||||
emu_init();
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************
|
||||
// the loop() method runs continuously
|
||||
// ****************************************************
|
||||
|
|
@ -187,6 +225,7 @@ void loop(void)
|
|||
if (action == ACTION_RUNTFT) {
|
||||
toggleMenu(false);
|
||||
vgaMode = false;
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
//digitalWrite(TFT_CS, 1);
|
||||
//digitalWrite(SD_CS, 1);
|
||||
|
|
@ -200,6 +239,7 @@ void loop(void)
|
|||
vgaMode = true;
|
||||
VGA_frame_buffer = (uint8_t *)malloc((UVGA_YRES*(UVGA_XRES+UVGA_XRES_EXTRA))*sizeof(uint8_t));
|
||||
uvga.set_static_framebuffer(VGA_frame_buffer);
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
int retvga = uvga.begin(&modeline);
|
||||
Serial.println(retvga);
|
||||
|
|
@ -226,11 +266,11 @@ void loop(void)
|
|||
#endif
|
||||
if ( (!virtualkeyboardIsActive()) || (vgaMode) ) {
|
||||
emu_Step();
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
if (bClick & MASK_KEY_USER1) {
|
||||
emu_Input(bClick);
|
||||
mClick = 1;
|
||||
}
|
||||
//delay(20);
|
||||
//uint16_t bClick = emu_DebounceLocalKeys();
|
||||
//if (bClick & MASK_KEY_USER1) {
|
||||
// emu_Input(bClick);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -243,8 +283,15 @@ void loop(void)
|
|||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
|
|
@ -277,5 +324,3 @@ void emu_sndPlayBuzz(int size, int val) {
|
|||
//Serial.println(size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
53
MCUME_teensy/teensy64/vga_t_dma.h
Normal file
53
MCUME_teensy/teensy64/vga_t_dma.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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
|
||||
|
|
@ -69,7 +69,11 @@
|
|||
#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
|
||||
|
|
@ -1270,7 +1274,8 @@ void mode7 (tpixel *p, const tpixel *pe, uint16_t *spl, const uint16_t vc) {
|
|||
typedef void (*modes_t)( tpixel *p, const tpixel *pe, uint16_t *spl, const uint16_t vc ); //Funktionspointer
|
||||
const modes_t modes[8] = {mode0, mode1, mode2, mode3, mode4, mode5, mode6, mode7};
|
||||
|
||||
static uint16_t linebuffer[SCREEN_WIDTH];
|
||||
|
||||
static tpixel linebuffer[SCREEN_WIDTH];
|
||||
|
||||
void vic_do(void) {
|
||||
|
||||
|
|
@ -1304,7 +1309,7 @@ void vic_do(void) {
|
|||
cpu.vic.denLatch = 0;
|
||||
//if (cpu.vic.rasterLine == LINECNT)
|
||||
//delay(50);
|
||||
//emu_DrawVsync();
|
||||
emu_DrawVsync();
|
||||
|
||||
} else cpu.vic.rasterLine++;
|
||||
|
||||
|
|
@ -1602,7 +1607,13 @@ g-Zugriff
|
|||
|
||||
}
|
||||
|
||||
emu_DrawLine16(&linebuffer[0], SCREEN_WIDTH, SCREEN_HEIGHT, (r - FIRSTDISPLAYLINE));
|
||||
#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
|
||||
|
||||
|
||||
|
||||
//Rechter Rand nach CSEL, im Textbereich
|
||||
cpu_clock(5);
|
||||
|
|
|
|||
|
|
@ -267,6 +267,11 @@ void at8_Init(void)
|
|||
Initialise();
|
||||
}
|
||||
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void at8_Step(void)
|
||||
{
|
||||
|
|
@ -371,9 +376,3 @@ void at8_Start(char * cartname)
|
|||
|
||||
emu_printf("init done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,17 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const uint16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const uint16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
#include "logo.h"
|
||||
#endif
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -19,6 +28,13 @@ extern "C" {
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -84,7 +100,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -93,7 +109,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -113,13 +129,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -245,7 +258,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -272,13 +285,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -400,6 +429,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -575,7 +610,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -592,7 +627,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -637,7 +672,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -651,10 +686,6 @@ void handleVirtualkeyboard() {
|
|||
}
|
||||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -726,10 +757,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -839,7 +872,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -847,8 +880,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -1338,11 +1373,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1387,7 +1549,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1413,5 +1579,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
#define CUSTOM_SND 1
|
||||
#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
|
|
@ -18,7 +16,7 @@
|
|||
#define emu_Input(x) {}
|
||||
|
||||
#define PALETTE_SIZE 256
|
||||
#define VID_FRAME_SKIP 0x3
|
||||
#define VID_FRAME_SKIP 0x0
|
||||
#define TFT_VBUFFER_YCROP 0
|
||||
#define SINGLELINE_RENDERING 1
|
||||
|
||||
|
|
@ -60,7 +58,7 @@ const unsigned short keysw[] = {
|
|||
TAREA_END};
|
||||
|
||||
|
||||
const unsigned short keys[] = {
|
||||
const unsigned short key_map1[] = {
|
||||
0x1C+1,0x1F+1,0x1F ,0x1A+1,0x18+1,0x1D+1,0x1B+1,0x33+1,0x35+1,0x30+1,0x32+1,0x36+1,0x37+1,0,0,
|
||||
0x2C+1,0x2F+1,0x2F ,0x2A+1,0x28+1,0x2D+1,0x2B+1,0x0B+1,0x0D+1,0x08+1,0x0A+1,0x0E,0x0F+1,0x0C+1,
|
||||
0, 0x3F+1,0x3F ,0x3A+1,0x38+1,0x3D+1,0x39+1,0x01+1,0x05+1,0x00+1,0x02+1,0x06+1,0x07+1,0,
|
||||
|
|
@ -97,6 +95,9 @@ const unsigned short i2ckeys[] = {
|
|||
|
||||
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
extern void emu_resetSD(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
extern void emu_printi(int val);
|
||||
extern void * emu_Malloc(int size);
|
||||
|
|
@ -117,6 +118,7 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
|
|
@ -130,6 +132,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -138,8 +143,10 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,22 @@
|
|||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
//#define OLD_LAYOUT 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
#define ILI9341 1
|
||||
#define HAS_SND 1
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_USBKEY 1
|
||||
//#define HAS_I2CKBD 1
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ extern "C" {
|
|||
#include "emuapi.h"
|
||||
}
|
||||
#include "keyboard_osd.h"
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
extern "C" {
|
||||
#include "atari800.h"
|
||||
|
|
@ -36,7 +35,14 @@ uVGA uvga;
|
|||
uint8_t * VGA_frame_buffer;
|
||||
#endif
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -60,7 +66,7 @@ void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int
|
|||
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);
|
||||
palette16[index] = RGBVAL16(r,g,b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +76,11 @@ void emu_DrawVsync(void)
|
|||
skip += 1;
|
||||
skip &= VID_FRAME_SKIP;
|
||||
if (!vgaMode) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.waitSync();
|
||||
#else
|
||||
while (vbl==vb) {};
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -82,7 +92,11 @@ void emu_DrawVsync(void)
|
|||
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
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -100,11 +114,43 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
|||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -154,8 +200,13 @@ void * emu_LineBuffer(int line)
|
|||
// the setup() method runs once, when the sketch starts
|
||||
// ****************************************************
|
||||
void setup() {
|
||||
tft.begin();
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_352x240);
|
||||
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 255);
|
||||
#else
|
||||
tft.begin();
|
||||
#endif
|
||||
emu_init();
|
||||
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
|
|
@ -169,15 +220,16 @@ void loop(void)
|
|||
if (menuActive()) {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
int action = handleMenu(bClick);
|
||||
char * filename = menuSelection();
|
||||
char * filename = menuSelection();
|
||||
if (action == ACTION_RUNTFT) {
|
||||
toggleMenu(false);
|
||||
vgaMode = false;
|
||||
vgaMode = false;
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
//digitalWrite(TFT_CS, 1);
|
||||
//digitalWrite(SD_CS, 1);
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
tft.startDMA();
|
||||
tft.startDMA();
|
||||
}
|
||||
else if (action == ACTION_RUNVGA) {
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -185,6 +237,7 @@ void loop(void)
|
|||
vgaMode = true;
|
||||
VGA_frame_buffer = (uint8_t *)malloc((UVGA_YRES*(UVGA_XRES+UVGA_XRES_EXTRA))*sizeof(uint8_t));
|
||||
uvga.set_static_framebuffer(VGA_frame_buffer);
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
int retvga = uvga.begin(&modeline);
|
||||
Serial.println(retvga);
|
||||
|
|
@ -217,6 +270,7 @@ void loop(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
#include <Audio.h>
|
||||
|
|
@ -224,8 +278,15 @@ void loop(void)
|
|||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
|
|
@ -233,6 +294,10 @@ AudioConnection patchCord1(mymixer, dac1);
|
|||
|
||||
void emu_sndInit() {
|
||||
Serial.println("sound init");
|
||||
#ifdef HAS_T4_VGA
|
||||
// sgtl5000_1.enable();
|
||||
// sgtl5000_1.volume(0.6);
|
||||
#endif
|
||||
AudioMemory(16);
|
||||
mymixer.start();
|
||||
}
|
||||
|
|
@ -258,7 +323,3 @@ void emu_sndPlayBuzz(int size, int val) {
|
|||
//Serial.println(size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
53
MCUME_teensy/teensy800/vga_t_dma.h
Normal file
53
MCUME_teensy/teensy800/vga_t_dma.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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
|
||||
|
|
@ -4,13 +4,15 @@
|
|||
|
||||
// #define RAM_SIZE 0xF8000 // 512k //655360UL
|
||||
// #define NATIVE_RAM (0X28000) // 128k+32768 //231424UL
|
||||
#define RAM_SIZE 0x78000 // 512k //655360UL
|
||||
#define NATIVE_RAM (0X28000) // 128k+32768 //231424UL
|
||||
#define NATIVE_START 0UL
|
||||
|
||||
|
||||
#define RAM_SIZE 0x78000 // 512k //655360UL
|
||||
#define NATIVE_RAM (0X28000) // 128k+32768 //231424UL
|
||||
#define NATIVE_START 0UL
|
||||
|
||||
|
||||
|
||||
#define ROM_READ(a,b) a[b]
|
||||
#define ROM_READ(a,b) a[b]
|
||||
|
||||
|
||||
//#define INCLUDE_ROM_BASIC
|
||||
|
|
@ -152,4 +154,3 @@ union _bytewordregs_{
|
|||
uint16_t wordregs[8];
|
||||
uint8_t byteregs[8];
|
||||
} ;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
#define KEYMAP_PRESENT 1
|
||||
|
||||
//extern "C" {
|
||||
extern "C" {
|
||||
#include "emuapi.h"
|
||||
#include "iopins.h"
|
||||
//}
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const uint16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const uint16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
#include "logo.h"
|
||||
#endif
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -19,6 +28,13 @@
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -84,7 +100,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -93,7 +109,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -113,13 +129,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -245,7 +258,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -272,13 +285,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -400,6 +429,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -575,7 +610,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -592,7 +627,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -637,7 +672,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -651,10 +686,6 @@ void handleVirtualkeyboard() {
|
|||
}
|
||||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -726,10 +757,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -839,7 +872,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -847,8 +880,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -1338,11 +1373,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1387,7 +1549,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1413,5 +1579,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#else
|
||||
#endif
|
||||
//#define HAS_SND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
//#define CUSTOM_SND 1
|
||||
#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
|
@ -60,7 +55,7 @@ const unsigned short keysw[]=
|
|||
//TAREA_NEW_ROW,18,18,18,18,18,18,18,18,18,18,
|
||||
TAREA_END};
|
||||
|
||||
const unsigned short keys[]={
|
||||
const unsigned short key_map1[]={
|
||||
|
||||
59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
|
||||
109,110,111,112,106,107,108,17,18,19,
|
||||
|
|
@ -99,10 +94,16 @@ const unsigned short i2ckeys[] = {
|
|||
#define MASK_KEY_USER4 0x2000
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
extern void emu_printi(int val);
|
||||
|
||||
extern void * emu_Malloc(int size);
|
||||
extern void emu_Free(void * pt);
|
||||
|
||||
|
|
@ -121,6 +122,7 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
|
|
@ -134,6 +136,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -142,9 +147,14 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,22 @@
|
|||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
//#define OLD_LAYOUT 1
|
||||
#define HAS_T41 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
//#define HAS_SND 1
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_USBKEY 1
|
||||
|
||||
//#define ILI9341 1
|
||||
#define ST7789 1
|
||||
#define SWAP_JOYSTICK 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
|
||||
extern "C" {
|
||||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
}
|
||||
#include "keyboard_osd.h"
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
#include "test.h"
|
||||
|
||||
|
|
@ -33,7 +33,14 @@ uVGA uvga;
|
|||
uint8_t * VGA_frame_buffer;
|
||||
#endif
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -55,9 +62,8 @@ static void vblCount() {
|
|||
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);
|
||||
palette16[index] = RGBVAL16(r,g,b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +73,11 @@ void emu_DrawVsync(void)
|
|||
skip += 1;
|
||||
skip &= VID_FRAME_SKIP;
|
||||
if (!vgaMode) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.waitSync();
|
||||
#else
|
||||
while (vbl==vb) {};
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -79,7 +89,11 @@ void emu_DrawVsync(void)
|
|||
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
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -97,11 +111,28 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
|||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -112,7 +143,11 @@ 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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -162,13 +197,18 @@ void * emu_LineBuffer(int line)
|
|||
// the setup() method runs once, when the sketch starts
|
||||
// ****************************************************
|
||||
void setup() {
|
||||
tft.begin();
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_640x240);
|
||||
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
|
||||
#else
|
||||
tft.begin();
|
||||
#endif
|
||||
emu_init();
|
||||
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
}
|
||||
static unsigned char col=0;
|
||||
|
||||
// ****************************************************
|
||||
// the loop() method runs continuously
|
||||
// ****************************************************
|
||||
|
|
@ -177,13 +217,16 @@ void loop(void)
|
|||
if (menuActive()) {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
int action = handleMenu(bClick);
|
||||
char * filename = menuSelection();
|
||||
char * filename = menuSelection();
|
||||
if (action == ACTION_RUNTFT) {
|
||||
toggleMenu(false);
|
||||
vgaMode = false;
|
||||
emu_Init(filename);
|
||||
vgaMode = false;
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
//digitalWrite(TFT_CS, 1);
|
||||
//digitalWrite(SD_CS, 1);
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
tft.startDMA();
|
||||
tft.startDMA();
|
||||
}
|
||||
else if (action == ACTION_RUNVGA) {
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -191,6 +234,7 @@ void loop(void)
|
|||
vgaMode = true;
|
||||
VGA_frame_buffer = (uint8_t *)malloc((UVGA_YRES*(UVGA_XRES+UVGA_XRES_EXTRA))*sizeof(uint8_t));
|
||||
uvga.set_static_framebuffer(VGA_frame_buffer);
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
int retvga = uvga.begin(&modeline);
|
||||
Serial.println(retvga);
|
||||
|
|
@ -215,29 +259,42 @@ void loop(void)
|
|||
handleVirtualkeyboard();
|
||||
#endif
|
||||
if ( (!virtualkeyboardIsActive()) || (vgaMode) ) {
|
||||
emu_Step();
|
||||
//delay(20);
|
||||
//tft.fillScreen( RGBVAL16(0xff,col,0x00) );
|
||||
//if ((uint32_t)_pfbtft >= 0x20200000u) arm_dcache_flush(_pfbtft, CBALLOC);
|
||||
//col++;
|
||||
emu_Step();
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
emu_Input(bClick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
#include <Audio.h>
|
||||
#include "AudioPlaySystem.h"
|
||||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
#endif
|
||||
|
||||
void emu_sndInit() {
|
||||
Serial.println("sound init");
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
sgtl5000_1.enable();
|
||||
sgtl5000_1.volume(0.6);
|
||||
#endif
|
||||
AudioMemory(16);
|
||||
mymixer.start();
|
||||
}
|
||||
|
|
@ -247,7 +304,6 @@ void emu_sndPlaySound(int chan, int volume, int freq)
|
|||
if (chan < 6) {
|
||||
mymixer.sound(chan, freq, volume);
|
||||
}
|
||||
|
||||
/*
|
||||
Serial.print(chan);
|
||||
Serial.print(":" );
|
||||
|
|
|
|||
|
|
@ -4,7 +4,13 @@
|
|||
#include "emu.h"
|
||||
#include "ps2.h"
|
||||
|
||||
#ifdef HAS_T41
|
||||
EXTMEM static unsigned char MemPool[8*1024*1024];
|
||||
#else
|
||||
static uint8_t LOMEM[NATIVE_RAM];
|
||||
#endif
|
||||
|
||||
|
||||
uint8_t * RAM;
|
||||
uint8_t * LORAM;
|
||||
|
||||
|
|
@ -333,14 +339,15 @@ void installPalette(void) {
|
|||
|
||||
extern uint8_t vidmode, portram[0x400];
|
||||
|
||||
#define XRES 320
|
||||
#define YRES 200
|
||||
#define XRES_MAX 640
|
||||
#define XRES_HI 640
|
||||
#define XRES_LO 320
|
||||
#define YRES 200
|
||||
|
||||
#include "font.h"
|
||||
|
||||
|
||||
static unsigned short line[XRES];
|
||||
|
||||
static unsigned short line[XRES_MAX];
|
||||
|
||||
void drawscreentext80(void) {
|
||||
uint16_t row, col, y, x, xpos;
|
||||
|
|
@ -360,23 +367,23 @@ void drawscreentext80(void) {
|
|||
fg = attrib & 0x0F;
|
||||
//if (y == 0) {printf("0x%02X",cc);}
|
||||
fontdata = ROM_READ(font, ((uint32_t)cc << 3) + (y&0x7));
|
||||
for (x=0; x<4; x++)
|
||||
for (x=0; x<8; x++)
|
||||
//for (x=0; x<4; x++)
|
||||
{
|
||||
if (fontdata & 1) {
|
||||
line[xpos++] = palettecga[fg];
|
||||
} else {
|
||||
line[xpos++] = palettecga[bg];
|
||||
}
|
||||
fontdata >>= 2;
|
||||
fontdata >>= 1;
|
||||
//fontdata >>= 2;
|
||||
}
|
||||
}
|
||||
|
||||
emu_DrawLine16(&line[0], XRES, YRES, y);
|
||||
emu_DrawLine16(&line[0], XRES_HI, YRES, y);
|
||||
}
|
||||
}
|
||||
|
||||
void drawscreenlorescga(void) {
|
||||
//uint16_t row;
|
||||
uint16_t y, x, xpos;
|
||||
uint8_t intensity, usepal;
|
||||
uint16_t color;
|
||||
|
|
@ -385,10 +392,8 @@ void drawscreenlorescga(void) {
|
|||
|
||||
for (y=0; y<(25*8); y++)
|
||||
{
|
||||
//row = y>>3;
|
||||
//uint8_t * vrampt=&VRAM[160*row];
|
||||
xpos = 0;
|
||||
for (x=0; x<XRES; x++)
|
||||
for (x=0; x<XRES_LO; x++)
|
||||
{
|
||||
int ychar = y;// >> 1;
|
||||
int xchar = x;// >> 1;
|
||||
|
|
@ -403,8 +408,7 @@ void drawscreenlorescga(void) {
|
|||
if (color == (usepal + intensity)) color = 0;
|
||||
line[xpos++] = palettecga[color];
|
||||
}
|
||||
|
||||
emu_DrawLine16(&line[0], XRES, YRES, y);
|
||||
emu_DrawLine16(&line[0], XRES_LO, YRES, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -415,7 +419,7 @@ void drawscreenhirescga(void) {
|
|||
for (y=0; y<(25*8); y++)
|
||||
{
|
||||
xpos = 0;
|
||||
for (x=0; x<XRES; x++)
|
||||
for (x=0; x<XRES_HI; x++)
|
||||
{
|
||||
int ychar = y >> 1;
|
||||
int xchar = x;
|
||||
|
|
@ -423,8 +427,7 @@ void drawscreenhirescga(void) {
|
|||
color = ((curchar >> (7-(x&7))) & 1) ? 15 : 0;
|
||||
line[xpos++] = palettecga[color];
|
||||
}
|
||||
|
||||
emu_DrawLine16(&line[0], XRES, YRES, y);
|
||||
emu_DrawLine16(&line[0], XRES_HI, YRES, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,9 +460,10 @@ static uint8_t nbkeys=0;
|
|||
static uint8_t kcnt=0;
|
||||
static int toggle=1;
|
||||
|
||||
//static char * seq="DIR\r";
|
||||
//static char * seq="CAT.EXE\r";
|
||||
static char * seq="PRINCE.BAT\r";
|
||||
static char * seq;
|
||||
static char * seq1="PRINCE.BAT\r";
|
||||
static char * seq2="CAT.EXE\r";
|
||||
static char * seq3="DIR\r";
|
||||
|
||||
static int mouse_x = 160;
|
||||
static int mouse_y = 100;
|
||||
|
|
@ -480,7 +484,6 @@ static void keyevent(int keysym, int isdown)
|
|||
if (!isdown) portram[0x60] |= 0x80;
|
||||
portram[0x64] |= 2;
|
||||
doirq(1);
|
||||
//vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -490,7 +493,13 @@ extern void apc_Input(int bClick) {
|
|||
|
||||
if (nbkeys == 0) {
|
||||
if (bClick & MASK_JOY2_BTN) {
|
||||
nbkeys = strlen(seq);
|
||||
nbkeys = strlen(seq1);
|
||||
seq=seq1;
|
||||
kcnt=0;
|
||||
}
|
||||
if (bClick & MASK_KEY_USER1) {
|
||||
nbkeys = strlen(seq2);
|
||||
seq=seq2;
|
||||
kcnt=0;
|
||||
}
|
||||
}
|
||||
|
|
@ -554,35 +563,23 @@ static void do_events(void)
|
|||
}
|
||||
else {
|
||||
if (( k & MASK_JOY1_RIGHT) || ( k & MASK_JOY2_RIGHT)) {
|
||||
if ( mouse_x < XRES ) {
|
||||
if ( mouse_x < XRES_HI ) {
|
||||
mouse_x += 1;
|
||||
//Serial.print("r");
|
||||
//IkbdMouseMotion ( mouse_x, mouse_y );
|
||||
//IkbdLoop();
|
||||
}
|
||||
}
|
||||
else if (( k & MASK_JOY1_LEFT) || ( k & MASK_JOY2_LEFT)) {
|
||||
if ( mouse_x > 1 ) {
|
||||
mouse_x -= 1;
|
||||
//Serial.print("l");
|
||||
//IkbdMouseMotion ( mouse_x, mouse_y );
|
||||
//IkbdLoop();
|
||||
mouse_x -= 1;
|
||||
}
|
||||
}
|
||||
else if (( k & MASK_JOY1_UP) || ( k & MASK_JOY2_UP)) {
|
||||
if ( mouse_y > 1 ) {
|
||||
mouse_y -= 1;
|
||||
//Serial.print("u");
|
||||
//IkbdMouseMotion ( mouse_x, mouse_y );
|
||||
//IkbdLoop();
|
||||
mouse_y -= 1;
|
||||
}
|
||||
}
|
||||
else if (( k & MASK_JOY1_DOWN) || ( k & MASK_JOY2_DOWN)) {
|
||||
if ( mouse_y < YRES ) {
|
||||
mouse_y += 1;
|
||||
//Serial.print("d");
|
||||
//IkbdMouseMotion ( mouse_x, mouse_y );
|
||||
//IkbdLoop();
|
||||
mouse_y += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -591,15 +588,17 @@ static void do_events(void)
|
|||
mouseb=1;
|
||||
}
|
||||
if ( (mouseb != prev_mouseb) ){
|
||||
//if (mouseb) IkbdMousePress(2);
|
||||
//else IkbdMouseRelease(2);
|
||||
//Serial.println("btoggle");
|
||||
//IkbdLoop();
|
||||
prev_mouseb = mouseb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void apc_Step(void)
|
||||
{
|
||||
exec86(8000);
|
||||
|
|
@ -612,12 +611,18 @@ void apc_Step(void)
|
|||
|
||||
void apc_Init(void)
|
||||
{
|
||||
#ifdef HAS_T41
|
||||
LORAM = MemPool;
|
||||
RAM = MemPool + NATIVE_RAM;
|
||||
#else
|
||||
RAM = (uint8_t*) malloc(RAM_SIZE);
|
||||
if (!RAM) emu_printf("SPI RAM malloc failed");
|
||||
if (!RAM) emu_printf("RAM malloc failed");
|
||||
LORAM = &LOMEM[0];
|
||||
//LORAM = (uint8_t*)malloc(NATIVE_RAM);
|
||||
//if (!LORAM) emu_printf("LORAM malloc failed");
|
||||
|
||||
#endif
|
||||
|
||||
installPalette();
|
||||
init8253();
|
||||
reset86();
|
||||
|
|
@ -630,9 +635,3 @@ void apc_Start(char * filename)
|
|||
initDisk(filename);
|
||||
emu_printf("init done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
53
MCUME_teensy/teensy8086/vga_t_dma.h
Normal file
53
MCUME_teensy/teensy8086/vga_t_dma.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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 640
|
||||
#define TFT_REALWIDTH 640
|
||||
|
||||
#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
|
||||
|
|
@ -5,10 +5,20 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const uint16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const uint16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
//#include "logo.h"
|
||||
#include "logozx80kbd.h"
|
||||
#include "logozx81kbd.h"
|
||||
static const uint16_t * logo = logozx80kbd;
|
||||
#endif
|
||||
static const unsigned short * keysw = keyswzx80;
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -21,6 +31,13 @@ extern "C" {
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -86,7 +103,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -95,7 +112,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -115,14 +132,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
static const uint16_t * logo = logozx80kbd;
|
||||
static const unsigned short * keysw = keyswzx80;
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -248,7 +261,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -275,13 +288,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -403,6 +432,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -578,7 +613,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -595,7 +630,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -640,7 +675,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -655,11 +690,15 @@ void handleVirtualkeyboard() {
|
|||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
#ifndef HAS_T4_VGA
|
||||
logo = logozx81kbd;
|
||||
#endif
|
||||
keysw = keyswzx81;
|
||||
}
|
||||
else {
|
||||
#ifndef HAS_T4_VGA
|
||||
logo = logozx80kbd;
|
||||
#endif
|
||||
keysw = keyswzx80;
|
||||
}
|
||||
}
|
||||
|
|
@ -733,10 +772,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -846,7 +887,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -854,8 +895,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -1345,11 +1388,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1394,7 +1564,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1420,5 +1594,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
//#define TIMER_REND 1
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
// Title: < >
|
||||
|
|
@ -62,7 +59,7 @@ const unsigned short keyswzx81[] = {
|
|||
TAREA_NEW_ROW,30,30,30,30,30,30,30,30,30,30,
|
||||
TAREA_END};
|
||||
|
||||
const unsigned short keys[] = {
|
||||
const unsigned short key_map1[] = {
|
||||
30,31,32,33,34,35,36,37,38,39,
|
||||
20,26, 8,21,23,28,25,12,18,19,
|
||||
4, 9, 7,22, 4,11,13,14,15,40,
|
||||
|
|
@ -96,8 +93,10 @@ const unsigned short i2ckeys[] = {
|
|||
#define MASK_KEY_USER4 0x2000
|
||||
|
||||
|
||||
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
extern void emu_resetSD(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
extern void emu_printi(int val);
|
||||
extern void * emu_Malloc(int size);
|
||||
|
|
@ -118,6 +117,7 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
|
|
@ -131,6 +131,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -139,10 +142,10 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,22 @@
|
|||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
//#define OLD_LAYOUT 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
#define ILI9341 1
|
||||
//#define HAS_SND 1
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_USBKEY 1
|
||||
//#define HAS_I2CKBD 1
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ extern "C" {
|
|||
#include "emuapi.h"
|
||||
}
|
||||
#include "keyboard_osd.h"
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
extern "C" {
|
||||
#include "zx81.h"
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAS_VGA
|
||||
#include <uVGA.h>
|
||||
uVGA uvga;
|
||||
|
|
@ -36,7 +36,14 @@ uVGA uvga;
|
|||
uint8_t * VGA_frame_buffer;
|
||||
#endif
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -60,7 +67,7 @@ void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int
|
|||
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);
|
||||
palette16[index] = RGBVAL16(r,g,b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +77,11 @@ void emu_DrawVsync(void)
|
|||
skip += 1;
|
||||
skip &= VID_FRAME_SKIP;
|
||||
if (!vgaMode) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.waitSync();
|
||||
#else
|
||||
while (vbl==vb) {};
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -82,7 +93,11 @@ void emu_DrawVsync(void)
|
|||
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
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -100,11 +115,43 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
|||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -154,8 +201,13 @@ void * emu_LineBuffer(int line)
|
|||
// the setup() method runs once, when the sketch starts
|
||||
// ****************************************************
|
||||
void setup() {
|
||||
tft.begin();
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_352x240);
|
||||
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
|
||||
#else
|
||||
tft.begin();
|
||||
#endif
|
||||
emu_init();
|
||||
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
|
|
@ -169,15 +221,16 @@ void loop(void)
|
|||
if (menuActive()) {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
int action = handleMenu(bClick);
|
||||
char * filename = menuSelection();
|
||||
char * filename = menuSelection();
|
||||
if (action == ACTION_RUNTFT) {
|
||||
toggleMenu(false);
|
||||
vgaMode = false;
|
||||
vgaMode = false;
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
//digitalWrite(TFT_CS, 1);
|
||||
//digitalWrite(SD_CS, 1);
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
tft.startDMA();
|
||||
tft.startDMA();
|
||||
}
|
||||
else if (action == ACTION_RUNVGA) {
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -185,6 +238,7 @@ void loop(void)
|
|||
vgaMode = true;
|
||||
VGA_frame_buffer = (uint8_t *)malloc((UVGA_YRES*(UVGA_XRES+UVGA_XRES_EXTRA))*sizeof(uint8_t));
|
||||
uvga.set_static_framebuffer(VGA_frame_buffer);
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
int retvga = uvga.begin(&modeline);
|
||||
Serial.println(retvga);
|
||||
|
|
@ -217,6 +271,7 @@ void loop(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
#include <Audio.h>
|
||||
|
|
@ -224,8 +279,15 @@ void loop(void)
|
|||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
|
|
@ -233,6 +295,10 @@ AudioConnection patchCord1(mymixer, dac1);
|
|||
|
||||
void emu_sndInit() {
|
||||
Serial.println("sound init");
|
||||
#ifdef HAS_T4_VGA
|
||||
sgtl5000_1.enable();
|
||||
sgtl5000_1.volume(0.6);
|
||||
#endif
|
||||
AudioMemory(16);
|
||||
mymixer.start();
|
||||
}
|
||||
|
|
@ -258,6 +324,3 @@ void emu_sndPlayBuzz(int size, int val) {
|
|||
//Serial.println(size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -443,7 +446,7 @@ void TFT_T_DMA::startDMA(void) {
|
|||
digitalWrite(_cs, HIGH);
|
||||
SPI.begin();
|
||||
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
|
||||
#ifdef TFT_DEBUG
|
||||
PRREG(LPSPI4_CCR);
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
53
MCUME_teensy/teensy81/vga_t_dma.h
Normal file
53
MCUME_teensy/teensy81/vga_t_dma.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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
|
||||
|
|
@ -200,6 +200,7 @@ void do_interrupt()
|
|||
|
||||
void bitbufBlit(unsigned char * buf)
|
||||
{
|
||||
emu_DrawVsync();
|
||||
memset( XBuf, 1, WIDTH*8 );
|
||||
buf = buf + (ZX_VID_MARGIN*(ZX_VID_FULLWIDTH/8));
|
||||
int y,x,i;
|
||||
|
|
@ -472,6 +473,13 @@ static void initmem()
|
|||
}
|
||||
|
||||
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
|
||||
void z81_Init(void)
|
||||
{
|
||||
#if HAS_SND
|
||||
|
|
@ -516,8 +524,7 @@ void z81_Step(void)
|
|||
{
|
||||
ExecZ80();
|
||||
sighandler(0);
|
||||
//if (strlen(tapename)) handleKeyBuf();
|
||||
emu_DrawVsync();
|
||||
//if (strlen(tapename)) handleKeyBuf();
|
||||
updateKeyboard();
|
||||
Loop8910(&ay,20);
|
||||
}
|
||||
|
|
@ -558,4 +565,3 @@ void z81_Start(char * filename)
|
|||
ramsize = 56;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ static void do_events(void)
|
|||
|
||||
|
||||
if (hk != prev_hk) {
|
||||
prev_hk == hk;
|
||||
prev_hk = hk;
|
||||
if ( (hk != 0) && (hk != prev_key) ) {
|
||||
prev_key = hk;
|
||||
IkbdKeyPress ( hk );
|
||||
|
|
|
|||
|
|
@ -110,6 +110,12 @@ struct
|
|||
/***************************************
|
||||
* Exported procedures
|
||||
***************************************/
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void coc_Init(void)
|
||||
{
|
||||
int J;
|
||||
|
|
@ -894,5 +900,3 @@ void RefreshLine3(register byte Y)
|
|||
|
||||
RefreshBorder(Y);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,17 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const int16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const int16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
#include "logo.h"
|
||||
#endif
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -19,6 +28,13 @@ extern "C" {
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -84,7 +100,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -93,7 +109,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -113,13 +129,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -245,7 +258,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -272,13 +285,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -400,6 +429,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -575,7 +610,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -592,7 +627,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -637,7 +672,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -651,10 +686,6 @@ void handleVirtualkeyboard() {
|
|||
}
|
||||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -726,10 +757,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -839,7 +872,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -847,8 +880,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -1338,11 +1373,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1387,7 +1549,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1413,5 +1579,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
//#define TIMER_REND 1
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
// Title: < >
|
||||
|
|
@ -53,7 +50,7 @@ const unsigned short keysw[] = {
|
|||
TAREA_NEW_ROW,20,20,20,
|
||||
TAREA_END};
|
||||
|
||||
const unsigned short keys[] = {
|
||||
const unsigned short key_map1[] = {
|
||||
2,3,4,
|
||||
5,6,7,
|
||||
8,9,10,
|
||||
|
|
@ -86,8 +83,10 @@ const unsigned short i2ckeys[] = {
|
|||
#define MASK_KEY_USER4 0x2000
|
||||
|
||||
|
||||
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
extern void emu_resetSD(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
extern void emu_printi(int val);
|
||||
extern void * emu_Malloc(int size);
|
||||
|
|
@ -108,6 +107,7 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
|
|
@ -121,6 +121,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -129,9 +132,11 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,21 @@
|
|||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
//#define OLD_LAYOUT 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
#define ILI9341 1
|
||||
//#define HAS_SND 1
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_USBKEY 1
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ extern "C" {
|
|||
#include "emuapi.h"
|
||||
}
|
||||
#include "keyboard_osd.h"
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
extern "C" {
|
||||
#include "Colem.h"
|
||||
|
|
@ -36,7 +35,14 @@ uVGA uvga;
|
|||
uint8_t * VGA_frame_buffer;
|
||||
#endif
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -60,7 +66,7 @@ void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int
|
|||
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);
|
||||
palette16[index] = RGBVAL16(r,g,b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +76,11 @@ void emu_DrawVsync(void)
|
|||
skip += 1;
|
||||
skip &= VID_FRAME_SKIP;
|
||||
if (!vgaMode) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.waitSync();
|
||||
#else
|
||||
while (vbl==vb) {};
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -82,7 +92,11 @@ void emu_DrawVsync(void)
|
|||
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
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -100,11 +114,43 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
|||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -154,8 +200,13 @@ void * emu_LineBuffer(int line)
|
|||
// the setup() method runs once, when the sketch starts
|
||||
// ****************************************************
|
||||
void setup() {
|
||||
tft.begin();
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_352x240);
|
||||
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
|
||||
#else
|
||||
tft.begin();
|
||||
#endif
|
||||
emu_init();
|
||||
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
|
|
@ -169,15 +220,16 @@ void loop(void)
|
|||
if (menuActive()) {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
int action = handleMenu(bClick);
|
||||
char * filename = menuSelection();
|
||||
char * filename = menuSelection();
|
||||
if (action == ACTION_RUNTFT) {
|
||||
toggleMenu(false);
|
||||
vgaMode = false;
|
||||
vgaMode = false;
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
//digitalWrite(TFT_CS, 1);
|
||||
//digitalWrite(SD_CS, 1);
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
tft.startDMA();
|
||||
tft.startDMA();
|
||||
}
|
||||
else if (action == ACTION_RUNVGA) {
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -185,6 +237,7 @@ void loop(void)
|
|||
vgaMode = true;
|
||||
VGA_frame_buffer = (uint8_t *)malloc((UVGA_YRES*(UVGA_XRES+UVGA_XRES_EXTRA))*sizeof(uint8_t));
|
||||
uvga.set_static_framebuffer(VGA_frame_buffer);
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
int retvga = uvga.begin(&modeline);
|
||||
Serial.println(retvga);
|
||||
|
|
@ -209,14 +262,15 @@ void loop(void)
|
|||
handleVirtualkeyboard();
|
||||
#endif
|
||||
if ( (!virtualkeyboardIsActive()) || (vgaMode) ) {
|
||||
emu_Step();
|
||||
delay(20);
|
||||
emu_Step();
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
emu_Input(bClick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
#include <Audio.h>
|
||||
|
|
@ -224,8 +278,15 @@ void loop(void)
|
|||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
|
|
@ -233,6 +294,10 @@ AudioConnection patchCord1(mymixer, dac1);
|
|||
|
||||
void emu_sndInit() {
|
||||
Serial.println("sound init");
|
||||
#ifdef HAS_T4_VGA
|
||||
sgtl5000_1.enable();
|
||||
sgtl5000_1.volume(0.6);
|
||||
#endif
|
||||
AudioMemory(16);
|
||||
mymixer.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
50
MCUME_teensy/teensycolem/vga_t_dma.h
Normal file
50
MCUME_teensy/teensycolem/vga_t_dma.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
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 256
|
||||
#define TFT_REALWIDTH 320
|
||||
|
||||
#define TFT_HEIGHT 192
|
||||
#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
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "emuapi.h"
|
||||
#include "tft_t_dma.h"
|
||||
#include "psram_t.h"
|
||||
#include "iopins.h"
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -10,6 +9,29 @@ extern "C" {
|
|||
#include "system.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T41
|
||||
|
||||
EXTMEM static unsigned char MemPool[8*1024*1024];
|
||||
|
||||
extern "C" uint8 read_rom(int address) {
|
||||
return (MemPool[address]);
|
||||
}
|
||||
|
||||
extern "C" uint8 readb_swap_rom(int address) {
|
||||
return (MemPool[address^1]);
|
||||
}
|
||||
|
||||
extern "C" uint16 readw_swap_rom(int address) {
|
||||
return ((MemPool[address+1]<<8) + MemPool[address]);
|
||||
}
|
||||
extern "C" void write_rom(int address, uint8 val) {
|
||||
MemPool[address]=val;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "psram_t.h"
|
||||
|
||||
PSRAM_T psram = PSRAM_T(PSRAM_CS, PSRAM_MOSI, PSRAM_SCLK, PSRAM_MISO);
|
||||
|
||||
extern "C" uint8 read_rom(int address) {
|
||||
|
|
@ -27,6 +49,8 @@ extern "C" void write_rom(int address, uint8 val) {
|
|||
psram.pswrite(address,val);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static uint8 romversion;
|
||||
extern "C" uint8 rom_version(void) {
|
||||
return romversion;
|
||||
|
|
@ -47,11 +71,18 @@ static deinterleave_block(int offset, int srcoffset)
|
|||
}
|
||||
}
|
||||
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void gen_Init(void)
|
||||
{
|
||||
emu_printf("Allocating MEM");
|
||||
#ifndef HAS_T41
|
||||
psram.begin();
|
||||
#endif
|
||||
mem_init();
|
||||
emu_printf("Allocating MEM done");
|
||||
}
|
||||
|
|
@ -167,7 +198,3 @@ audio_play_sample(stream, 0, len);
|
|||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,17 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const uint16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const uint16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
#include "logo.h"
|
||||
#endif
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -19,6 +28,13 @@ extern "C" {
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -84,7 +100,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -93,7 +109,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -113,13 +129,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -245,7 +258,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -272,13 +285,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -400,6 +429,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -575,7 +610,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -592,7 +627,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -637,7 +672,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -651,10 +686,6 @@ void handleVirtualkeyboard() {
|
|||
}
|
||||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -726,10 +757,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -839,7 +872,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -847,8 +880,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -1338,11 +1373,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1387,7 +1549,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1413,5 +1579,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
#define CUSTOM_SND 1
|
||||
//#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
|
||||
#define EXTRA_HEAP 0x10 //0x9000
|
||||
#ifdef HAS_T4_VGA
|
||||
#define EXTRA_HEAP 0x10000
|
||||
#else
|
||||
#define EXTRA_HEAP 0x10
|
||||
#endif
|
||||
|
||||
// Title: < >
|
||||
#define TITLE " Genesis Emulator "
|
||||
|
|
@ -18,7 +20,7 @@
|
|||
#define emu_Step(x) {gen_Step();}
|
||||
#define emu_Input(x) {gen_Input(x);}
|
||||
|
||||
#define PALETTE_SIZE 2
|
||||
#define PALETTE_SIZE 1
|
||||
#define VID_FRAME_SKIP 0x0
|
||||
#define TFT_VBUFFER_YCROP 0
|
||||
#define SINGLELINE_RENDERING 1
|
||||
|
|
@ -57,7 +59,7 @@ const unsigned short keysw[]=
|
|||
//TAREA_NEW_ROW,18,18,18,18,18,18,18,18,18,18,
|
||||
TAREA_END};
|
||||
|
||||
const unsigned short keys[]={
|
||||
const unsigned short key_map1[]={
|
||||
|
||||
59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
|
||||
109,110,111,112,106,107,108,17,18,19,
|
||||
|
|
@ -101,17 +103,17 @@ const unsigned short i2ckeys[] = {
|
|||
extern "C" {
|
||||
#endif
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
extern void emu_printi(int val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
extern void * emu_Malloc(int size);
|
||||
extern void emu_Free(void * pt);
|
||||
|
||||
|
||||
extern int emu_FileOpen(char * filename);
|
||||
extern int emu_FileRead(char * buf, int size);
|
||||
extern unsigned char emu_FileGetc(void);
|
||||
extern int emu_FileTell(void);
|
||||
extern int emu_FileSeek(int seek);
|
||||
extern void emu_FileClose(void);
|
||||
extern int emu_FileSize(char * filename);
|
||||
|
|
@ -124,6 +126,7 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
|
|
@ -137,6 +140,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -145,12 +151,14 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,22 @@
|
|||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
//#define OLD_LAYOUT 1
|
||||
#define HAS_T41 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
#define ILI9341 1
|
||||
//#define HAS_SND 1
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_USBKEY 1
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -240,7 +240,6 @@ Serial.printf("D") ; Serial.flush();
|
|||
|
||||
#include "emuapi.h"
|
||||
|
||||
|
||||
PSRAM_T::PSRAM_T(uint8_t cs, uint8_t mosi, uint8_t sclk, uint8_t miso)
|
||||
{
|
||||
}
|
||||
|
|
@ -386,4 +385,3 @@ uint16_t PSRAM_T::psread_w(uint32_t addr)
|
|||
psram_read_n(curPage,&(pages[top].page[0]),PAGE_SIZE);
|
||||
return (pages[top].page[offs+1]<<8) + pages[top].page[offs];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,14 @@
|
|||
|
||||
|
||||
#include "shared.h"
|
||||
#include "platform_config.h"
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
#endif
|
||||
extern void emu_DrawLine16(unsigned short *src, int width , int height, int line);
|
||||
extern void emu_printf(char * text);
|
||||
|
||||
|
||||
#ifdef ALIGN_LONG
|
||||
|
||||
|
|
@ -14,6 +22,27 @@
|
|||
#undef READ_LONG
|
||||
#undef WRITE_LONG
|
||||
|
||||
|
||||
|
||||
if(reg[12] & 8)
|
||||
{
|
||||
int j;
|
||||
for(j = 0; j < 3; j += 1)
|
||||
{
|
||||
color = &vdp_palette[j][data];
|
||||
set_color((j << 6), color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
color = &vdp_palette[1][data];
|
||||
set_color(0x00, color);
|
||||
set_color(0x40, color);
|
||||
set_color(0x80, color);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ uint32 READ_LONG(void *address)
|
||||
{
|
||||
if ((uint32)address & 3)
|
||||
|
|
@ -155,6 +184,9 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
|||
|
||||
/* Pixel creation macros, input is four bits each */
|
||||
|
||||
/* 3:3:2 RGB */
|
||||
#define MAKE_PIXEL_8(r,g,b) ((r) << 5 | (g) << 2 | ((b) >> 1))
|
||||
|
||||
/* 5:6:5 RGB */
|
||||
#define MAKE_PIXEL_16(r,g,b) ((r) << 12 | (g) << 7 | (b) << 1)
|
||||
|
||||
|
|
@ -229,6 +261,7 @@ int render_init(void)
|
|||
pixel_16_lut[2][i] = MAKE_PIXEL_16(r|8,g|8,b|8);
|
||||
}
|
||||
|
||||
|
||||
/* Set up color update function */
|
||||
color_update = color_update_16;
|
||||
|
||||
|
|
@ -283,6 +316,7 @@ void render_reset(void)
|
|||
memset(ntb_buf, 0, sizeof(ntb_buf));
|
||||
memset(obj_buf, 0, sizeof(obj_buf));
|
||||
|
||||
//memset(&pixel_8, 0, sizeof(pixel_8));
|
||||
memset(&pixel_16, 0, sizeof(pixel_16));
|
||||
}
|
||||
|
||||
|
|
@ -363,12 +397,8 @@ void render_line(int line)
|
|||
|
||||
|
||||
int width = (reg[12] & 1) ? 320 : 256;
|
||||
|
||||
|
||||
|
||||
remap_16(lb+0x20, line_buf, pixel_16, width);
|
||||
emu_DrawLine16(line_buf, width ,256, line);
|
||||
//remap_16(lb+0x20, emu_LineBuffer(line), pixel_16, width);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Window rendering */
|
||||
|
|
@ -770,18 +800,6 @@ void window_clip(int line)
|
|||
/*--------------------------------------------------------------------------*/
|
||||
/* Remap functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
void remap_8(uint8 *src, uint8 *dst, uint8 *table, int length)
|
||||
{
|
||||
int count;
|
||||
for(count = 0; count < length; count += 1)
|
||||
{
|
||||
*dst++ = table[*src++];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void remap_16(uint8 *src, uint16 *dst, uint16 *table, int length)
|
||||
{
|
||||
int count;
|
||||
|
|
@ -808,6 +826,7 @@ void merge(uint8 *srca, uint8 *srcb, uint8 *dst, uint8 *table, int width)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void color_update_16(int index, uint16 data)
|
||||
{
|
||||
if(reg[12] & 8)
|
||||
|
|
@ -1044,4 +1063,3 @@ void render_obj_im2(int line, uint8 *buf, uint8 *table)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,40 +1,39 @@
|
|||
|
||||
#ifndef _RENDER_H_
|
||||
#define _RENDER_H_
|
||||
|
||||
|
||||
/* Look-up pixel table information */
|
||||
#define LUT_MAX (5)
|
||||
#define LUT_SIZE (0x10000)
|
||||
|
||||
/* Clip structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8 left;
|
||||
uint8 right;
|
||||
uint8 enable;
|
||||
}clip_t;
|
||||
|
||||
/* Function prototypes */
|
||||
int render_init(void);
|
||||
void render_reset(void);
|
||||
void render_shutdown(void);
|
||||
void render_line(int line);
|
||||
void render_obj(int line, uint8 *buf, uint8 *table);
|
||||
void render_obj_im2(int line, uint8 *buf, uint8 *table);
|
||||
void render_ntw(int line, uint8 *buf);
|
||||
void render_ntw_im2(int line, uint8 *buf);
|
||||
void render_ntx(int which, int line, uint8 *buf);
|
||||
void render_ntx_im2(int which, int line, uint8 *buf);
|
||||
void render_ntx_vs(int which, int line, uint8 *buf);
|
||||
void update_bg_pattern_cache(void);
|
||||
void get_hscroll(int line, uint16 *scrolla, uint16 *scrollb);
|
||||
void window_clip(int line);
|
||||
void remap_16(uint8 *src, uint16 *dst, uint16 *table, int length);
|
||||
void merge(uint8 *srca, uint8 *srcb, uint8 *dst, uint8 *table, int width);
|
||||
void color_update_16(int index, uint16 data);
|
||||
void make_name_lut(void);
|
||||
void parse_satb(int line);
|
||||
|
||||
#endif /* _RENDER_H_ */
|
||||
|
||||
|
||||
#ifndef _RENDER_H_
|
||||
#define _RENDER_H_
|
||||
|
||||
|
||||
/* Look-up pixel table information */
|
||||
#define LUT_MAX (5)
|
||||
#define LUT_SIZE (0x10000)
|
||||
|
||||
/* Clip structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8 left;
|
||||
uint8 right;
|
||||
uint8 enable;
|
||||
}clip_t;
|
||||
|
||||
/* Function prototypes */
|
||||
int render_init(void);
|
||||
void render_reset(void);
|
||||
void render_shutdown(void);
|
||||
void render_line(int line);
|
||||
void render_obj(int line, uint8 *buf, uint8 *table);
|
||||
void render_obj_im2(int line, uint8 *buf, uint8 *table);
|
||||
void render_ntw(int line, uint8 *buf);
|
||||
void render_ntw_im2(int line, uint8 *buf);
|
||||
void render_ntx(int which, int line, uint8 *buf);
|
||||
void render_ntx_im2(int which, int line, uint8 *buf);
|
||||
void render_ntx_vs(int which, int line, uint8 *buf);
|
||||
void update_bg_pattern_cache(void);
|
||||
void get_hscroll(int line, uint16 *scrolla, uint16 *scrollb);
|
||||
void window_clip(int line);
|
||||
void remap_16(uint8 *src, uint16 *dst, uint16 *table, int length);
|
||||
void merge(uint8 *srca, uint8 *srcb, uint8 *dst, uint8 *table, int width);
|
||||
void color_update_16(int index, uint16 data);
|
||||
void make_name_lut(void);
|
||||
void parse_satb(int line);
|
||||
|
||||
#endif /* _RENDER_H_ */
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
|
||||
extern "C" {
|
||||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
}
|
||||
#include "keyboard_osd.h"
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
|
@ -33,7 +34,14 @@ uVGA uvga;
|
|||
uint8_t * VGA_frame_buffer;
|
||||
#endif
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -55,9 +63,8 @@ static void vblCount() {
|
|||
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);
|
||||
palette16[index] = RGBVAL16(r,g,b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +74,11 @@ void emu_DrawVsync(void)
|
|||
skip += 1;
|
||||
skip &= VID_FRAME_SKIP;
|
||||
if (!vgaMode) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.waitSync();
|
||||
#else
|
||||
while (vbl==vb) {};
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -79,7 +90,11 @@ void emu_DrawVsync(void)
|
|||
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
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -97,11 +112,28 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
|||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -112,7 +144,11 @@ 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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -162,14 +198,18 @@ void * emu_LineBuffer(int line)
|
|||
// the setup() method runs once, when the sketch starts
|
||||
// ****************************************************
|
||||
void setup() {
|
||||
tft.begin();
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_320x240);
|
||||
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
|
||||
#else
|
||||
tft.begin();
|
||||
#endif
|
||||
emu_init();
|
||||
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************
|
||||
// the loop() method runs continuously
|
||||
// ****************************************************
|
||||
|
|
@ -178,13 +218,16 @@ void loop(void)
|
|||
if (menuActive()) {
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
int action = handleMenu(bClick);
|
||||
char * filename = menuSelection();
|
||||
char * filename = menuSelection();
|
||||
if (action == ACTION_RUNTFT) {
|
||||
toggleMenu(false);
|
||||
vgaMode = false;
|
||||
emu_Init(filename);
|
||||
vgaMode = false;
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
//digitalWrite(TFT_CS, 1);
|
||||
//digitalWrite(SD_CS, 1);
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
tft.startDMA();
|
||||
tft.startDMA();
|
||||
}
|
||||
else if (action == ACTION_RUNVGA) {
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -192,6 +235,7 @@ void loop(void)
|
|||
vgaMode = true;
|
||||
VGA_frame_buffer = (uint8_t *)malloc((UVGA_YRES*(UVGA_XRES+UVGA_XRES_EXTRA))*sizeof(uint8_t));
|
||||
uvga.set_static_framebuffer(VGA_frame_buffer);
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
int retvga = uvga.begin(&modeline);
|
||||
Serial.println(retvga);
|
||||
|
|
@ -216,13 +260,15 @@ void loop(void)
|
|||
handleVirtualkeyboard();
|
||||
#endif
|
||||
if ( (!virtualkeyboardIsActive()) || (vgaMode) ) {
|
||||
emu_Step();
|
||||
uint16_t bClick = 0; //emu_DebounceLocalKeys();
|
||||
emu_Step();
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
emu_Input(bClick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
#include <Audio.h>
|
||||
|
|
@ -230,8 +276,15 @@ void loop(void)
|
|||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
|
|
@ -239,6 +292,10 @@ AudioConnection patchCord1(mymixer, dac1);
|
|||
|
||||
void emu_sndInit() {
|
||||
Serial.println("sound init");
|
||||
#ifdef HAS_T4_VGA
|
||||
sgtl5000_1.enable();
|
||||
sgtl5000_1.volume(0.6);
|
||||
#endif
|
||||
AudioMemory(16);
|
||||
mymixer.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
53
MCUME_teensy/teensygen/vga_t_dma.h
Normal file
53
MCUME_teensy/teensygen/vga_t_dma.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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 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
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "emuapi.h"
|
||||
#include "tft_t_dma.h"
|
||||
#include "psram_t.h"
|
||||
#include "iopins.h"
|
||||
|
||||
|
|
@ -21,27 +20,39 @@ extern "C" {
|
|||
#include "loader.h"
|
||||
}
|
||||
|
||||
|
||||
static int rom_offset = 0;
|
||||
|
||||
PSRAM_T psram = PSRAM_T(PSRAM_CS, PSRAM_MOSI, PSRAM_SCLK, PSRAM_MISO);
|
||||
|
||||
#ifdef HAS_T41
|
||||
EXTMEM static unsigned char MemPool[8*1024*1024];
|
||||
|
||||
extern "C" uint8 read_rom(int address) {
|
||||
return (MemPool[address+rom_offset]);
|
||||
}
|
||||
|
||||
extern "C" void write_rom(int address, uint8 val) {
|
||||
MemPool[address]=val;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "psram_t.h"
|
||||
|
||||
PSRAM_T psram = PSRAM_T(PSRAM_CS, PSRAM_MOSI, PSRAM_SCLK, PSRAM_MISO);
|
||||
|
||||
extern "C" uint8 read_rom(int address) {
|
||||
return (psram.psread(address+rom_offset));
|
||||
}
|
||||
|
||||
//extern "C" uint8 readb_swap_rom(int address) {
|
||||
// return(psram.psread(address^1));
|
||||
//}
|
||||
|
||||
//extern "C" uint16 readw_swap_rom(int address) {
|
||||
// return psram.psread_w(address);
|
||||
//}
|
||||
|
||||
extern "C" void write_rom(int address, uint8 val) {
|
||||
psram.pswrite(address,val);
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -49,7 +60,9 @@ extern "C" void write_rom(int address, uint8 val) {
|
|||
void gbe_Init(void)
|
||||
{
|
||||
emu_printf("Allocating MEM");
|
||||
#ifndef HAS_T41
|
||||
psram.begin();
|
||||
#endif
|
||||
mem_init();
|
||||
emu_printf("Allocating MEM done");
|
||||
}
|
||||
|
|
@ -98,8 +111,10 @@ void gbe_Start(char * Cartridge)
|
|||
cpu_reset();
|
||||
mbc_reset();
|
||||
#ifdef SOUND_PRESENT
|
||||
#ifdef HAS_SND
|
||||
sound_reset(22050);
|
||||
emu_sndInit();
|
||||
emu_sndInit();
|
||||
#endif
|
||||
#endif
|
||||
lcd_begin();
|
||||
emu_printf("init done");
|
||||
|
|
@ -151,7 +166,3 @@ void SND_Process(void *stream, int len) {
|
|||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,17 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const uint16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const uint16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
#include "logo.h"
|
||||
#endif
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -19,6 +28,13 @@ extern "C" {
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -84,7 +100,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -93,7 +109,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -113,13 +129,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -245,7 +258,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -272,13 +285,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -400,6 +429,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -413,7 +448,7 @@ int emu_ReadKeys(void)
|
|||
if ( digitalRead(PIN_KEY_USER4) == LOW ) retval |= MASK_KEY_USER4;
|
||||
#endif
|
||||
|
||||
//Serial.println(retval,HEX);
|
||||
// Serial.println(retval,HEX);
|
||||
|
||||
if ( ((retval & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2))
|
||||
|| (retval & MASK_KEY_USER4 ) )
|
||||
|
|
@ -575,7 +610,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -592,7 +627,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -637,7 +672,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -651,10 +686,6 @@ void handleVirtualkeyboard() {
|
|||
}
|
||||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -726,10 +757,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -839,7 +872,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -847,8 +880,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -1338,11 +1373,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1387,7 +1549,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1413,5 +1579,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_SND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
#define CUSTOM_SND 1
|
||||
//#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
|
||||
#define EXTRA_HEAP 0x10 //0x9000
|
||||
|
|
@ -57,7 +55,7 @@ const unsigned short keysw[]=
|
|||
//TAREA_NEW_ROW,18,18,18,18,18,18,18,18,18,18,
|
||||
TAREA_END};
|
||||
|
||||
const unsigned short keys[]={
|
||||
const unsigned short key_map1[]={
|
||||
|
||||
59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
|
||||
109,110,111,112,106,107,108,17,18,19,
|
||||
|
|
@ -101,17 +99,17 @@ const unsigned short i2ckeys[] = {
|
|||
extern "C" {
|
||||
#endif
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
extern void emu_resetSD(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
extern void emu_printi(int val);
|
||||
extern void emu_printh(int val);
|
||||
extern void * emu_Malloc(int size);
|
||||
extern void emu_Free(void * pt);
|
||||
|
||||
|
||||
extern int emu_FileOpen(char * filename);
|
||||
extern int emu_FileRead(char * buf, int size);
|
||||
extern unsigned char emu_FileGetc(void);
|
||||
extern int emu_FileTell(void);
|
||||
extern int emu_FileSeek(int seek);
|
||||
extern void emu_FileClose(void);
|
||||
extern int emu_FileSize(char * filename);
|
||||
|
|
@ -124,6 +122,7 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
|
|
@ -137,6 +136,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -145,12 +147,14 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,22 @@
|
|||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
//#define OLD_LAYOUT 1
|
||||
#define HAS_T41 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
#define ILI9341 1
|
||||
#define HAS_SND 1
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_USBKEY 1
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
extern "C" {
|
||||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
}
|
||||
|
||||
#include "keyboard_osd.h"
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
|
@ -33,7 +34,13 @@ uVGA uvga;
|
|||
uint8_t * VGA_frame_buffer;
|
||||
#endif
|
||||
|
||||
#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;
|
||||
|
||||
|
|
@ -43,6 +50,9 @@ static IntervalTimer myTimer;
|
|||
volatile boolean vbl=true;
|
||||
static int skip=0;
|
||||
static elapsedMicros tius;
|
||||
volatile int16_t mClick=0;
|
||||
|
||||
|
||||
|
||||
static void vblCount() {
|
||||
if (vbl) {
|
||||
|
|
@ -67,7 +77,11 @@ void emu_DrawVsync(void)
|
|||
skip += 1;
|
||||
skip &= VID_FRAME_SKIP;
|
||||
if (!vgaMode) {
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.waitSync();
|
||||
#else
|
||||
while (vbl==vb) {};
|
||||
#endif
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -79,7 +93,11 @@ void emu_DrawVsync(void)
|
|||
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
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
else {
|
||||
|
|
@ -97,11 +115,28 @@ void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
|||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
#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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -112,7 +147,11 @@ 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
|
||||
}
|
||||
}
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -158,15 +197,20 @@ void * emu_LineBuffer(int line)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************
|
||||
// the setup() method runs once, when the sketch starts
|
||||
// ****************************************************
|
||||
void setup() {
|
||||
tft.begin();
|
||||
|
||||
emu_init();
|
||||
|
||||
myTimer.begin(vblCount, 20000); //to run every 20ms
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_320x240);
|
||||
NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
|
||||
#else
|
||||
tft.begin();
|
||||
#endif
|
||||
|
||||
emu_init();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -181,10 +225,14 @@ void loop(void)
|
|||
char * filename = menuSelection();
|
||||
if (action == ACTION_RUNTFT) {
|
||||
toggleMenu(false);
|
||||
vgaMode = false;
|
||||
emu_Init(filename);
|
||||
vgaMode = false;
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
//digitalWrite(TFT_CS, 1);
|
||||
//digitalWrite(SD_CS, 1);
|
||||
tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) );
|
||||
tft.startDMA();
|
||||
myTimer.begin(vblCount, 40000); //to run every 40ms
|
||||
}
|
||||
else if (action == ACTION_RUNVGA) {
|
||||
#ifdef HAS_VGA
|
||||
|
|
@ -192,6 +240,7 @@ void loop(void)
|
|||
vgaMode = true;
|
||||
VGA_frame_buffer = (uint8_t *)malloc((UVGA_YRES*(UVGA_XRES+UVGA_XRES_EXTRA))*sizeof(uint8_t));
|
||||
uvga.set_static_framebuffer(VGA_frame_buffer);
|
||||
emu_start();
|
||||
emu_Init(filename);
|
||||
int retvga = uvga.begin(&modeline);
|
||||
Serial.println(retvga);
|
||||
|
|
@ -202,6 +251,7 @@ void loop(void)
|
|||
// In VGA mode, we show the keyboard on TFT
|
||||
toggleVirtualkeyboard(true); // keepOn
|
||||
Serial.println("Starting");
|
||||
myTimer.begin(vblCount, 40000); //to run every 20ms
|
||||
#endif
|
||||
}
|
||||
delay(20);
|
||||
|
|
@ -216,13 +266,18 @@ void loop(void)
|
|||
handleVirtualkeyboard();
|
||||
#endif
|
||||
if ( (!virtualkeyboardIsActive()) || (vgaMode) ) {
|
||||
emu_Step();
|
||||
uint16_t bClick = 0; //emu_DebounceLocalKeys();
|
||||
emu_Input(bClick);
|
||||
emu_Step();
|
||||
//delay(20);
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
emu_Input(bClick);
|
||||
if (bClick & MASK_KEY_USER1) {
|
||||
mClick = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
#include <Audio.h>
|
||||
|
|
@ -230,8 +285,15 @@ void loop(void)
|
|||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
53
MCUME_teensy/teensygnuboy/vga_t_dma.h
Normal file
53
MCUME_teensy/teensygnuboy/vga_t_dma.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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 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
|
||||
|
|
@ -5,8 +5,17 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
}
|
||||
|
||||
#ifdef HAS_T4_VGA
|
||||
#include "vga_t_dma.h"
|
||||
const uint16_t deflogo[] = {
|
||||
0,0
|
||||
};
|
||||
static const uint16_t * logo = deflogo;
|
||||
#else
|
||||
#include "tft_t_dma.h"
|
||||
#include "logo.h"
|
||||
#endif
|
||||
|
||||
#include "bmpjoy.h"
|
||||
#include "bmpvbar.h"
|
||||
#ifdef OLD_LAYOUT
|
||||
|
|
@ -19,6 +28,13 @@ extern "C" {
|
|||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
#include "USBHost_t36.h" // Read this header first for key info
|
||||
USBHost myusb;
|
||||
KeyboardController keyboard1(myusb);
|
||||
#endif
|
||||
static uint8_t usbnavpad=0;
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include "uSDFS.h"
|
||||
static FATFS fatfs;
|
||||
|
|
@ -84,7 +100,7 @@ static File file;
|
|||
#define MKEY_TFT 23
|
||||
#define MKEY_VGA 24
|
||||
|
||||
#define MAX_FILES 32
|
||||
#define MAX_FILES 64
|
||||
#define MAX_FILENAME_SIZE 24
|
||||
#define MAX_MENULINES (MKEY_L9)
|
||||
#define TEXT_HEIGHT 16
|
||||
|
|
@ -93,7 +109,7 @@ static File file;
|
|||
#define MENU_FILE_YOFFSET (2*TEXT_HEIGHT)
|
||||
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||||
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x20)
|
||||
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x40)
|
||||
#define MENU_JOYS_YOFFSET (12*TEXT_HEIGHT)
|
||||
#define MENU_VBAR_XOFFSET (0*TEXT_WIDTH)
|
||||
#define MENU_VBAR_YOFFSET (MENU_FILE_YOFFSET)
|
||||
|
|
@ -113,13 +129,10 @@ static char selection[MAX_FILENAME_SIZE+1]="";
|
|||
static char files[MAX_FILES][MAX_FILENAME_SIZE];
|
||||
static bool menuRedraw=true;
|
||||
|
||||
static int16_t calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static int calMinX=-1,calMinY=-1,calMaxX=-1,calMaxY=-1;
|
||||
static bool i2cKeyboardPresent = false;
|
||||
//const uint16_t deflogo[] = {
|
||||
// 0x0000,0x0000
|
||||
//};
|
||||
//static const uint16_t * logo = deflogo;
|
||||
|
||||
static unsigned short * keys;
|
||||
static int keyMap;
|
||||
|
||||
const unsigned short menutouchareas[] = {
|
||||
TAREA_XY,MENU_FILE_XOFFSET,MENU_FILE_YOFFSET,
|
||||
|
|
@ -245,7 +258,7 @@ void emu_printf(int val)
|
|||
|
||||
void emu_printi(int val)
|
||||
{
|
||||
Serial.println(val);
|
||||
Serial.println(val,HEX);
|
||||
}
|
||||
|
||||
void emu_printh(int val)
|
||||
|
|
@ -272,13 +285,29 @@ void * emu_Malloc(int size)
|
|||
}
|
||||
}
|
||||
else {
|
||||
emu_printf("could allocate ");
|
||||
emu_printf("could allocate dynamic ");
|
||||
emu_printf(size);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void * emu_MallocI(int size)
|
||||
{
|
||||
void * retval = NULL;
|
||||
|
||||
if ( (malbufpt+size) < sizeof(malbuf) ) {
|
||||
retval = (void *)&malbuf[malbufpt];
|
||||
malbufpt += size;
|
||||
emu_printf("could allocate static ");
|
||||
emu_printf(size);
|
||||
}
|
||||
else {
|
||||
emu_printf("failure to allocate");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void emu_Free(void * pt)
|
||||
{
|
||||
free(pt);
|
||||
|
|
@ -400,6 +429,12 @@ int emu_ReadKeys(void)
|
|||
retval = ((j2 << 8) | j1);
|
||||
}
|
||||
|
||||
if (usbnavpad & MASK_JOY2_UP) retval |= MASK_JOY2_UP;
|
||||
if (usbnavpad & MASK_JOY2_DOWN) retval |= MASK_JOY2_DOWN;
|
||||
if (usbnavpad & MASK_JOY2_LEFT) retval |= MASK_JOY2_LEFT;
|
||||
if (usbnavpad & MASK_JOY2_RIGHT) retval |= MASK_JOY2_RIGHT;
|
||||
if (usbnavpad & MASK_JOY2_BTN) retval |= MASK_JOY2_BTN;
|
||||
|
||||
#ifdef PIN_KEY_USER1
|
||||
if ( digitalRead(PIN_KEY_USER1) == LOW ) retval |= MASK_KEY_USER1;
|
||||
#endif
|
||||
|
|
@ -575,7 +610,7 @@ bool virtualkeyboardIsActive(void) {
|
|||
void toggleVirtualkeyboard(bool keepOn) {
|
||||
|
||||
if (keepOn) {
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbKeepOn = true;
|
||||
vkbActive = true;
|
||||
|
|
@ -592,7 +627,7 @@ void toggleVirtualkeyboard(bool keepOn) {
|
|||
}
|
||||
else {
|
||||
tft.stopDMA();
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo);
|
||||
tft.drawSpriteNoDma(0,0,logo);
|
||||
//prev_zt = 0;
|
||||
vkbActive = true;
|
||||
exitVkbd = false;
|
||||
|
|
@ -637,7 +672,7 @@ void handleVirtualkeyboard() {
|
|||
|
||||
if (vkeyRefresh) {
|
||||
vkeyRefresh = false;
|
||||
tft.drawSpriteNoDma(0,0,(uint16_t*)logo, rx, ry, rw, rh);
|
||||
tft.drawSpriteNoDma(0,0,logo, rx, ry, rw, rh);
|
||||
}
|
||||
|
||||
if ( (exitVkbd) && (vkbActive) ) {
|
||||
|
|
@ -651,10 +686,6 @@ void handleVirtualkeyboard() {
|
|||
}
|
||||
|
||||
int emu_setKeymap(int index) {
|
||||
if (index) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -726,10 +757,12 @@ void backgroundMenu(void) {
|
|||
menuRedraw=true;
|
||||
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,(uint16_t*)bmpvbar);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(MENU_VBAR_XOFFSET,MENU_VBAR_YOFFSET,bmpvbar);
|
||||
#endif
|
||||
#ifdef OLD_LAYOUT
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,(uint16_t*)bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,(uint16_t*)bmpvga);
|
||||
tft.drawSpriteNoDma(MENU_TFT_XOFFSET,MENU_TFT_YOFFSET,bmptft);
|
||||
tft.drawSpriteNoDma(MENU_VGA_XOFFSET,MENU_VGA_YOFFSET,bmpvga);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -839,7 +872,7 @@ int handleMenu(uint16_t bClick)
|
|||
strcpy(selection,filename);
|
||||
}
|
||||
else {
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, 0xFFFF, 0x0000, true);
|
||||
tft.drawTextNoDma(MENU_FILE_XOFFSET,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, filename, RGBVAL16(0xff,0xff,0xff), MENU_FILE_BGCOLOR, true);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
|
@ -847,8 +880,10 @@ int handleMenu(uint16_t bClick)
|
|||
fileIndex++;
|
||||
}
|
||||
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0xff,0x00,0x00), false);
|
||||
#ifndef HAS_T4_VGA
|
||||
tft.drawSpriteNoDma(0,MENU_JOYS_YOFFSET,(uint16_t*)bmpjoy);
|
||||
#endif
|
||||
tft.drawTextNoDma(48,MENU_JOYS_YOFFSET+8, (emu_SwapJoysticks(1)?(char*)"SWAP=1":(char*)"SWAP=0"), RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), false);
|
||||
menuRedraw=false;
|
||||
}
|
||||
|
||||
|
|
@ -910,7 +945,7 @@ static void readCallibration(void)
|
|||
#else
|
||||
File file = SD.open(CALIBRATION_FILE, O_READ);
|
||||
if (file) {
|
||||
if ( file.read(fileBuffer, 64) ) {
|
||||
if ( file.read(fileBuffer, 64) ) {
|
||||
sscanf(fileBuffer,"%d %d %d %d", &calMinX,&calMinY,&calMaxX,&calMaxY);
|
||||
}
|
||||
file.close();
|
||||
|
|
@ -924,7 +959,7 @@ static void readCallibration(void)
|
|||
else {
|
||||
Serial.println("Callibration read error");
|
||||
}
|
||||
tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY);
|
||||
tft.callibrateTouch(calMinX,calMinY,calMaxX,calMaxY);
|
||||
}
|
||||
|
||||
static void writeCallibration(void)
|
||||
|
|
@ -1338,11 +1373,138 @@ void emu_FileTempWrite(int addr, unsigned char val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
void OnPress(auto key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad |= MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad |= MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad |= MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad |= MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad |= MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnDown(keymodifier, key);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRelease(int key)
|
||||
{
|
||||
uint8_t keymodifier = keyboard1.getModifiers();
|
||||
|
||||
if(keymodifier == 0x40){
|
||||
// ALTGR Key modifier FR Keyboard
|
||||
switch (key) {
|
||||
#ifdef LAYOUT_FRENCH
|
||||
case 233 : key = '~' ; break;
|
||||
case 34 : key = '#' ; break;
|
||||
case 39 : key = '{' ; break;
|
||||
case 40 : key = '[' ; break;
|
||||
case 45 : key = '|' ; break;
|
||||
case 232 : key = '`' ; break;
|
||||
case 95 : key = 92 ; break;
|
||||
case 231 : key = '^' ; break;
|
||||
case 224 : key = '@' ; break;
|
||||
case 41 : key = ']' ; break;
|
||||
case 61 : key = '}' ; break;
|
||||
#endif
|
||||
#ifdef LAYOUT_FRENCH_BELGIAN
|
||||
case 38 : key = '|' ; break; //1
|
||||
case 233 : key = '@' ; break; //2
|
||||
case 34 : key = '#' ; break; //3
|
||||
case 167 : key = '^' ; break; //6
|
||||
case 231 : key = '{' ; break; //9
|
||||
case 224 : key = '}' ; break; //0
|
||||
case 36 : key = ']' ; break; //$
|
||||
case 61 : key = '~' ; break; //=
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (menuActive())
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 217:
|
||||
usbnavpad &= ~MASK_JOY2_DOWN;
|
||||
break;
|
||||
case 218:
|
||||
usbnavpad &= ~MASK_JOY2_UP;
|
||||
break;
|
||||
case 216:
|
||||
usbnavpad &= ~MASK_JOY2_LEFT;
|
||||
break;
|
||||
case 215:
|
||||
usbnavpad &= ~MASK_JOY2_RIGHT;
|
||||
break;
|
||||
case 10:
|
||||
usbnavpad &= ~MASK_JOY2_BTN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emu_KeyboardOnUp(keymodifier, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
#ifdef HAS_USBKEY
|
||||
myusb.begin();
|
||||
keyboard1.attachPress(OnPress);
|
||||
keyboard1.attachRelease(OnRelease);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
strcpy(romspath,SDFSDEV);
|
||||
strcat(romspath,ROMSDIR);
|
||||
|
|
@ -1355,9 +1517,9 @@ void emu_init(void)
|
|||
}
|
||||
#else
|
||||
#ifdef USE_SDFAT
|
||||
if (!SD.begin(SD_CONFIG))
|
||||
while (!SD.begin(SD_CONFIG))
|
||||
#else
|
||||
if (!SD.begin(SD_CS))
|
||||
while (!SD.begin(SD_CS))
|
||||
#endif
|
||||
{
|
||||
Serial.println("SD begin failed, retrying...");
|
||||
|
|
@ -1370,7 +1532,6 @@ void emu_init(void)
|
|||
|
||||
Serial.print("SD initialized, files found: ");
|
||||
Serial.println(nbFiles);
|
||||
|
||||
|
||||
emu_InitJoysticks();
|
||||
#ifdef SWAP_JOYSTICK
|
||||
|
|
@ -1387,7 +1548,11 @@ void emu_init(void)
|
|||
{
|
||||
toggleMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void emu_start(void)
|
||||
{
|
||||
#ifdef HAS_I2CKBD
|
||||
byte msg[7]={0,0,0,0,0,0,0};
|
||||
Wire.begin(); // join i2c bus SDA2/SCL2
|
||||
|
|
@ -1413,5 +1578,9 @@ void emu_init(void)
|
|||
Serial.println("i2C keyboard found");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
usbnavpad = 0;
|
||||
|
||||
keys = key_map1;
|
||||
keyMap = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
#ifndef EMUAPI_H
|
||||
#define EMUAPI_H
|
||||
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_SND 1
|
||||
//#define HAS_I2CKBD 1
|
||||
//#define TIMER_REND 1
|
||||
#include "platform_config.h"
|
||||
|
||||
//#define TIMER_REND 1
|
||||
#define EXTRA_HEAP 0x10
|
||||
|
||||
// Title: < >
|
||||
|
|
@ -52,7 +49,7 @@ const unsigned short keysw[] = {
|
|||
TAREA_NEW_ROW,30,30,30,30,30,30,30,30,30,30,
|
||||
TAREA_END};
|
||||
|
||||
const unsigned short keys[] = {
|
||||
const unsigned short key_map1[] = {
|
||||
30,31,32,33,34,35,36,37,38,39,
|
||||
20,26, 8,21,23,28,25,12,18,19,
|
||||
4, 9, 7,22, 4,11,13,14,15,40,
|
||||
|
|
@ -87,8 +84,10 @@ const unsigned short i2ckeys[] = {
|
|||
#define MASK_KEY_USER4 0x2000
|
||||
|
||||
|
||||
|
||||
extern void emu_init(void);
|
||||
extern void emu_start(void);
|
||||
extern void emu_resetSD(void);
|
||||
|
||||
extern void emu_printf(char * text);
|
||||
extern void emu_printi(int val);
|
||||
extern void * emu_Malloc(int size);
|
||||
|
|
@ -109,8 +108,11 @@ extern void emu_FileTempWrite(int addr, unsigned char val);
|
|||
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_DrawLine8(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_DrawVsync(void);
|
||||
extern int emu_FrameSkip(void);
|
||||
extern void * emu_LineBuffer(int line);
|
||||
|
||||
extern void emu_InitJoysticks(void);
|
||||
extern int emu_SwapJoysticks(int statusOnly);
|
||||
|
|
@ -120,6 +122,9 @@ extern int emu_GetPad(void);
|
|||
extern int emu_ReadAnalogJoyX(int min, int max);
|
||||
extern int emu_ReadAnalogJoyY(int min, int max);
|
||||
extern int emu_ReadI2CKeyboard(void);
|
||||
extern void emu_KeyboardOnUp(int keymodifer, int key);
|
||||
extern void emu_KeyboardOnDown(int keymodifer, int key);
|
||||
|
||||
extern void emu_sndPlaySound(int chan, int volume, int freq);
|
||||
extern void emu_sndPlayBuzz(int size, int val);
|
||||
extern void emu_sndInit();
|
||||
|
|
@ -128,8 +133,9 @@ extern int emu_us(void);
|
|||
|
||||
extern int emu_setKeymap(int index);
|
||||
|
||||
extern void emu_FileTempInit(void);
|
||||
extern void emu_FileTempRead(int addr, unsigned char * val, int n);
|
||||
extern void emu_FileTempWrite(int addr, unsigned char val);
|
||||
extern void emu_printh(int val);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,13 +35,26 @@
|
|||
#define I2C_SDA_IO 18
|
||||
|
||||
// Analog joystick (primary) for JOY2 and 5 extra buttons
|
||||
#ifdef HAS_T4_VGA
|
||||
#define PIN_JOY2_A1X A3
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 14
|
||||
#define PIN_KEY_USER1 22
|
||||
#define PIN_KEY_USER2 23
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 34
|
||||
#define PIN_JOY1_1 38 // UP
|
||||
#define PIN_JOY1_2 36 // DOWN
|
||||
#define PIN_JOY1_3 35 // RIGHT
|
||||
#define PIN_JOY1_4 37 // LEFT
|
||||
|
||||
#else
|
||||
#define PIN_JOY2_A1X A1
|
||||
#define PIN_JOY2_A2Y A2
|
||||
#define PIN_JOY2_BTN 17
|
||||
#define PIN_KEY_USER1 3 //34
|
||||
#define PIN_KEY_USER2 4 //35
|
||||
//#define PIN_KEY_USER3 33
|
||||
//#define PIN_KEY_USER4 39
|
||||
|
||||
// Second joystick
|
||||
#define PIN_JOY1_BTN 2
|
||||
|
|
@ -49,6 +62,7 @@
|
|||
#define PIN_JOY1_2 7 // DOWN
|
||||
#define PIN_JOY1_3 6 // RIGHT
|
||||
#define PIN_JOY1_4 5 // LEFT
|
||||
#endif
|
||||
|
||||
#else
|
||||
// OLD LAYOUT!!!!
|
||||
|
|
@ -87,7 +101,3 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,21 @@
|
|||
#define _PLATFORM_CONFIG_H_
|
||||
|
||||
//#define OLD_LAYOUT 1
|
||||
#define HAS_T4_VGA 1
|
||||
|
||||
#define ILI9341 1
|
||||
//#define HAS_SND 1
|
||||
//#define INVX 1
|
||||
//#define INVY 1
|
||||
#define HAS_USBKEY 1
|
||||
|
||||
//#define ILI9341 1
|
||||
//#define ST7789 1
|
||||
//#define SWAP_JOYSTICK 1
|
||||
//#define LOHRES 1
|
||||
//#define ROTATE_SCREEN 1
|
||||
#define EXTERNAL_SD 1
|
||||
//#define EXTERNAL_SD 1
|
||||
|
||||
#define HAS_PSRAM 1
|
||||
//#define HAS_PSRAM 1
|
||||
|
||||
//#define USE_SDFAT 1
|
||||
//#define SD_FAT_TYPE 1
|
||||
|
|
|
|||
|
|
@ -2,31 +2,39 @@ extern "C" {
|
|||
#include "iopins.h"
|
||||
#include "emuapi.h"
|
||||
}
|
||||
#include "tft_t_dma.h"
|
||||
|
||||
#include "keyboard_osd.h"
|
||||
#include <math.h>
|
||||
#include "mcume.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
|
||||
|
||||
static int xOffLogo=0;
|
||||
static int swipeAngle=0;
|
||||
|
||||
void setup() {
|
||||
//emu_sndInit();
|
||||
#ifdef HAS_T4_VGA
|
||||
tft.begin(VGA_MODE_320x240);
|
||||
// NVIC_SET_PRIORITY(IRQ_QTIMER3, 0);
|
||||
#else
|
||||
tft.begin();
|
||||
//emu_sndPlaySound(0, 255, 4000);
|
||||
emu_init();
|
||||
//delay(5000);
|
||||
//toggleMenu(false);
|
||||
//tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||||
//tft.startDMA();
|
||||
#endif
|
||||
emu_init();
|
||||
}
|
||||
|
||||
static uint8_t col=0x00;
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
|
||||
uint16_t bClick = emu_DebounceLocalKeys();
|
||||
if (menuActive()) {
|
||||
int action = handleMenu(bClick);
|
||||
|
|
@ -62,10 +70,9 @@ void loop(void)
|
|||
#endif
|
||||
if ( (!virtualkeyboardIsActive()) ) {
|
||||
delay(20);
|
||||
//emu_printf("step");
|
||||
xOffLogo = 16*sin((2*3.14*swipeAngle)/256)+30;
|
||||
swipeAngle = (swipeAngle + 4)&0xff;
|
||||
tft.drawSprite(xOffLogo,10,(uint16_t*)logo);
|
||||
swipeAngle = (swipeAngle + 4)&0xff;
|
||||
tft.drawSprite(xOffLogo,10,(uint16_t*)logo);
|
||||
if (bClick & MASK_JOY2_BTN) {
|
||||
tft.stopDMA();
|
||||
emu_init();
|
||||
|
|
@ -75,6 +82,12 @@ void loop(void)
|
|||
}
|
||||
}
|
||||
|
||||
void emu_KeyboardOnDown(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
void emu_KeyboardOnUp(int keymodifer, int key) {
|
||||
}
|
||||
|
||||
#ifdef HAS_SND
|
||||
|
||||
#include <Audio.h>
|
||||
|
|
@ -82,8 +95,15 @@ void loop(void)
|
|||
|
||||
AudioPlaySystem mymixer;
|
||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
|
||||
#ifdef HAS_T4_VGA
|
||||
AudioOutputI2S i2s1;
|
||||
AudioConnection patchCord8(mymixer, 0, i2s1, 0);
|
||||
AudioConnection patchCord9(mymixer, 0, i2s1, 1);
|
||||
AudioControlSGTL5000 sgtl5000_1;
|
||||
#else
|
||||
AudioOutputMQS mqs;
|
||||
AudioConnection patchCord9(mymixer, 0, mqs, 1);
|
||||
#endif
|
||||
#else
|
||||
AudioOutputAnalog dac1;
|
||||
AudioConnection patchCord1(mymixer, dac1);
|
||||
|
|
@ -91,6 +111,10 @@ AudioConnection patchCord1(mymixer, dac1);
|
|||
|
||||
void emu_sndInit() {
|
||||
Serial.println("sound init");
|
||||
#ifdef HAS_T4_VGA
|
||||
sgtl5000_1.enable();
|
||||
sgtl5000_1.volume(0.6);
|
||||
#endif
|
||||
AudioMemory(16);
|
||||
mymixer.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
|
||||
#include "TFT_T_DMA.h"
|
||||
|
||||
#ifndef HAS_T4_VGA
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
|
||||
|
|
@ -1231,7 +1234,7 @@ void TFT_T_DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_
|
|||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
53
MCUME_teensy/teensylogo/vga_t_dma.h
Normal file
53
MCUME_teensy/teensylogo/vga_t_dma.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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
|
||||
BIN
MCUME_teensy/teensymsx/.DS_Store
vendored
BIN
MCUME_teensy/teensymsx/.DS_Store
vendored
Binary file not shown.
|
|
@ -1,317 +1,320 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** AY8910.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the AY8910 sound chip **/
|
||||
/** produced by General Instruments, Yamaha, etc. See **/
|
||||
/** AY8910.h for declarations. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-2003 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#include "AY8910.h"
|
||||
#include "Sound.h"
|
||||
#include <string.h>
|
||||
|
||||
/** Reset8910() **********************************************/
|
||||
/** Reset the sound chip and use sound channels from the **/
|
||||
/** one given in First. **/
|
||||
/*************************************************************/
|
||||
void Reset8910(register AY8910 *D,int First)
|
||||
{
|
||||
static byte RegInit[16] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFD,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00
|
||||
};
|
||||
int J;
|
||||
|
||||
for(J=0;J<AY8910_CHANNELS;J++) D->Freq[J]=D->Volume[J]=0;
|
||||
memcpy(D->R,RegInit,sizeof(D->R));
|
||||
D->Phase[0]=D->Phase[1]=D->Phase[2]=0;
|
||||
D->First = First;
|
||||
D->Sync = AY8910_ASYNC;
|
||||
D->Changed = 0x00;
|
||||
D->EPeriod = 0;
|
||||
D->ECount = 0;
|
||||
D->Latch = 0x00;
|
||||
|
||||
/* Set sound types */
|
||||
SetSound(0+First,SND_MELODIC);
|
||||
SetSound(1+First,SND_MELODIC);
|
||||
SetSound(2+First,SND_MELODIC);
|
||||
SetSound(3+First,SND_NOISE);
|
||||
SetSound(4+First,SND_NOISE);
|
||||
SetSound(5+First,SND_NOISE);
|
||||
}
|
||||
|
||||
/** WrCtrl8910() *********************************************/
|
||||
/** Write a value V to the PSG Control Port. **/
|
||||
/*************************************************************/
|
||||
void WrCtrl8910(AY8910 *D,byte V)
|
||||
{
|
||||
D->Latch=V&0x0F;
|
||||
}
|
||||
|
||||
/** WrData8910() *********************************************/
|
||||
/** Write a value V to the PSG Data Port. **/
|
||||
/*************************************************************/
|
||||
void WrData8910(AY8910 *D,byte V)
|
||||
{
|
||||
Write8910(D,D->Latch,V);
|
||||
}
|
||||
|
||||
/** RdData8910() *********************************************/
|
||||
/** Read a value from the PSG Data Port. **/
|
||||
/*************************************************************/
|
||||
byte RdData8910(AY8910 *D)
|
||||
{
|
||||
return(D->R[D->Latch]);
|
||||
}
|
||||
|
||||
/** Write8910() **********************************************/
|
||||
/** Call this function to output a value V into the sound **/
|
||||
/** chip. **/
|
||||
/*************************************************************/
|
||||
void Write8910(register AY8910 *D,register byte R,register byte V)
|
||||
{
|
||||
register int J,I;
|
||||
|
||||
/* Exit if no change */
|
||||
if((R>15)||((V==D->R[R])&&(R<8)&&(R>10))) return;
|
||||
|
||||
switch(R)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
/* Write value */
|
||||
D->R[R]=V;
|
||||
/* Exit if the channel is silenced */
|
||||
if(D->R[7]&(1<<(R>>1))) return;
|
||||
/* Go to the first register in the pair */
|
||||
R&=0xFE;
|
||||
/* Compute frequency */
|
||||
J=((int)(D->R[R+1]&0x0F)<<8)+D->R[R];
|
||||
/* Compute channel number */
|
||||
R>>=1;
|
||||
/* Assign frequency */
|
||||
D->Freq[R]=AY8910_BASE/(J+1);
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=1<<R;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/* Write value */
|
||||
D->R[6]=V;
|
||||
/* Exit if noise channels are silenced */
|
||||
if(!(~D->R[7]&0x38)) return;
|
||||
/* Compute and assign noise frequency */
|
||||
J=AY8910_BASE/((V&0x1F)+1);
|
||||
if(!(D->R[7]&0x08)) D->Freq[3]=J;
|
||||
if(!(D->R[7]&0x10)) D->Freq[4]=J;
|
||||
if(!(D->R[7]&0x20)) D->Freq[5]=J;
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=0x38&~D->R[7];
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/* Find changed channels */
|
||||
R=(V^D->R[7])&0x3F;
|
||||
D->Changed|=R;
|
||||
/* Write value */
|
||||
D->R[7]=V;
|
||||
/* Update frequencies */
|
||||
for(J=0;R&&(J<AY8910_CHANNELS);J++,R>>=1,V>>=1)
|
||||
if(R&1)
|
||||
{
|
||||
if(V&1) D->Freq[J]=0;
|
||||
else
|
||||
{
|
||||
I=J<3? (((int)(D->R[J*2+1]&0x0F)<<8)+D->R[J*2]):(D->R[6]&0x1F);
|
||||
D->Freq[J]=AY8910_BASE/(I+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
/* Write value */
|
||||
D->R[R]=V;
|
||||
/* Compute channel number */
|
||||
R-=8;
|
||||
/* Compute and assign new volume */
|
||||
D->Volume[R+3]=D->Volume[R]=255*(V&0x0F)/15;
|
||||
/* Start/stop envelope */
|
||||
D->Phase[R]=V&0x10? 1:0;
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=(0x09<<R)&~D->R[7];
|
||||
break;
|
||||
|
||||
case 11:
|
||||
case 12:
|
||||
/* Write value */
|
||||
D->R[R]=V;
|
||||
/* Compute frequency */
|
||||
J=((int)D->R[12]<<8)+D->R[11];
|
||||
D->EPeriod=1000*J/AY8910_BASE/16;
|
||||
D->ECount=0;
|
||||
/* No channels changed */
|
||||
return;
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
/* Write value */
|
||||
D->R[R]=V;
|
||||
/* No channels changed */
|
||||
return;
|
||||
|
||||
default:
|
||||
/* Wrong register, do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* For asynchronous mode, make Sound() calls right away */
|
||||
if(!D->Sync&&D->Changed) Sync8910(D,AY8910_FLUSH);
|
||||
}
|
||||
|
||||
/** Loop8910() ***********************************************/
|
||||
/** Call this function periodically to update volume **/
|
||||
/** envelopes. Use mS to pass the time since the last call **/
|
||||
/** of Loop8910() in milliseconds. **/
|
||||
/*************************************************************/
|
||||
void Loop8910(register AY8910 *D,int mS)
|
||||
{
|
||||
register int J,I,Step;
|
||||
|
||||
/* Exit if no envelope running */
|
||||
if(!D->EPeriod) return;
|
||||
|
||||
/* Count milliseconds */
|
||||
D->ECount+=mS;
|
||||
if(D->ECount<D->EPeriod) return;
|
||||
D->ECount-=D->EPeriod;
|
||||
|
||||
/* By how much do we change volume? */
|
||||
Step=mS>=D->EPeriod? mS/D->EPeriod:1;
|
||||
|
||||
for(J=0;J<3;J++)
|
||||
if(D->Phase[J]&&(D->R[J+8]&0x10))
|
||||
switch(D->R[13]&0x0F)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 9:
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I>=0? I:0;
|
||||
if(!I) D->Phase[J]=0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I<256? I:0;
|
||||
if(!I) D->Phase[J]=0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 8:
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I>=0? I:255;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 10:
|
||||
if(D->Phase[J]==2)
|
||||
{
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I<256? I:255;
|
||||
if(I==255) D->Phase[J]=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I>=0? I:0;
|
||||
if(!I) D->Phase[J]=2;
|
||||
}
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 11:
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I>=0? I:255;
|
||||
if(I==255) D->Phase[J]=0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 12:
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I<256? I:0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 13:
|
||||
case 15:
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I<256? I:255;
|
||||
if(I==255) D->Phase[J]=0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 14:
|
||||
if(D->Phase[J]==2)
|
||||
{
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I>=0? I:0;
|
||||
if(!I) D->Phase[J]=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I<256? I:255;
|
||||
if(I==255) D->Phase[J]=2;
|
||||
}
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
}
|
||||
|
||||
/* For asynchronous mode, make Sound() calls right away */
|
||||
if(!D->Sync&&D->Changed) Sync8910(D,AY8910_FLUSH);
|
||||
}
|
||||
|
||||
/** Sync8910() ***********************************************/
|
||||
/** Flush all accumulated changes by issuing Sound() calls **/
|
||||
/** and set the synchronization on/off. The second argument **/
|
||||
/** should be AY8910_SYNC/AY8910_ASYNC to set/reset sync, **/
|
||||
/** or AY8910_FLUSH to leave sync mode as it is. To emulate **/
|
||||
/** noise channels with MIDI drums, OR second argument with **/
|
||||
/** AY8910_DRUMS. **/
|
||||
/*************************************************************/
|
||||
void Sync8910(register AY8910 *D,register byte Sync)
|
||||
{
|
||||
register int J,I;
|
||||
|
||||
/* Hit MIDI drums for noise channels, if requested */
|
||||
if(Sync&AY8910_DRUMS)
|
||||
{
|
||||
Sync&=~AY8910_DRUMS;
|
||||
J=0;
|
||||
if(D->Volume[3]&&D->Freq[3]) J+=D->Volume[3];
|
||||
if(D->Volume[4]&&D->Freq[4]) J+=D->Volume[4];
|
||||
if(D->Volume[5]&&D->Freq[5]) J+=D->Volume[5];
|
||||
if(J) Drum(DRM_MIDI|28,(J+2)/3);
|
||||
}
|
||||
|
||||
if(Sync!=AY8910_FLUSH) D->Sync=Sync;
|
||||
|
||||
for(J=0,I=D->Changed;I&&(J<AY8910_CHANNELS);J++,I>>=1)
|
||||
if(I&1) Sound(J+D->First,D->Freq[J],D->Volume[J]);
|
||||
|
||||
D->Changed=0x00;
|
||||
}
|
||||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** AY8910.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the AY8910 sound chip **/
|
||||
/** produced by General Instruments, Yamaha, etc. See **/
|
||||
/** AY8910.h for declarations. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#include "AY8910.h"
|
||||
#include "Sound.h"
|
||||
#include <string.h>
|
||||
|
||||
/** Reset8910() **********************************************/
|
||||
/** Reset the sound chip and use sound channels from the **/
|
||||
/** one given in First. **/
|
||||
/*************************************************************/
|
||||
void Reset8910(register AY8910 *D,int First)
|
||||
{
|
||||
static byte RegInit[16] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFD,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00
|
||||
};
|
||||
int J;
|
||||
|
||||
for(J=0;J<AY8910_CHANNELS;J++) D->Freq[J]=D->Volume[J]=0;
|
||||
memcpy(D->R,RegInit,sizeof(D->R));
|
||||
D->Phase[0]=D->Phase[1]=D->Phase[2]=0;
|
||||
D->First = First;
|
||||
D->Sync = AY8910_ASYNC;
|
||||
D->Changed = 0x00;
|
||||
D->EPeriod = 0;
|
||||
D->ECount = 0;
|
||||
D->Latch = 0x00;
|
||||
|
||||
/* Set sound types */
|
||||
SetSound(0+First,SND_MELODIC);
|
||||
SetSound(1+First,SND_MELODIC);
|
||||
SetSound(2+First,SND_MELODIC);
|
||||
SetSound(3+First,SND_NOISE);
|
||||
SetSound(4+First,SND_NOISE);
|
||||
SetSound(5+First,SND_NOISE);
|
||||
}
|
||||
|
||||
/** WrCtrl8910() *********************************************/
|
||||
/** Write a value V to the PSG Control Port. **/
|
||||
/*************************************************************/
|
||||
void WrCtrl8910(AY8910 *D,byte V)
|
||||
{
|
||||
D->Latch=V&0x0F;
|
||||
}
|
||||
|
||||
/** WrData8910() *********************************************/
|
||||
/** Write a value V to the PSG Data Port. **/
|
||||
/*************************************************************/
|
||||
void WrData8910(AY8910 *D,byte V)
|
||||
{
|
||||
Write8910(D,D->Latch,V);
|
||||
}
|
||||
|
||||
/** RdData8910() *********************************************/
|
||||
/** Read a value from the PSG Data Port. **/
|
||||
/*************************************************************/
|
||||
byte RdData8910(AY8910 *D)
|
||||
{
|
||||
return(D->R[D->Latch]);
|
||||
}
|
||||
|
||||
/** Write8910() **********************************************/
|
||||
/** Call this function to output a value V into the sound **/
|
||||
/** chip. **/
|
||||
/*************************************************************/
|
||||
void Write8910(register AY8910 *D,register byte R,register byte V)
|
||||
{
|
||||
register int J,I;
|
||||
|
||||
/* Exit if no change */
|
||||
if((R>15)||((V==D->R[R])&&(R<8)&&(R>10))) return;
|
||||
|
||||
switch(R)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
/* Write value */
|
||||
D->R[R]=V;
|
||||
/* Exit if the channel is silenced */
|
||||
if(D->R[7]&(1<<(R>>1))) return;
|
||||
/* Go to the first register in the pair */
|
||||
R&=0xFE;
|
||||
/* Compute frequency */
|
||||
J=((int)(D->R[R+1]&0x0F)<<8)+D->R[R];
|
||||
/* Compute channel number */
|
||||
R>>=1;
|
||||
/* Assign frequency */
|
||||
D->Freq[R]=AY8910_BASE/(J+1);
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=1<<R;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/* Write value */
|
||||
D->R[6]=V;
|
||||
/* Exit if noise channels are silenced */
|
||||
if(!(~D->R[7]&0x38)) return;
|
||||
/* Compute and assign noise frequency */
|
||||
J=AY8910_BASE/((V&0x1F)+1);
|
||||
if(!(D->R[7]&0x08)) D->Freq[3]=J;
|
||||
if(!(D->R[7]&0x10)) D->Freq[4]=J;
|
||||
if(!(D->R[7]&0x20)) D->Freq[5]=J;
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=0x38&~D->R[7];
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/* Find changed channels */
|
||||
R=(V^D->R[7])&0x3F;
|
||||
D->Changed|=R;
|
||||
/* Write value */
|
||||
D->R[7]=V;
|
||||
/* Update frequencies */
|
||||
for(J=0;R&&(J<AY8910_CHANNELS);J++,R>>=1,V>>=1)
|
||||
if(R&1)
|
||||
{
|
||||
if(V&1) D->Freq[J]=0;
|
||||
else
|
||||
{
|
||||
I=J<3? (((int)(D->R[J*2+1]&0x0F)<<8)+D->R[J*2]):(D->R[6]&0x1F);
|
||||
D->Freq[J]=AY8910_BASE/(I+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
/* Write value */
|
||||
D->R[R]=V;
|
||||
/* Compute channel number */
|
||||
R-=8;
|
||||
/* Compute and assign new volume */
|
||||
D->Volume[R+3]=D->Volume[R]=
|
||||
V&0x10? (V&0x04? 0:255):255*(V&0x0F)/15;
|
||||
/* Start/stop envelope */
|
||||
D->Phase[R]=V&0x10? 1:0;
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=(0x09<<R)&~D->R[7];
|
||||
break;
|
||||
|
||||
case 11:
|
||||
case 12:
|
||||
/* Write value */
|
||||
D->R[R]=V;
|
||||
/* Compute frequency */
|
||||
J=((int)D->R[12]<<8)+D->R[11]+1;
|
||||
D->EPeriod=1000*(J<<4)/AY8910_BASE;
|
||||
D->ECount=0;
|
||||
/* No channels changed */
|
||||
return;
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
/* Write value */
|
||||
D->R[R]=V;
|
||||
/* No channels changed */
|
||||
return;
|
||||
|
||||
default:
|
||||
/* Wrong register, do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* For asynchronous mode, make Sound() calls right away */
|
||||
if(!D->Sync&&D->Changed) Sync8910(D,AY8910_FLUSH);
|
||||
}
|
||||
|
||||
/** Loop8910() ***********************************************/
|
||||
/** Call this function periodically to update volume **/
|
||||
/** envelopes. Use mS to pass the time since the last call **/
|
||||
/** of Loop8910() in milliseconds. **/
|
||||
/*************************************************************/
|
||||
void Loop8910(register AY8910 *D,int mS)
|
||||
{
|
||||
register int J,I,Step;
|
||||
|
||||
/* Exit if no envelope running */
|
||||
if(!D->EPeriod) return;
|
||||
|
||||
/* Count milliseconds */
|
||||
D->ECount+=mS;
|
||||
if(D->ECount<D->EPeriod) return;
|
||||
|
||||
/* By how much do we change volume? */
|
||||
Step=(D->ECount<<8)/D->EPeriod;
|
||||
|
||||
/* Count the remaining milliseconds */
|
||||
D->ECount%=D->EPeriod;
|
||||
|
||||
for(J=0;J<3;J++)
|
||||
if(D->Phase[J]&&(D->R[J+8]&0x10))
|
||||
switch(D->R[13]&0x0F)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 9:
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I>=0? I:0;
|
||||
if(!I) D->Phase[J]=0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I<256? I:0;
|
||||
if(!I) D->Phase[J]=0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 8:
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I>=0? I:255;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 10:
|
||||
if(D->Phase[J]==2)
|
||||
{
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I<256? I:255;
|
||||
if(I==255) D->Phase[J]=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I>=0? I:0;
|
||||
if(!I) D->Phase[J]=2;
|
||||
}
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 11:
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I>=0? I:255;
|
||||
if(I==255) D->Phase[J]=0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 12:
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I<256? I:0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 13:
|
||||
case 15:
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I<256? I:255;
|
||||
if(I==255) D->Phase[J]=0;
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
case 14:
|
||||
if(D->Phase[J]==2)
|
||||
{
|
||||
I=D->Volume[J]-Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I>=0? I:0;
|
||||
if(!I) D->Phase[J]=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
I=D->Volume[J]+Step;
|
||||
D->Volume[J+3]=D->Volume[J]=I=I<256? I:255;
|
||||
if(I==255) D->Phase[J]=2;
|
||||
}
|
||||
D->Changed|=(0x09<<J)&~D->R[7];
|
||||
break;
|
||||
}
|
||||
|
||||
/* For asynchronous mode, make Sound() calls right away */
|
||||
if(!D->Sync&&D->Changed) Sync8910(D,AY8910_FLUSH);
|
||||
}
|
||||
|
||||
/** Sync8910() ***********************************************/
|
||||
/** Flush all accumulated changes by issuing Sound() calls **/
|
||||
/** and set the synchronization on/off. The second argument **/
|
||||
/** should be AY8910_SYNC/AY8910_ASYNC to set/reset sync, **/
|
||||
/** or AY8910_FLUSH to leave sync mode as it is. To emulate **/
|
||||
/** noise channels with MIDI drums, OR second argument with **/
|
||||
/** AY8910_DRUMS. **/
|
||||
/*************************************************************/
|
||||
void Sync8910(register AY8910 *D,register byte Sync)
|
||||
{
|
||||
register int J,I;
|
||||
|
||||
/* Hit MIDI drums for noise channels, if requested */
|
||||
if(Sync&AY8910_DRUMS)
|
||||
{
|
||||
Sync&=~AY8910_DRUMS;
|
||||
J=0;
|
||||
if(D->Volume[3]&&D->Freq[3]) J+=D->Volume[3];
|
||||
if(D->Volume[4]&&D->Freq[4]) J+=D->Volume[4];
|
||||
if(D->Volume[5]&&D->Freq[5]) J+=D->Volume[5];
|
||||
if(J) Drum(DRM_MIDI|28,(J+2)/3);
|
||||
}
|
||||
|
||||
if(Sync!=AY8910_FLUSH) D->Sync=Sync;
|
||||
|
||||
for(J=0,I=D->Changed;I&&(J<AY8910_CHANNELS);J++,I>>=1)
|
||||
if(I&1) Sound(J+D->First,D->Freq[J],D->Volume[J]);
|
||||
|
||||
D->Changed=0x00;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,91 +1,91 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** AY8910.h **/
|
||||
/** **/
|
||||
/** This file contains emulation for the AY8910 sound chip **/
|
||||
/** produced by General Instruments, Yamaha, etc. See **/
|
||||
/** AY8910.c for the actual code. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-2003 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#ifndef AY8910_H
|
||||
#define AY8910_H
|
||||
|
||||
#define AY8910_BASE 111861 /* Base frequency for AY8910 */
|
||||
#define AY8910_CHANNELS 6 /* 3 melodic + 3 noise chanls */
|
||||
|
||||
#define AY8910_ASYNC 0 /* Asynchronous emulation */
|
||||
#define AY8910_SYNC 1 /* Synchronous emulation */
|
||||
#define AY8910_FLUSH 2 /* Flush buffers only */
|
||||
#define AY8910_DRUMS 0x80 /* Hit drums for noise chnls */
|
||||
|
||||
#ifndef BYTE_TYPE_DEFINED
|
||||
#define BYTE_TYPE_DEFINED
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
/** AY8910 ***************************************************/
|
||||
/** This data structure stores AY8910 state. **/
|
||||
/*************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
byte R[16]; /* PSG registers contents */
|
||||
int Freq[AY8910_CHANNELS]; /* Frequencies (0 for off) */
|
||||
int Volume[AY8910_CHANNELS]; /* Volumes (0..255) */
|
||||
int First; /* First used Sound() channel */
|
||||
byte Changed; /* Bitmap of changed channels */
|
||||
byte Sync; /* AY8910_SYNC/AY8910_ASYNC */
|
||||
byte Latch; /* Latch for the register num */
|
||||
int EPeriod; /* Envelope step in msecs */
|
||||
int ECount; /* Envelope step counter */
|
||||
byte Phase[3]; /* Envelope phase (0 for off) */
|
||||
} AY8910;
|
||||
|
||||
/** Reset8910() **********************************************/
|
||||
/** Reset the sound chip and use sound channels from the **/
|
||||
/** one given in First. **/
|
||||
/*************************************************************/
|
||||
void Reset8910(register AY8910 *D,int First);
|
||||
|
||||
/** Write8910() **********************************************/
|
||||
/** Call this function to output a value V into the sound **/
|
||||
/** chip. **/
|
||||
/*************************************************************/
|
||||
void Write8910(register AY8910 *D,register byte R,register byte V);
|
||||
|
||||
/** WrCtrl8910() *********************************************/
|
||||
/** Write a value V to the PSG Control Port. **/
|
||||
/*************************************************************/
|
||||
void WrCtrl8910(AY8910 *D,byte V);
|
||||
|
||||
/** WrData8910() *********************************************/
|
||||
/** Write a value V to the PSG Data Port. **/
|
||||
/*************************************************************/
|
||||
void WrData8910(AY8910 *D,byte V);
|
||||
|
||||
/** RdData8910() *********************************************/
|
||||
/** Read a value from the PSG Data Port. **/
|
||||
/*************************************************************/
|
||||
byte RdData8910(AY8910 *D);
|
||||
|
||||
/** Sync8910() ***********************************************/
|
||||
/** Flush all accumulated changes by issuing Sound() calls **/
|
||||
/** and set the synchronization on/off. The second argument **/
|
||||
/** should be AY8910_SYNC/AY8910_ASYNC to set/reset sync, **/
|
||||
/** or AY8910_FLUSH to leave sync mode as it is. To emulate **/
|
||||
/** noise channels with MIDI drums, OR second argument with **/
|
||||
/** AY8910_DRUMS. **/
|
||||
/*************************************************************/
|
||||
void Sync8910(register AY8910 *D,register byte Sync);
|
||||
|
||||
/** Loop8910() ***********************************************/
|
||||
/** Call this function periodically to update volume **/
|
||||
/** envelopes. Use mS to pass the time since the last call **/
|
||||
/** of Loop8910() in milliseconds. **/
|
||||
/*************************************************************/
|
||||
void Loop8910(register AY8910 *D,int mS);
|
||||
|
||||
#endif /* AY8910_H */
|
||||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** AY8910.h **/
|
||||
/** **/
|
||||
/** This file contains emulation for the AY8910 sound chip **/
|
||||
/** produced by General Instruments, Yamaha, etc. See **/
|
||||
/** AY8910.c for the actual code. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#ifndef AY8910_H
|
||||
#define AY8910_H
|
||||
|
||||
#define AY8910_BASE 111861 /* Base frequency for AY8910 */
|
||||
#define AY8910_CHANNELS 6 /* 3 melodic + 3 noise chanls */
|
||||
|
||||
#define AY8910_ASYNC 0 /* Asynchronous emulation */
|
||||
#define AY8910_SYNC 1 /* Synchronous emulation */
|
||||
#define AY8910_FLUSH 2 /* Flush buffers only */
|
||||
#define AY8910_DRUMS 0x80 /* Hit drums for noise chnls */
|
||||
|
||||
#ifndef BYTE_TYPE_DEFINED
|
||||
#define BYTE_TYPE_DEFINED
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
/** AY8910 ***************************************************/
|
||||
/** This data structure stores AY8910 state. **/
|
||||
/*************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
byte R[16]; /* PSG registers contents */
|
||||
int Freq[AY8910_CHANNELS]; /* Frequencies (0 for off) */
|
||||
int Volume[AY8910_CHANNELS]; /* Volumes (0..255) */
|
||||
int First; /* First used Sound() channel */
|
||||
byte Changed; /* Bitmap of changed channels */
|
||||
byte Sync; /* AY8910_SYNC/AY8910_ASYNC */
|
||||
byte Latch; /* Latch for the register num */
|
||||
int EPeriod; /* Envelope step in msecs */
|
||||
int ECount; /* Envelope step counter */
|
||||
byte Phase[3]; /* Envelope phase (0 for off) */
|
||||
} AY8910;
|
||||
|
||||
/** Reset8910() **********************************************/
|
||||
/** Reset the sound chip and use sound channels from the **/
|
||||
/** one given in First. **/
|
||||
/*************************************************************/
|
||||
void Reset8910(register AY8910 *D,int First);
|
||||
|
||||
/** Write8910() **********************************************/
|
||||
/** Call this function to output a value V into the sound **/
|
||||
/** chip. **/
|
||||
/*************************************************************/
|
||||
void Write8910(register AY8910 *D,register byte R,register byte V);
|
||||
|
||||
/** WrCtrl8910() *********************************************/
|
||||
/** Write a value V to the PSG Control Port. **/
|
||||
/*************************************************************/
|
||||
void WrCtrl8910(AY8910 *D,byte V);
|
||||
|
||||
/** WrData8910() *********************************************/
|
||||
/** Write a value V to the PSG Data Port. **/
|
||||
/*************************************************************/
|
||||
void WrData8910(AY8910 *D,byte V);
|
||||
|
||||
/** RdData8910() *********************************************/
|
||||
/** Read a value from the PSG Data Port. **/
|
||||
/*************************************************************/
|
||||
byte RdData8910(AY8910 *D);
|
||||
|
||||
/** Sync8910() ***********************************************/
|
||||
/** Flush all accumulated changes by issuing Sound() calls **/
|
||||
/** and set the synchronization on/off. The second argument **/
|
||||
/** should be AY8910_SYNC/AY8910_ASYNC to set/reset sync, **/
|
||||
/** or AY8910_FLUSH to leave sync mode as it is. To emulate **/
|
||||
/** noise channels with MIDI drums, OR second argument with **/
|
||||
/** AY8910_DRUMS. **/
|
||||
/*************************************************************/
|
||||
void Sync8910(register AY8910 *D,register byte Sync);
|
||||
|
||||
/** Loop8910() ***********************************************/
|
||||
/** Call this function periodically to update volume **/
|
||||
/** envelopes. Use mS to pass the time since the last call **/
|
||||
/** of Loop8910() in milliseconds. **/
|
||||
/*************************************************************/
|
||||
void Loop8910(register AY8910 *D,int mS);
|
||||
|
||||
#endif /* AY8910_H */
|
||||
|
|
|
|||
|
|
@ -1,378 +1,385 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** Codes.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the main table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case JR_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||
case JR_NC: if(R->AF.B.l&C_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||
case JR_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||
case JR_C: if(R->AF.B.l&C_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||
|
||||
case JP_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_Z: if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_C: if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_PE: if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_M: if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
|
||||
case RET_NZ: if(!(R->AF.B.l&Z_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_NC: if(!(R->AF.B.l&C_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_PO: if(!(R->AF.B.l&P_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_P: if(!(R->AF.B.l&S_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_C: if(R->AF.B.l&C_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_M: if(R->AF.B.l&S_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
|
||||
case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_C: if(R->AF.B.l&C_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_M: if(R->AF.B.l&S_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
|
||||
case ADD_B: M_ADD(R->BC.B.h);break;
|
||||
case ADD_C: M_ADD(R->BC.B.l);break;
|
||||
case ADD_D: M_ADD(R->DE.B.h);break;
|
||||
case ADD_E: M_ADD(R->DE.B.l);break;
|
||||
case ADD_H: M_ADD(R->HL.B.h);break;
|
||||
case ADD_L: M_ADD(R->HL.B.l);break;
|
||||
case ADD_A: M_ADD(R->AF.B.h);break;
|
||||
case ADD_xHL: I=RdZ80(R->HL.W);M_ADD(I);break;
|
||||
case ADD_BYTE: I=RdZ80(R->PC.W++);M_ADD(I);break;
|
||||
|
||||
case SUB_B: M_SUB(R->BC.B.h);break;
|
||||
case SUB_C: M_SUB(R->BC.B.l);break;
|
||||
case SUB_D: M_SUB(R->DE.B.h);break;
|
||||
case SUB_E: M_SUB(R->DE.B.l);break;
|
||||
case SUB_H: M_SUB(R->HL.B.h);break;
|
||||
case SUB_L: M_SUB(R->HL.B.l);break;
|
||||
case SUB_A: R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case SUB_xHL: I=RdZ80(R->HL.W);M_SUB(I);break;
|
||||
case SUB_BYTE: I=RdZ80(R->PC.W++);M_SUB(I);break;
|
||||
|
||||
case AND_B: M_AND(R->BC.B.h);break;
|
||||
case AND_C: M_AND(R->BC.B.l);break;
|
||||
case AND_D: M_AND(R->DE.B.h);break;
|
||||
case AND_E: M_AND(R->DE.B.l);break;
|
||||
case AND_H: M_AND(R->HL.B.h);break;
|
||||
case AND_L: M_AND(R->HL.B.l);break;
|
||||
case AND_A: M_AND(R->AF.B.h);break;
|
||||
case AND_xHL: I=RdZ80(R->HL.W);M_AND(I);break;
|
||||
case AND_BYTE: I=RdZ80(R->PC.W++);M_AND(I);break;
|
||||
|
||||
case OR_B: M_OR(R->BC.B.h);break;
|
||||
case OR_C: M_OR(R->BC.B.l);break;
|
||||
case OR_D: M_OR(R->DE.B.h);break;
|
||||
case OR_E: M_OR(R->DE.B.l);break;
|
||||
case OR_H: M_OR(R->HL.B.h);break;
|
||||
case OR_L: M_OR(R->HL.B.l);break;
|
||||
case OR_A: M_OR(R->AF.B.h);break;
|
||||
case OR_xHL: I=RdZ80(R->HL.W);M_OR(I);break;
|
||||
case OR_BYTE: I=RdZ80(R->PC.W++);M_OR(I);break;
|
||||
|
||||
case ADC_B: M_ADC(R->BC.B.h);break;
|
||||
case ADC_C: M_ADC(R->BC.B.l);break;
|
||||
case ADC_D: M_ADC(R->DE.B.h);break;
|
||||
case ADC_E: M_ADC(R->DE.B.l);break;
|
||||
case ADC_H: M_ADC(R->HL.B.h);break;
|
||||
case ADC_L: M_ADC(R->HL.B.l);break;
|
||||
case ADC_A: M_ADC(R->AF.B.h);break;
|
||||
case ADC_xHL: I=RdZ80(R->HL.W);M_ADC(I);break;
|
||||
case ADC_BYTE: I=RdZ80(R->PC.W++);M_ADC(I);break;
|
||||
|
||||
case SBC_B: M_SBC(R->BC.B.h);break;
|
||||
case SBC_C: M_SBC(R->BC.B.l);break;
|
||||
case SBC_D: M_SBC(R->DE.B.h);break;
|
||||
case SBC_E: M_SBC(R->DE.B.l);break;
|
||||
case SBC_H: M_SBC(R->HL.B.h);break;
|
||||
case SBC_L: M_SBC(R->HL.B.l);break;
|
||||
case SBC_A: M_SBC(R->AF.B.h);break;
|
||||
case SBC_xHL: I=RdZ80(R->HL.W);M_SBC(I);break;
|
||||
case SBC_BYTE: I=RdZ80(R->PC.W++);M_SBC(I);break;
|
||||
|
||||
case XOR_B: M_XOR(R->BC.B.h);break;
|
||||
case XOR_C: M_XOR(R->BC.B.l);break;
|
||||
case XOR_D: M_XOR(R->DE.B.h);break;
|
||||
case XOR_E: M_XOR(R->DE.B.l);break;
|
||||
case XOR_H: M_XOR(R->HL.B.h);break;
|
||||
case XOR_L: M_XOR(R->HL.B.l);break;
|
||||
case XOR_A: R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
|
||||
case XOR_xHL: I=RdZ80(R->HL.W);M_XOR(I);break;
|
||||
case XOR_BYTE: I=RdZ80(R->PC.W++);M_XOR(I);break;
|
||||
|
||||
case CP_B: M_CP(R->BC.B.h);break;
|
||||
case CP_C: M_CP(R->BC.B.l);break;
|
||||
case CP_D: M_CP(R->DE.B.h);break;
|
||||
case CP_E: M_CP(R->DE.B.l);break;
|
||||
case CP_H: M_CP(R->HL.B.h);break;
|
||||
case CP_L: M_CP(R->HL.B.l);break;
|
||||
case CP_A: R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case CP_xHL: I=RdZ80(R->HL.W);M_CP(I);break;
|
||||
case CP_BYTE: I=RdZ80(R->PC.W++);M_CP(I);break;
|
||||
|
||||
case LD_BC_WORD: M_LDWORD(BC);break;
|
||||
case LD_DE_WORD: M_LDWORD(DE);break;
|
||||
case LD_HL_WORD: M_LDWORD(HL);break;
|
||||
case LD_SP_WORD: M_LDWORD(SP);break;
|
||||
|
||||
case LD_PC_HL: R->PC.W=R->HL.W;break;
|
||||
case LD_SP_HL: R->SP.W=R->HL.W;break;
|
||||
case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
|
||||
case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
|
||||
|
||||
case ADD_HL_BC: M_ADDW(HL,BC);break;
|
||||
case ADD_HL_DE: M_ADDW(HL,DE);break;
|
||||
case ADD_HL_HL: M_ADDW(HL,HL);break;
|
||||
case ADD_HL_SP: M_ADDW(HL,SP);break;
|
||||
|
||||
case DEC_BC: R->BC.W--;break;
|
||||
case DEC_DE: R->DE.W--;break;
|
||||
case DEC_HL: R->HL.W--;break;
|
||||
case DEC_SP: R->SP.W--;break;
|
||||
|
||||
case INC_BC: R->BC.W++;break;
|
||||
case INC_DE: R->DE.W++;break;
|
||||
case INC_HL: R->HL.W++;break;
|
||||
case INC_SP: R->SP.W++;break;
|
||||
|
||||
case DEC_B: M_DEC(R->BC.B.h);break;
|
||||
case DEC_C: M_DEC(R->BC.B.l);break;
|
||||
case DEC_D: M_DEC(R->DE.B.h);break;
|
||||
case DEC_E: M_DEC(R->DE.B.l);break;
|
||||
case DEC_H: M_DEC(R->HL.B.h);break;
|
||||
case DEC_L: M_DEC(R->HL.B.l);break;
|
||||
case DEC_A: M_DEC(R->AF.B.h);break;
|
||||
case DEC_xHL: I=RdZ80(R->HL.W);M_DEC(I);WrZ80(R->HL.W,I);break;
|
||||
|
||||
case INC_B: M_INC(R->BC.B.h);break;
|
||||
case INC_C: M_INC(R->BC.B.l);break;
|
||||
case INC_D: M_INC(R->DE.B.h);break;
|
||||
case INC_E: M_INC(R->DE.B.l);break;
|
||||
case INC_H: M_INC(R->HL.B.h);break;
|
||||
case INC_L: M_INC(R->HL.B.l);break;
|
||||
case INC_A: M_INC(R->AF.B.h);break;
|
||||
case INC_xHL: I=RdZ80(R->HL.W);M_INC(I);WrZ80(R->HL.W,I);break;
|
||||
|
||||
case RLCA:
|
||||
I=R->AF.B.h&0x80? C_FLAG:0;
|
||||
R->AF.B.h=(R->AF.B.h<<1)|I;
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RLA:
|
||||
I=R->AF.B.h&0x80? C_FLAG:0;
|
||||
R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRCA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
|
||||
case RST00: M_RST(0x0000);break;
|
||||
case RST08: M_RST(0x0008);break;
|
||||
case RST10: M_RST(0x0010);break;
|
||||
case RST18: M_RST(0x0018);break;
|
||||
case RST20: M_RST(0x0020);break;
|
||||
case RST28: M_RST(0x0028);break;
|
||||
case RST30: M_RST(0x0030);break;
|
||||
case RST38: M_RST(0x0038);break;
|
||||
|
||||
case PUSH_BC: M_PUSH(BC);break;
|
||||
case PUSH_DE: M_PUSH(DE);break;
|
||||
case PUSH_HL: M_PUSH(HL);break;
|
||||
case PUSH_AF: M_PUSH(AF);break;
|
||||
|
||||
case POP_BC: M_POP(BC);break;
|
||||
case POP_DE: M_POP(DE);break;
|
||||
case POP_HL: M_POP(HL);break;
|
||||
case POP_AF: M_POP(AF);break;
|
||||
|
||||
case DJNZ: if(--R->BC.B.h) { M_JR; } else R->PC.W++;break;
|
||||
case JP: M_JP;break;
|
||||
case JR: M_JR;break;
|
||||
case CALL: M_CALL;break;
|
||||
case RET: M_RET;break;
|
||||
case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break;
|
||||
case CPL: R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
|
||||
case NOP: break;
|
||||
case OUTA: OutZ80(RdZ80(R->PC.W++),R->AF.B.h);break;
|
||||
case INA: R->AF.B.h=InZ80(RdZ80(R->PC.W++));break;
|
||||
case HALT: R->PC.W--;R->IFF|=0x80;R->ICount=0;break;
|
||||
|
||||
case DI:
|
||||
R->IFF&=0xFE;
|
||||
break;
|
||||
case EI:
|
||||
R->IFF|=0x01;
|
||||
if(R->IRequest!=INT_NONE)
|
||||
{
|
||||
R->IFF|=0x20;
|
||||
R->IBackup=R->ICount;
|
||||
R->ICount=1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CCF:
|
||||
R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
|
||||
R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
|
||||
break;
|
||||
|
||||
case EXX:
|
||||
J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
|
||||
J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
|
||||
J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
|
||||
break;
|
||||
|
||||
case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
|
||||
case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
|
||||
|
||||
case LD_B_B: R->BC.B.h=R->BC.B.h;break;
|
||||
case LD_C_B: R->BC.B.l=R->BC.B.h;break;
|
||||
case LD_D_B: R->DE.B.h=R->BC.B.h;break;
|
||||
case LD_E_B: R->DE.B.l=R->BC.B.h;break;
|
||||
case LD_H_B: R->HL.B.h=R->BC.B.h;break;
|
||||
case LD_L_B: R->HL.B.l=R->BC.B.h;break;
|
||||
case LD_A_B: R->AF.B.h=R->BC.B.h;break;
|
||||
case LD_xHL_B: WrZ80(R->HL.W,R->BC.B.h);break;
|
||||
|
||||
case LD_B_C: R->BC.B.h=R->BC.B.l;break;
|
||||
case LD_C_C: R->BC.B.l=R->BC.B.l;break;
|
||||
case LD_D_C: R->DE.B.h=R->BC.B.l;break;
|
||||
case LD_E_C: R->DE.B.l=R->BC.B.l;break;
|
||||
case LD_H_C: R->HL.B.h=R->BC.B.l;break;
|
||||
case LD_L_C: R->HL.B.l=R->BC.B.l;break;
|
||||
case LD_A_C: R->AF.B.h=R->BC.B.l;break;
|
||||
case LD_xHL_C: WrZ80(R->HL.W,R->BC.B.l);break;
|
||||
|
||||
case LD_B_D: R->BC.B.h=R->DE.B.h;break;
|
||||
case LD_C_D: R->BC.B.l=R->DE.B.h;break;
|
||||
case LD_D_D: R->DE.B.h=R->DE.B.h;break;
|
||||
case LD_E_D: R->DE.B.l=R->DE.B.h;break;
|
||||
case LD_H_D: R->HL.B.h=R->DE.B.h;break;
|
||||
case LD_L_D: R->HL.B.l=R->DE.B.h;break;
|
||||
case LD_A_D: R->AF.B.h=R->DE.B.h;break;
|
||||
case LD_xHL_D: WrZ80(R->HL.W,R->DE.B.h);break;
|
||||
|
||||
case LD_B_E: R->BC.B.h=R->DE.B.l;break;
|
||||
case LD_C_E: R->BC.B.l=R->DE.B.l;break;
|
||||
case LD_D_E: R->DE.B.h=R->DE.B.l;break;
|
||||
case LD_E_E: R->DE.B.l=R->DE.B.l;break;
|
||||
case LD_H_E: R->HL.B.h=R->DE.B.l;break;
|
||||
case LD_L_E: R->HL.B.l=R->DE.B.l;break;
|
||||
case LD_A_E: R->AF.B.h=R->DE.B.l;break;
|
||||
case LD_xHL_E: WrZ80(R->HL.W,R->DE.B.l);break;
|
||||
|
||||
case LD_B_H: R->BC.B.h=R->HL.B.h;break;
|
||||
case LD_C_H: R->BC.B.l=R->HL.B.h;break;
|
||||
case LD_D_H: R->DE.B.h=R->HL.B.h;break;
|
||||
case LD_E_H: R->DE.B.l=R->HL.B.h;break;
|
||||
case LD_H_H: R->HL.B.h=R->HL.B.h;break;
|
||||
case LD_L_H: R->HL.B.l=R->HL.B.h;break;
|
||||
case LD_A_H: R->AF.B.h=R->HL.B.h;break;
|
||||
case LD_xHL_H: WrZ80(R->HL.W,R->HL.B.h);break;
|
||||
|
||||
case LD_B_L: R->BC.B.h=R->HL.B.l;break;
|
||||
case LD_C_L: R->BC.B.l=R->HL.B.l;break;
|
||||
case LD_D_L: R->DE.B.h=R->HL.B.l;break;
|
||||
case LD_E_L: R->DE.B.l=R->HL.B.l;break;
|
||||
case LD_H_L: R->HL.B.h=R->HL.B.l;break;
|
||||
case LD_L_L: R->HL.B.l=R->HL.B.l;break;
|
||||
case LD_A_L: R->AF.B.h=R->HL.B.l;break;
|
||||
case LD_xHL_L: WrZ80(R->HL.W,R->HL.B.l);break;
|
||||
|
||||
case LD_B_A: R->BC.B.h=R->AF.B.h;break;
|
||||
case LD_C_A: R->BC.B.l=R->AF.B.h;break;
|
||||
case LD_D_A: R->DE.B.h=R->AF.B.h;break;
|
||||
case LD_E_A: R->DE.B.l=R->AF.B.h;break;
|
||||
case LD_H_A: R->HL.B.h=R->AF.B.h;break;
|
||||
case LD_L_A: R->HL.B.l=R->AF.B.h;break;
|
||||
case LD_A_A: R->AF.B.h=R->AF.B.h;break;
|
||||
case LD_xHL_A: WrZ80(R->HL.W,R->AF.B.h);break;
|
||||
|
||||
case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
|
||||
case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
|
||||
|
||||
case LD_B_xHL: R->BC.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_C_xHL: R->BC.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_D_xHL: R->DE.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_E_xHL: R->DE.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_H_xHL: R->HL.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_L_xHL: R->HL.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_A_xHL: R->AF.B.h=RdZ80(R->HL.W);break;
|
||||
|
||||
case LD_B_BYTE: R->BC.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_C_BYTE: R->BC.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_D_BYTE: R->DE.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_E_BYTE: R->DE.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_H_BYTE: R->HL.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_L_BYTE: R->HL.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_A_BYTE: R->AF.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_xHL_BYTE: WrZ80(R->HL.W,RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_xWORD_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->HL.B.l);
|
||||
WrZ80(J.W,R->HL.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->HL.B.l=RdZ80(J.W++);
|
||||
R->HL.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_A_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->AF.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_xWORD_A:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);
|
||||
break;
|
||||
|
||||
case EX_HL_xSP:
|
||||
J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->HL.B.l);
|
||||
J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->HL.B.h);
|
||||
R->HL.W=J.W;
|
||||
break;
|
||||
|
||||
case DAA:
|
||||
J.W=R->AF.B.h;
|
||||
if(R->AF.B.l&C_FLAG) J.W|=256;
|
||||
if(R->AF.B.l&H_FLAG) J.W|=512;
|
||||
if(R->AF.B.l&N_FLAG) J.W|=1024;
|
||||
R->AF.W=DAATable[J.W];
|
||||
break;
|
||||
|
||||
default:
|
||||
if(R->TrapBadOps)
|
||||
printf
|
||||
(
|
||||
"[Z80 %lX] Unrecognized instruction: %02X at PC=%04X\n",
|
||||
(long)R->User,RdZ80(R->PC.W-1),R->PC.W-1
|
||||
);
|
||||
break;
|
||||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** Codes.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the main table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case JR_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||
case JR_NC: if(R->AF.B.l&C_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||
case JR_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||
case JR_C: if(R->AF.B.l&C_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||
|
||||
case JP_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_Z: if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_C: if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_PE: if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_M: if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
|
||||
case RET_NZ: if(!(R->AF.B.l&Z_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_NC: if(!(R->AF.B.l&C_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_PO: if(!(R->AF.B.l&P_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_P: if(!(R->AF.B.l&S_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_C: if(R->AF.B.l&C_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_M: if(R->AF.B.l&S_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
|
||||
case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_C: if(R->AF.B.l&C_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_M: if(R->AF.B.l&S_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
|
||||
case ADD_B: M_ADD(R->BC.B.h);break;
|
||||
case ADD_C: M_ADD(R->BC.B.l);break;
|
||||
case ADD_D: M_ADD(R->DE.B.h);break;
|
||||
case ADD_E: M_ADD(R->DE.B.l);break;
|
||||
case ADD_H: M_ADD(R->HL.B.h);break;
|
||||
case ADD_L: M_ADD(R->HL.B.l);break;
|
||||
case ADD_A: M_ADD(R->AF.B.h);break;
|
||||
case ADD_xHL: I=RdZ80(R->HL.W);M_ADD(I);break;
|
||||
case ADD_BYTE: I=RdZ80(R->PC.W++);M_ADD(I);break;
|
||||
|
||||
case SUB_B: M_SUB(R->BC.B.h);break;
|
||||
case SUB_C: M_SUB(R->BC.B.l);break;
|
||||
case SUB_D: M_SUB(R->DE.B.h);break;
|
||||
case SUB_E: M_SUB(R->DE.B.l);break;
|
||||
case SUB_H: M_SUB(R->HL.B.h);break;
|
||||
case SUB_L: M_SUB(R->HL.B.l);break;
|
||||
case SUB_A: R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case SUB_xHL: I=RdZ80(R->HL.W);M_SUB(I);break;
|
||||
case SUB_BYTE: I=RdZ80(R->PC.W++);M_SUB(I);break;
|
||||
|
||||
case AND_B: M_AND(R->BC.B.h);break;
|
||||
case AND_C: M_AND(R->BC.B.l);break;
|
||||
case AND_D: M_AND(R->DE.B.h);break;
|
||||
case AND_E: M_AND(R->DE.B.l);break;
|
||||
case AND_H: M_AND(R->HL.B.h);break;
|
||||
case AND_L: M_AND(R->HL.B.l);break;
|
||||
case AND_A: M_AND(R->AF.B.h);break;
|
||||
case AND_xHL: I=RdZ80(R->HL.W);M_AND(I);break;
|
||||
case AND_BYTE: I=RdZ80(R->PC.W++);M_AND(I);break;
|
||||
|
||||
case OR_B: M_OR(R->BC.B.h);break;
|
||||
case OR_C: M_OR(R->BC.B.l);break;
|
||||
case OR_D: M_OR(R->DE.B.h);break;
|
||||
case OR_E: M_OR(R->DE.B.l);break;
|
||||
case OR_H: M_OR(R->HL.B.h);break;
|
||||
case OR_L: M_OR(R->HL.B.l);break;
|
||||
case OR_A: M_OR(R->AF.B.h);break;
|
||||
case OR_xHL: I=RdZ80(R->HL.W);M_OR(I);break;
|
||||
case OR_BYTE: I=RdZ80(R->PC.W++);M_OR(I);break;
|
||||
|
||||
case ADC_B: M_ADC(R->BC.B.h);break;
|
||||
case ADC_C: M_ADC(R->BC.B.l);break;
|
||||
case ADC_D: M_ADC(R->DE.B.h);break;
|
||||
case ADC_E: M_ADC(R->DE.B.l);break;
|
||||
case ADC_H: M_ADC(R->HL.B.h);break;
|
||||
case ADC_L: M_ADC(R->HL.B.l);break;
|
||||
case ADC_A: M_ADC(R->AF.B.h);break;
|
||||
case ADC_xHL: I=RdZ80(R->HL.W);M_ADC(I);break;
|
||||
case ADC_BYTE: I=RdZ80(R->PC.W++);M_ADC(I);break;
|
||||
|
||||
case SBC_B: M_SBC(R->BC.B.h);break;
|
||||
case SBC_C: M_SBC(R->BC.B.l);break;
|
||||
case SBC_D: M_SBC(R->DE.B.h);break;
|
||||
case SBC_E: M_SBC(R->DE.B.l);break;
|
||||
case SBC_H: M_SBC(R->HL.B.h);break;
|
||||
case SBC_L: M_SBC(R->HL.B.l);break;
|
||||
case SBC_A: M_SBC(R->AF.B.h);break;
|
||||
case SBC_xHL: I=RdZ80(R->HL.W);M_SBC(I);break;
|
||||
case SBC_BYTE: I=RdZ80(R->PC.W++);M_SBC(I);break;
|
||||
|
||||
case XOR_B: M_XOR(R->BC.B.h);break;
|
||||
case XOR_C: M_XOR(R->BC.B.l);break;
|
||||
case XOR_D: M_XOR(R->DE.B.h);break;
|
||||
case XOR_E: M_XOR(R->DE.B.l);break;
|
||||
case XOR_H: M_XOR(R->HL.B.h);break;
|
||||
case XOR_L: M_XOR(R->HL.B.l);break;
|
||||
case XOR_A: R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
|
||||
case XOR_xHL: I=RdZ80(R->HL.W);M_XOR(I);break;
|
||||
case XOR_BYTE: I=RdZ80(R->PC.W++);M_XOR(I);break;
|
||||
|
||||
case CP_B: M_CP(R->BC.B.h);break;
|
||||
case CP_C: M_CP(R->BC.B.l);break;
|
||||
case CP_D: M_CP(R->DE.B.h);break;
|
||||
case CP_E: M_CP(R->DE.B.l);break;
|
||||
case CP_H: M_CP(R->HL.B.h);break;
|
||||
case CP_L: M_CP(R->HL.B.l);break;
|
||||
case CP_A: R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case CP_xHL: I=RdZ80(R->HL.W);M_CP(I);break;
|
||||
case CP_BYTE: I=RdZ80(R->PC.W++);M_CP(I);break;
|
||||
|
||||
case LD_BC_WORD: M_LDWORD(BC);break;
|
||||
case LD_DE_WORD: M_LDWORD(DE);break;
|
||||
case LD_HL_WORD: M_LDWORD(HL);break;
|
||||
case LD_SP_WORD: M_LDWORD(SP);break;
|
||||
|
||||
case LD_PC_HL: R->PC.W=R->HL.W;break;
|
||||
case LD_SP_HL: R->SP.W=R->HL.W;break;
|
||||
case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
|
||||
case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
|
||||
|
||||
case ADD_HL_BC: M_ADDW(HL,BC);break;
|
||||
case ADD_HL_DE: M_ADDW(HL,DE);break;
|
||||
case ADD_HL_HL: M_ADDW(HL,HL);break;
|
||||
case ADD_HL_SP: M_ADDW(HL,SP);break;
|
||||
|
||||
case DEC_BC: R->BC.W--;break;
|
||||
case DEC_DE: R->DE.W--;break;
|
||||
case DEC_HL: R->HL.W--;break;
|
||||
case DEC_SP: R->SP.W--;break;
|
||||
|
||||
case INC_BC: R->BC.W++;break;
|
||||
case INC_DE: R->DE.W++;break;
|
||||
case INC_HL: R->HL.W++;break;
|
||||
case INC_SP: R->SP.W++;break;
|
||||
|
||||
case DEC_B: M_DEC(R->BC.B.h);break;
|
||||
case DEC_C: M_DEC(R->BC.B.l);break;
|
||||
case DEC_D: M_DEC(R->DE.B.h);break;
|
||||
case DEC_E: M_DEC(R->DE.B.l);break;
|
||||
case DEC_H: M_DEC(R->HL.B.h);break;
|
||||
case DEC_L: M_DEC(R->HL.B.l);break;
|
||||
case DEC_A: M_DEC(R->AF.B.h);break;
|
||||
case DEC_xHL: I=RdZ80(R->HL.W);M_DEC(I);WrZ80(R->HL.W,I);break;
|
||||
|
||||
case INC_B: M_INC(R->BC.B.h);break;
|
||||
case INC_C: M_INC(R->BC.B.l);break;
|
||||
case INC_D: M_INC(R->DE.B.h);break;
|
||||
case INC_E: M_INC(R->DE.B.l);break;
|
||||
case INC_H: M_INC(R->HL.B.h);break;
|
||||
case INC_L: M_INC(R->HL.B.l);break;
|
||||
case INC_A: M_INC(R->AF.B.h);break;
|
||||
case INC_xHL: I=RdZ80(R->HL.W);M_INC(I);WrZ80(R->HL.W,I);break;
|
||||
|
||||
case RLCA:
|
||||
I=R->AF.B.h&0x80? C_FLAG:0;
|
||||
R->AF.B.h=(R->AF.B.h<<1)|I;
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RLA:
|
||||
I=R->AF.B.h&0x80? C_FLAG:0;
|
||||
R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRCA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
|
||||
case RST00: M_RST(0x0000);break;
|
||||
case RST08: M_RST(0x0008);break;
|
||||
case RST10: M_RST(0x0010);break;
|
||||
case RST18: M_RST(0x0018);break;
|
||||
case RST20: M_RST(0x0020);break;
|
||||
case RST28: M_RST(0x0028);break;
|
||||
case RST30: M_RST(0x0030);break;
|
||||
case RST38: M_RST(0x0038);break;
|
||||
|
||||
case PUSH_BC: M_PUSH(BC);break;
|
||||
case PUSH_DE: M_PUSH(DE);break;
|
||||
case PUSH_HL: M_PUSH(HL);break;
|
||||
case PUSH_AF: M_PUSH(AF);break;
|
||||
|
||||
case POP_BC: M_POP(BC);break;
|
||||
case POP_DE: M_POP(DE);break;
|
||||
case POP_HL: M_POP(HL);break;
|
||||
case POP_AF: M_POP(AF);break;
|
||||
|
||||
case DJNZ: if(--R->BC.B.h) { R->ICount-=5;M_JR; } else R->PC.W++;break;
|
||||
case JP: M_JP;break;
|
||||
case JR: M_JR;break;
|
||||
case CALL: M_CALL;break;
|
||||
case RET: M_RET;break;
|
||||
case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break;
|
||||
case CPL: R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
|
||||
case NOP: break;
|
||||
case OUTA: I=RdZ80(R->PC.W++);OutZ80(I,R->AF.B.h);break;
|
||||
case INA: I=RdZ80(R->PC.W++);R->AF.B.h=InZ80(I);break;
|
||||
|
||||
case HALT:
|
||||
R->PC.W--;
|
||||
R->IFF|=IFF_HALT;
|
||||
R->IBackup=0;
|
||||
R->ICount=0;
|
||||
break;
|
||||
|
||||
case DI:
|
||||
if(R->IFF&IFF_EI) R->ICount+=R->IBackup-1;
|
||||
R->IFF&=~(IFF_1|IFF_2|IFF_EI);
|
||||
break;
|
||||
|
||||
case EI:
|
||||
if(!(R->IFF&(IFF_1|IFF_EI)))
|
||||
{
|
||||
R->IFF|=IFF_2|IFF_EI;
|
||||
R->IBackup=R->ICount;
|
||||
R->ICount=1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CCF:
|
||||
R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
|
||||
R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
|
||||
break;
|
||||
|
||||
case EXX:
|
||||
J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
|
||||
J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
|
||||
J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
|
||||
break;
|
||||
|
||||
case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
|
||||
case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
|
||||
|
||||
case LD_B_B: R->BC.B.h=R->BC.B.h;break;
|
||||
case LD_C_B: R->BC.B.l=R->BC.B.h;break;
|
||||
case LD_D_B: R->DE.B.h=R->BC.B.h;break;
|
||||
case LD_E_B: R->DE.B.l=R->BC.B.h;break;
|
||||
case LD_H_B: R->HL.B.h=R->BC.B.h;break;
|
||||
case LD_L_B: R->HL.B.l=R->BC.B.h;break;
|
||||
case LD_A_B: R->AF.B.h=R->BC.B.h;break;
|
||||
case LD_xHL_B: WrZ80(R->HL.W,R->BC.B.h);break;
|
||||
|
||||
case LD_B_C: R->BC.B.h=R->BC.B.l;break;
|
||||
case LD_C_C: R->BC.B.l=R->BC.B.l;break;
|
||||
case LD_D_C: R->DE.B.h=R->BC.B.l;break;
|
||||
case LD_E_C: R->DE.B.l=R->BC.B.l;break;
|
||||
case LD_H_C: R->HL.B.h=R->BC.B.l;break;
|
||||
case LD_L_C: R->HL.B.l=R->BC.B.l;break;
|
||||
case LD_A_C: R->AF.B.h=R->BC.B.l;break;
|
||||
case LD_xHL_C: WrZ80(R->HL.W,R->BC.B.l);break;
|
||||
|
||||
case LD_B_D: R->BC.B.h=R->DE.B.h;break;
|
||||
case LD_C_D: R->BC.B.l=R->DE.B.h;break;
|
||||
case LD_D_D: R->DE.B.h=R->DE.B.h;break;
|
||||
case LD_E_D: R->DE.B.l=R->DE.B.h;break;
|
||||
case LD_H_D: R->HL.B.h=R->DE.B.h;break;
|
||||
case LD_L_D: R->HL.B.l=R->DE.B.h;break;
|
||||
case LD_A_D: R->AF.B.h=R->DE.B.h;break;
|
||||
case LD_xHL_D: WrZ80(R->HL.W,R->DE.B.h);break;
|
||||
|
||||
case LD_B_E: R->BC.B.h=R->DE.B.l;break;
|
||||
case LD_C_E: R->BC.B.l=R->DE.B.l;break;
|
||||
case LD_D_E: R->DE.B.h=R->DE.B.l;break;
|
||||
case LD_E_E: R->DE.B.l=R->DE.B.l;break;
|
||||
case LD_H_E: R->HL.B.h=R->DE.B.l;break;
|
||||
case LD_L_E: R->HL.B.l=R->DE.B.l;break;
|
||||
case LD_A_E: R->AF.B.h=R->DE.B.l;break;
|
||||
case LD_xHL_E: WrZ80(R->HL.W,R->DE.B.l);break;
|
||||
|
||||
case LD_B_H: R->BC.B.h=R->HL.B.h;break;
|
||||
case LD_C_H: R->BC.B.l=R->HL.B.h;break;
|
||||
case LD_D_H: R->DE.B.h=R->HL.B.h;break;
|
||||
case LD_E_H: R->DE.B.l=R->HL.B.h;break;
|
||||
case LD_H_H: R->HL.B.h=R->HL.B.h;break;
|
||||
case LD_L_H: R->HL.B.l=R->HL.B.h;break;
|
||||
case LD_A_H: R->AF.B.h=R->HL.B.h;break;
|
||||
case LD_xHL_H: WrZ80(R->HL.W,R->HL.B.h);break;
|
||||
|
||||
case LD_B_L: R->BC.B.h=R->HL.B.l;break;
|
||||
case LD_C_L: R->BC.B.l=R->HL.B.l;break;
|
||||
case LD_D_L: R->DE.B.h=R->HL.B.l;break;
|
||||
case LD_E_L: R->DE.B.l=R->HL.B.l;break;
|
||||
case LD_H_L: R->HL.B.h=R->HL.B.l;break;
|
||||
case LD_L_L: R->HL.B.l=R->HL.B.l;break;
|
||||
case LD_A_L: R->AF.B.h=R->HL.B.l;break;
|
||||
case LD_xHL_L: WrZ80(R->HL.W,R->HL.B.l);break;
|
||||
|
||||
case LD_B_A: R->BC.B.h=R->AF.B.h;break;
|
||||
case LD_C_A: R->BC.B.l=R->AF.B.h;break;
|
||||
case LD_D_A: R->DE.B.h=R->AF.B.h;break;
|
||||
case LD_E_A: R->DE.B.l=R->AF.B.h;break;
|
||||
case LD_H_A: R->HL.B.h=R->AF.B.h;break;
|
||||
case LD_L_A: R->HL.B.l=R->AF.B.h;break;
|
||||
case LD_A_A: R->AF.B.h=R->AF.B.h;break;
|
||||
case LD_xHL_A: WrZ80(R->HL.W,R->AF.B.h);break;
|
||||
|
||||
case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
|
||||
case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
|
||||
|
||||
case LD_B_xHL: R->BC.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_C_xHL: R->BC.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_D_xHL: R->DE.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_E_xHL: R->DE.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_H_xHL: R->HL.B.h=RdZ80(R->HL.W);break;
|
||||
case LD_L_xHL: R->HL.B.l=RdZ80(R->HL.W);break;
|
||||
case LD_A_xHL: R->AF.B.h=RdZ80(R->HL.W);break;
|
||||
|
||||
case LD_B_BYTE: R->BC.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_C_BYTE: R->BC.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_D_BYTE: R->DE.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_E_BYTE: R->DE.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_H_BYTE: R->HL.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_L_BYTE: R->HL.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_A_BYTE: R->AF.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_xHL_BYTE: WrZ80(R->HL.W,RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_xWORD_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->HL.B.l);
|
||||
WrZ80(J.W,R->HL.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->HL.B.l=RdZ80(J.W++);
|
||||
R->HL.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_A_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->AF.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_xWORD_A:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);
|
||||
break;
|
||||
|
||||
case EX_HL_xSP:
|
||||
J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->HL.B.l);
|
||||
J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->HL.B.h);
|
||||
R->HL.W=J.W;
|
||||
break;
|
||||
|
||||
case DAA:
|
||||
J.W=R->AF.B.h;
|
||||
if(R->AF.B.l&C_FLAG) J.W|=256;
|
||||
if(R->AF.B.l&H_FLAG) J.W|=512;
|
||||
if(R->AF.B.l&N_FLAG) J.W|=1024;
|
||||
R->AF.W=DAATable[J.W];
|
||||
break;
|
||||
|
||||
default:
|
||||
if(R->TrapBadOps)
|
||||
printf
|
||||
(
|
||||
"[Z80 %lX] Unrecognized instruction: %02X at PC=%04X\n",
|
||||
(long)R->User,RdZ80(R->PC.W-1),R->PC.W-1
|
||||
);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,204 +1,204 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesCB.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the CB table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case RLC_B: M_RLC(R->BC.B.h);break; case RLC_C: M_RLC(R->BC.B.l);break;
|
||||
case RLC_D: M_RLC(R->DE.B.h);break; case RLC_E: M_RLC(R->DE.B.l);break;
|
||||
case RLC_H: M_RLC(R->HL.B.h);break; case RLC_L: M_RLC(R->HL.B.l);break;
|
||||
case RLC_xHL: I=RdZ80(R->HL.W);M_RLC(I);WrZ80(R->HL.W,I);break;
|
||||
case RLC_A: M_RLC(R->AF.B.h);break;
|
||||
|
||||
case RRC_B: M_RRC(R->BC.B.h);break; case RRC_C: M_RRC(R->BC.B.l);break;
|
||||
case RRC_D: M_RRC(R->DE.B.h);break; case RRC_E: M_RRC(R->DE.B.l);break;
|
||||
case RRC_H: M_RRC(R->HL.B.h);break; case RRC_L: M_RRC(R->HL.B.l);break;
|
||||
case RRC_xHL: I=RdZ80(R->HL.W);M_RRC(I);WrZ80(R->HL.W,I);break;
|
||||
case RRC_A: M_RRC(R->AF.B.h);break;
|
||||
|
||||
case RL_B: M_RL(R->BC.B.h);break; case RL_C: M_RL(R->BC.B.l);break;
|
||||
case RL_D: M_RL(R->DE.B.h);break; case RL_E: M_RL(R->DE.B.l);break;
|
||||
case RL_H: M_RL(R->HL.B.h);break; case RL_L: M_RL(R->HL.B.l);break;
|
||||
case RL_xHL: I=RdZ80(R->HL.W);M_RL(I);WrZ80(R->HL.W,I);break;
|
||||
case RL_A: M_RL(R->AF.B.h);break;
|
||||
|
||||
case RR_B: M_RR(R->BC.B.h);break; case RR_C: M_RR(R->BC.B.l);break;
|
||||
case RR_D: M_RR(R->DE.B.h);break; case RR_E: M_RR(R->DE.B.l);break;
|
||||
case RR_H: M_RR(R->HL.B.h);break; case RR_L: M_RR(R->HL.B.l);break;
|
||||
case RR_xHL: I=RdZ80(R->HL.W);M_RR(I);WrZ80(R->HL.W,I);break;
|
||||
case RR_A: M_RR(R->AF.B.h);break;
|
||||
|
||||
case SLA_B: M_SLA(R->BC.B.h);break; case SLA_C: M_SLA(R->BC.B.l);break;
|
||||
case SLA_D: M_SLA(R->DE.B.h);break; case SLA_E: M_SLA(R->DE.B.l);break;
|
||||
case SLA_H: M_SLA(R->HL.B.h);break; case SLA_L: M_SLA(R->HL.B.l);break;
|
||||
case SLA_xHL: I=RdZ80(R->HL.W);M_SLA(I);WrZ80(R->HL.W,I);break;
|
||||
case SLA_A: M_SLA(R->AF.B.h);break;
|
||||
|
||||
case SRA_B: M_SRA(R->BC.B.h);break; case SRA_C: M_SRA(R->BC.B.l);break;
|
||||
case SRA_D: M_SRA(R->DE.B.h);break; case SRA_E: M_SRA(R->DE.B.l);break;
|
||||
case SRA_H: M_SRA(R->HL.B.h);break; case SRA_L: M_SRA(R->HL.B.l);break;
|
||||
case SRA_xHL: I=RdZ80(R->HL.W);M_SRA(I);WrZ80(R->HL.W,I);break;
|
||||
case SRA_A: M_SRA(R->AF.B.h);break;
|
||||
|
||||
case SLL_B: M_SLL(R->BC.B.h);break; case SLL_C: M_SLL(R->BC.B.l);break;
|
||||
case SLL_D: M_SLL(R->DE.B.h);break; case SLL_E: M_SLL(R->DE.B.l);break;
|
||||
case SLL_H: M_SLL(R->HL.B.h);break; case SLL_L: M_SLL(R->HL.B.l);break;
|
||||
case SLL_xHL: I=RdZ80(R->HL.W);M_SLL(I);WrZ80(R->HL.W,I);break;
|
||||
case SLL_A: M_SLL(R->AF.B.h);break;
|
||||
|
||||
case SRL_B: M_SRL(R->BC.B.h);break; case SRL_C: M_SRL(R->BC.B.l);break;
|
||||
case SRL_D: M_SRL(R->DE.B.h);break; case SRL_E: M_SRL(R->DE.B.l);break;
|
||||
case SRL_H: M_SRL(R->HL.B.h);break; case SRL_L: M_SRL(R->HL.B.l);break;
|
||||
case SRL_xHL: I=RdZ80(R->HL.W);M_SRL(I);WrZ80(R->HL.W,I);break;
|
||||
case SRL_A: M_SRL(R->AF.B.h);break;
|
||||
|
||||
case BIT0_B: M_BIT(0,R->BC.B.h);break; case BIT0_C: M_BIT(0,R->BC.B.l);break;
|
||||
case BIT0_D: M_BIT(0,R->DE.B.h);break; case BIT0_E: M_BIT(0,R->DE.B.l);break;
|
||||
case BIT0_H: M_BIT(0,R->HL.B.h);break; case BIT0_L: M_BIT(0,R->HL.B.l);break;
|
||||
case BIT0_xHL: I=RdZ80(R->HL.W);M_BIT(0,I);break;
|
||||
case BIT0_A: M_BIT(0,R->AF.B.h);break;
|
||||
|
||||
case BIT1_B: M_BIT(1,R->BC.B.h);break; case BIT1_C: M_BIT(1,R->BC.B.l);break;
|
||||
case BIT1_D: M_BIT(1,R->DE.B.h);break; case BIT1_E: M_BIT(1,R->DE.B.l);break;
|
||||
case BIT1_H: M_BIT(1,R->HL.B.h);break; case BIT1_L: M_BIT(1,R->HL.B.l);break;
|
||||
case BIT1_xHL: I=RdZ80(R->HL.W);M_BIT(1,I);break;
|
||||
case BIT1_A: M_BIT(1,R->AF.B.h);break;
|
||||
|
||||
case BIT2_B: M_BIT(2,R->BC.B.h);break; case BIT2_C: M_BIT(2,R->BC.B.l);break;
|
||||
case BIT2_D: M_BIT(2,R->DE.B.h);break; case BIT2_E: M_BIT(2,R->DE.B.l);break;
|
||||
case BIT2_H: M_BIT(2,R->HL.B.h);break; case BIT2_L: M_BIT(2,R->HL.B.l);break;
|
||||
case BIT2_xHL: I=RdZ80(R->HL.W);M_BIT(2,I);break;
|
||||
case BIT2_A: M_BIT(2,R->AF.B.h);break;
|
||||
|
||||
case BIT3_B: M_BIT(3,R->BC.B.h);break; case BIT3_C: M_BIT(3,R->BC.B.l);break;
|
||||
case BIT3_D: M_BIT(3,R->DE.B.h);break; case BIT3_E: M_BIT(3,R->DE.B.l);break;
|
||||
case BIT3_H: M_BIT(3,R->HL.B.h);break; case BIT3_L: M_BIT(3,R->HL.B.l);break;
|
||||
case BIT3_xHL: I=RdZ80(R->HL.W);M_BIT(3,I);break;
|
||||
case BIT3_A: M_BIT(3,R->AF.B.h);break;
|
||||
|
||||
case BIT4_B: M_BIT(4,R->BC.B.h);break; case BIT4_C: M_BIT(4,R->BC.B.l);break;
|
||||
case BIT4_D: M_BIT(4,R->DE.B.h);break; case BIT4_E: M_BIT(4,R->DE.B.l);break;
|
||||
case BIT4_H: M_BIT(4,R->HL.B.h);break; case BIT4_L: M_BIT(4,R->HL.B.l);break;
|
||||
case BIT4_xHL: I=RdZ80(R->HL.W);M_BIT(4,I);break;
|
||||
case BIT4_A: M_BIT(4,R->AF.B.h);break;
|
||||
|
||||
case BIT5_B: M_BIT(5,R->BC.B.h);break; case BIT5_C: M_BIT(5,R->BC.B.l);break;
|
||||
case BIT5_D: M_BIT(5,R->DE.B.h);break; case BIT5_E: M_BIT(5,R->DE.B.l);break;
|
||||
case BIT5_H: M_BIT(5,R->HL.B.h);break; case BIT5_L: M_BIT(5,R->HL.B.l);break;
|
||||
case BIT5_xHL: I=RdZ80(R->HL.W);M_BIT(5,I);break;
|
||||
case BIT5_A: M_BIT(5,R->AF.B.h);break;
|
||||
|
||||
case BIT6_B: M_BIT(6,R->BC.B.h);break; case BIT6_C: M_BIT(6,R->BC.B.l);break;
|
||||
case BIT6_D: M_BIT(6,R->DE.B.h);break; case BIT6_E: M_BIT(6,R->DE.B.l);break;
|
||||
case BIT6_H: M_BIT(6,R->HL.B.h);break; case BIT6_L: M_BIT(6,R->HL.B.l);break;
|
||||
case BIT6_xHL: I=RdZ80(R->HL.W);M_BIT(6,I);break;
|
||||
case BIT6_A: M_BIT(6,R->AF.B.h);break;
|
||||
|
||||
case BIT7_B: M_BIT(7,R->BC.B.h);break; case BIT7_C: M_BIT(7,R->BC.B.l);break;
|
||||
case BIT7_D: M_BIT(7,R->DE.B.h);break; case BIT7_E: M_BIT(7,R->DE.B.l);break;
|
||||
case BIT7_H: M_BIT(7,R->HL.B.h);break; case BIT7_L: M_BIT(7,R->HL.B.l);break;
|
||||
case BIT7_xHL: I=RdZ80(R->HL.W);M_BIT(7,I);break;
|
||||
case BIT7_A: M_BIT(7,R->AF.B.h);break;
|
||||
|
||||
case RES0_B: M_RES(0,R->BC.B.h);break; case RES0_C: M_RES(0,R->BC.B.l);break;
|
||||
case RES0_D: M_RES(0,R->DE.B.h);break; case RES0_E: M_RES(0,R->DE.B.l);break;
|
||||
case RES0_H: M_RES(0,R->HL.B.h);break; case RES0_L: M_RES(0,R->HL.B.l);break;
|
||||
case RES0_xHL: I=RdZ80(R->HL.W);M_RES(0,I);WrZ80(R->HL.W,I);break;
|
||||
case RES0_A: M_RES(0,R->AF.B.h);break;
|
||||
|
||||
case RES1_B: M_RES(1,R->BC.B.h);break; case RES1_C: M_RES(1,R->BC.B.l);break;
|
||||
case RES1_D: M_RES(1,R->DE.B.h);break; case RES1_E: M_RES(1,R->DE.B.l);break;
|
||||
case RES1_H: M_RES(1,R->HL.B.h);break; case RES1_L: M_RES(1,R->HL.B.l);break;
|
||||
case RES1_xHL: I=RdZ80(R->HL.W);M_RES(1,I);WrZ80(R->HL.W,I);break;
|
||||
case RES1_A: M_RES(1,R->AF.B.h);break;
|
||||
|
||||
case RES2_B: M_RES(2,R->BC.B.h);break; case RES2_C: M_RES(2,R->BC.B.l);break;
|
||||
case RES2_D: M_RES(2,R->DE.B.h);break; case RES2_E: M_RES(2,R->DE.B.l);break;
|
||||
case RES2_H: M_RES(2,R->HL.B.h);break; case RES2_L: M_RES(2,R->HL.B.l);break;
|
||||
case RES2_xHL: I=RdZ80(R->HL.W);M_RES(2,I);WrZ80(R->HL.W,I);break;
|
||||
case RES2_A: M_RES(2,R->AF.B.h);break;
|
||||
|
||||
case RES3_B: M_RES(3,R->BC.B.h);break; case RES3_C: M_RES(3,R->BC.B.l);break;
|
||||
case RES3_D: M_RES(3,R->DE.B.h);break; case RES3_E: M_RES(3,R->DE.B.l);break;
|
||||
case RES3_H: M_RES(3,R->HL.B.h);break; case RES3_L: M_RES(3,R->HL.B.l);break;
|
||||
case RES3_xHL: I=RdZ80(R->HL.W);M_RES(3,I);WrZ80(R->HL.W,I);break;
|
||||
case RES3_A: M_RES(3,R->AF.B.h);break;
|
||||
|
||||
case RES4_B: M_RES(4,R->BC.B.h);break; case RES4_C: M_RES(4,R->BC.B.l);break;
|
||||
case RES4_D: M_RES(4,R->DE.B.h);break; case RES4_E: M_RES(4,R->DE.B.l);break;
|
||||
case RES4_H: M_RES(4,R->HL.B.h);break; case RES4_L: M_RES(4,R->HL.B.l);break;
|
||||
case RES4_xHL: I=RdZ80(R->HL.W);M_RES(4,I);WrZ80(R->HL.W,I);break;
|
||||
case RES4_A: M_RES(4,R->AF.B.h);break;
|
||||
|
||||
case RES5_B: M_RES(5,R->BC.B.h);break; case RES5_C: M_RES(5,R->BC.B.l);break;
|
||||
case RES5_D: M_RES(5,R->DE.B.h);break; case RES5_E: M_RES(5,R->DE.B.l);break;
|
||||
case RES5_H: M_RES(5,R->HL.B.h);break; case RES5_L: M_RES(5,R->HL.B.l);break;
|
||||
case RES5_xHL: I=RdZ80(R->HL.W);M_RES(5,I);WrZ80(R->HL.W,I);break;
|
||||
case RES5_A: M_RES(5,R->AF.B.h);break;
|
||||
|
||||
case RES6_B: M_RES(6,R->BC.B.h);break; case RES6_C: M_RES(6,R->BC.B.l);break;
|
||||
case RES6_D: M_RES(6,R->DE.B.h);break; case RES6_E: M_RES(6,R->DE.B.l);break;
|
||||
case RES6_H: M_RES(6,R->HL.B.h);break; case RES6_L: M_RES(6,R->HL.B.l);break;
|
||||
case RES6_xHL: I=RdZ80(R->HL.W);M_RES(6,I);WrZ80(R->HL.W,I);break;
|
||||
case RES6_A: M_RES(6,R->AF.B.h);break;
|
||||
|
||||
case RES7_B: M_RES(7,R->BC.B.h);break; case RES7_C: M_RES(7,R->BC.B.l);break;
|
||||
case RES7_D: M_RES(7,R->DE.B.h);break; case RES7_E: M_RES(7,R->DE.B.l);break;
|
||||
case RES7_H: M_RES(7,R->HL.B.h);break; case RES7_L: M_RES(7,R->HL.B.l);break;
|
||||
case RES7_xHL: I=RdZ80(R->HL.W);M_RES(7,I);WrZ80(R->HL.W,I);break;
|
||||
case RES7_A: M_RES(7,R->AF.B.h);break;
|
||||
|
||||
case SET0_B: M_SET(0,R->BC.B.h);break; case SET0_C: M_SET(0,R->BC.B.l);break;
|
||||
case SET0_D: M_SET(0,R->DE.B.h);break; case SET0_E: M_SET(0,R->DE.B.l);break;
|
||||
case SET0_H: M_SET(0,R->HL.B.h);break; case SET0_L: M_SET(0,R->HL.B.l);break;
|
||||
case SET0_xHL: I=RdZ80(R->HL.W);M_SET(0,I);WrZ80(R->HL.W,I);break;
|
||||
case SET0_A: M_SET(0,R->AF.B.h);break;
|
||||
|
||||
case SET1_B: M_SET(1,R->BC.B.h);break; case SET1_C: M_SET(1,R->BC.B.l);break;
|
||||
case SET1_D: M_SET(1,R->DE.B.h);break; case SET1_E: M_SET(1,R->DE.B.l);break;
|
||||
case SET1_H: M_SET(1,R->HL.B.h);break; case SET1_L: M_SET(1,R->HL.B.l);break;
|
||||
case SET1_xHL: I=RdZ80(R->HL.W);M_SET(1,I);WrZ80(R->HL.W,I);break;
|
||||
case SET1_A: M_SET(1,R->AF.B.h);break;
|
||||
|
||||
case SET2_B: M_SET(2,R->BC.B.h);break; case SET2_C: M_SET(2,R->BC.B.l);break;
|
||||
case SET2_D: M_SET(2,R->DE.B.h);break; case SET2_E: M_SET(2,R->DE.B.l);break;
|
||||
case SET2_H: M_SET(2,R->HL.B.h);break; case SET2_L: M_SET(2,R->HL.B.l);break;
|
||||
case SET2_xHL: I=RdZ80(R->HL.W);M_SET(2,I);WrZ80(R->HL.W,I);break;
|
||||
case SET2_A: M_SET(2,R->AF.B.h);break;
|
||||
|
||||
case SET3_B: M_SET(3,R->BC.B.h);break; case SET3_C: M_SET(3,R->BC.B.l);break;
|
||||
case SET3_D: M_SET(3,R->DE.B.h);break; case SET3_E: M_SET(3,R->DE.B.l);break;
|
||||
case SET3_H: M_SET(3,R->HL.B.h);break; case SET3_L: M_SET(3,R->HL.B.l);break;
|
||||
case SET3_xHL: I=RdZ80(R->HL.W);M_SET(3,I);WrZ80(R->HL.W,I);break;
|
||||
case SET3_A: M_SET(3,R->AF.B.h);break;
|
||||
|
||||
case SET4_B: M_SET(4,R->BC.B.h);break; case SET4_C: M_SET(4,R->BC.B.l);break;
|
||||
case SET4_D: M_SET(4,R->DE.B.h);break; case SET4_E: M_SET(4,R->DE.B.l);break;
|
||||
case SET4_H: M_SET(4,R->HL.B.h);break; case SET4_L: M_SET(4,R->HL.B.l);break;
|
||||
case SET4_xHL: I=RdZ80(R->HL.W);M_SET(4,I);WrZ80(R->HL.W,I);break;
|
||||
case SET4_A: M_SET(4,R->AF.B.h);break;
|
||||
|
||||
case SET5_B: M_SET(5,R->BC.B.h);break; case SET5_C: M_SET(5,R->BC.B.l);break;
|
||||
case SET5_D: M_SET(5,R->DE.B.h);break; case SET5_E: M_SET(5,R->DE.B.l);break;
|
||||
case SET5_H: M_SET(5,R->HL.B.h);break; case SET5_L: M_SET(5,R->HL.B.l);break;
|
||||
case SET5_xHL: I=RdZ80(R->HL.W);M_SET(5,I);WrZ80(R->HL.W,I);break;
|
||||
case SET5_A: M_SET(5,R->AF.B.h);break;
|
||||
|
||||
case SET6_B: M_SET(6,R->BC.B.h);break; case SET6_C: M_SET(6,R->BC.B.l);break;
|
||||
case SET6_D: M_SET(6,R->DE.B.h);break; case SET6_E: M_SET(6,R->DE.B.l);break;
|
||||
case SET6_H: M_SET(6,R->HL.B.h);break; case SET6_L: M_SET(6,R->HL.B.l);break;
|
||||
case SET6_xHL: I=RdZ80(R->HL.W);M_SET(6,I);WrZ80(R->HL.W,I);break;
|
||||
case SET6_A: M_SET(6,R->AF.B.h);break;
|
||||
|
||||
case SET7_B: M_SET(7,R->BC.B.h);break; case SET7_C: M_SET(7,R->BC.B.l);break;
|
||||
case SET7_D: M_SET(7,R->DE.B.h);break; case SET7_E: M_SET(7,R->DE.B.l);break;
|
||||
case SET7_H: M_SET(7,R->HL.B.h);break; case SET7_L: M_SET(7,R->HL.B.l);break;
|
||||
case SET7_xHL: I=RdZ80(R->HL.W);M_SET(7,I);WrZ80(R->HL.W,I);break;
|
||||
case SET7_A: M_SET(7,R->AF.B.h);break;
|
||||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesCB.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the CB table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case RLC_B: M_RLC(R->BC.B.h);break; case RLC_C: M_RLC(R->BC.B.l);break;
|
||||
case RLC_D: M_RLC(R->DE.B.h);break; case RLC_E: M_RLC(R->DE.B.l);break;
|
||||
case RLC_H: M_RLC(R->HL.B.h);break; case RLC_L: M_RLC(R->HL.B.l);break;
|
||||
case RLC_xHL: I=RdZ80(R->HL.W);M_RLC(I);WrZ80(R->HL.W,I);break;
|
||||
case RLC_A: M_RLC(R->AF.B.h);break;
|
||||
|
||||
case RRC_B: M_RRC(R->BC.B.h);break; case RRC_C: M_RRC(R->BC.B.l);break;
|
||||
case RRC_D: M_RRC(R->DE.B.h);break; case RRC_E: M_RRC(R->DE.B.l);break;
|
||||
case RRC_H: M_RRC(R->HL.B.h);break; case RRC_L: M_RRC(R->HL.B.l);break;
|
||||
case RRC_xHL: I=RdZ80(R->HL.W);M_RRC(I);WrZ80(R->HL.W,I);break;
|
||||
case RRC_A: M_RRC(R->AF.B.h);break;
|
||||
|
||||
case RL_B: M_RL(R->BC.B.h);break; case RL_C: M_RL(R->BC.B.l);break;
|
||||
case RL_D: M_RL(R->DE.B.h);break; case RL_E: M_RL(R->DE.B.l);break;
|
||||
case RL_H: M_RL(R->HL.B.h);break; case RL_L: M_RL(R->HL.B.l);break;
|
||||
case RL_xHL: I=RdZ80(R->HL.W);M_RL(I);WrZ80(R->HL.W,I);break;
|
||||
case RL_A: M_RL(R->AF.B.h);break;
|
||||
|
||||
case RR_B: M_RR(R->BC.B.h);break; case RR_C: M_RR(R->BC.B.l);break;
|
||||
case RR_D: M_RR(R->DE.B.h);break; case RR_E: M_RR(R->DE.B.l);break;
|
||||
case RR_H: M_RR(R->HL.B.h);break; case RR_L: M_RR(R->HL.B.l);break;
|
||||
case RR_xHL: I=RdZ80(R->HL.W);M_RR(I);WrZ80(R->HL.W,I);break;
|
||||
case RR_A: M_RR(R->AF.B.h);break;
|
||||
|
||||
case SLA_B: M_SLA(R->BC.B.h);break; case SLA_C: M_SLA(R->BC.B.l);break;
|
||||
case SLA_D: M_SLA(R->DE.B.h);break; case SLA_E: M_SLA(R->DE.B.l);break;
|
||||
case SLA_H: M_SLA(R->HL.B.h);break; case SLA_L: M_SLA(R->HL.B.l);break;
|
||||
case SLA_xHL: I=RdZ80(R->HL.W);M_SLA(I);WrZ80(R->HL.W,I);break;
|
||||
case SLA_A: M_SLA(R->AF.B.h);break;
|
||||
|
||||
case SRA_B: M_SRA(R->BC.B.h);break; case SRA_C: M_SRA(R->BC.B.l);break;
|
||||
case SRA_D: M_SRA(R->DE.B.h);break; case SRA_E: M_SRA(R->DE.B.l);break;
|
||||
case SRA_H: M_SRA(R->HL.B.h);break; case SRA_L: M_SRA(R->HL.B.l);break;
|
||||
case SRA_xHL: I=RdZ80(R->HL.W);M_SRA(I);WrZ80(R->HL.W,I);break;
|
||||
case SRA_A: M_SRA(R->AF.B.h);break;
|
||||
|
||||
case SLL_B: M_SLL(R->BC.B.h);break; case SLL_C: M_SLL(R->BC.B.l);break;
|
||||
case SLL_D: M_SLL(R->DE.B.h);break; case SLL_E: M_SLL(R->DE.B.l);break;
|
||||
case SLL_H: M_SLL(R->HL.B.h);break; case SLL_L: M_SLL(R->HL.B.l);break;
|
||||
case SLL_xHL: I=RdZ80(R->HL.W);M_SLL(I);WrZ80(R->HL.W,I);break;
|
||||
case SLL_A: M_SLL(R->AF.B.h);break;
|
||||
|
||||
case SRL_B: M_SRL(R->BC.B.h);break; case SRL_C: M_SRL(R->BC.B.l);break;
|
||||
case SRL_D: M_SRL(R->DE.B.h);break; case SRL_E: M_SRL(R->DE.B.l);break;
|
||||
case SRL_H: M_SRL(R->HL.B.h);break; case SRL_L: M_SRL(R->HL.B.l);break;
|
||||
case SRL_xHL: I=RdZ80(R->HL.W);M_SRL(I);WrZ80(R->HL.W,I);break;
|
||||
case SRL_A: M_SRL(R->AF.B.h);break;
|
||||
|
||||
case BIT0_B: M_BIT(0,R->BC.B.h);break; case BIT0_C: M_BIT(0,R->BC.B.l);break;
|
||||
case BIT0_D: M_BIT(0,R->DE.B.h);break; case BIT0_E: M_BIT(0,R->DE.B.l);break;
|
||||
case BIT0_H: M_BIT(0,R->HL.B.h);break; case BIT0_L: M_BIT(0,R->HL.B.l);break;
|
||||
case BIT0_xHL: I=RdZ80(R->HL.W);M_BIT(0,I);break;
|
||||
case BIT0_A: M_BIT(0,R->AF.B.h);break;
|
||||
|
||||
case BIT1_B: M_BIT(1,R->BC.B.h);break; case BIT1_C: M_BIT(1,R->BC.B.l);break;
|
||||
case BIT1_D: M_BIT(1,R->DE.B.h);break; case BIT1_E: M_BIT(1,R->DE.B.l);break;
|
||||
case BIT1_H: M_BIT(1,R->HL.B.h);break; case BIT1_L: M_BIT(1,R->HL.B.l);break;
|
||||
case BIT1_xHL: I=RdZ80(R->HL.W);M_BIT(1,I);break;
|
||||
case BIT1_A: M_BIT(1,R->AF.B.h);break;
|
||||
|
||||
case BIT2_B: M_BIT(2,R->BC.B.h);break; case BIT2_C: M_BIT(2,R->BC.B.l);break;
|
||||
case BIT2_D: M_BIT(2,R->DE.B.h);break; case BIT2_E: M_BIT(2,R->DE.B.l);break;
|
||||
case BIT2_H: M_BIT(2,R->HL.B.h);break; case BIT2_L: M_BIT(2,R->HL.B.l);break;
|
||||
case BIT2_xHL: I=RdZ80(R->HL.W);M_BIT(2,I);break;
|
||||
case BIT2_A: M_BIT(2,R->AF.B.h);break;
|
||||
|
||||
case BIT3_B: M_BIT(3,R->BC.B.h);break; case BIT3_C: M_BIT(3,R->BC.B.l);break;
|
||||
case BIT3_D: M_BIT(3,R->DE.B.h);break; case BIT3_E: M_BIT(3,R->DE.B.l);break;
|
||||
case BIT3_H: M_BIT(3,R->HL.B.h);break; case BIT3_L: M_BIT(3,R->HL.B.l);break;
|
||||
case BIT3_xHL: I=RdZ80(R->HL.W);M_BIT(3,I);break;
|
||||
case BIT3_A: M_BIT(3,R->AF.B.h);break;
|
||||
|
||||
case BIT4_B: M_BIT(4,R->BC.B.h);break; case BIT4_C: M_BIT(4,R->BC.B.l);break;
|
||||
case BIT4_D: M_BIT(4,R->DE.B.h);break; case BIT4_E: M_BIT(4,R->DE.B.l);break;
|
||||
case BIT4_H: M_BIT(4,R->HL.B.h);break; case BIT4_L: M_BIT(4,R->HL.B.l);break;
|
||||
case BIT4_xHL: I=RdZ80(R->HL.W);M_BIT(4,I);break;
|
||||
case BIT4_A: M_BIT(4,R->AF.B.h);break;
|
||||
|
||||
case BIT5_B: M_BIT(5,R->BC.B.h);break; case BIT5_C: M_BIT(5,R->BC.B.l);break;
|
||||
case BIT5_D: M_BIT(5,R->DE.B.h);break; case BIT5_E: M_BIT(5,R->DE.B.l);break;
|
||||
case BIT5_H: M_BIT(5,R->HL.B.h);break; case BIT5_L: M_BIT(5,R->HL.B.l);break;
|
||||
case BIT5_xHL: I=RdZ80(R->HL.W);M_BIT(5,I);break;
|
||||
case BIT5_A: M_BIT(5,R->AF.B.h);break;
|
||||
|
||||
case BIT6_B: M_BIT(6,R->BC.B.h);break; case BIT6_C: M_BIT(6,R->BC.B.l);break;
|
||||
case BIT6_D: M_BIT(6,R->DE.B.h);break; case BIT6_E: M_BIT(6,R->DE.B.l);break;
|
||||
case BIT6_H: M_BIT(6,R->HL.B.h);break; case BIT6_L: M_BIT(6,R->HL.B.l);break;
|
||||
case BIT6_xHL: I=RdZ80(R->HL.W);M_BIT(6,I);break;
|
||||
case BIT6_A: M_BIT(6,R->AF.B.h);break;
|
||||
|
||||
case BIT7_B: M_BIT(7,R->BC.B.h);break; case BIT7_C: M_BIT(7,R->BC.B.l);break;
|
||||
case BIT7_D: M_BIT(7,R->DE.B.h);break; case BIT7_E: M_BIT(7,R->DE.B.l);break;
|
||||
case BIT7_H: M_BIT(7,R->HL.B.h);break; case BIT7_L: M_BIT(7,R->HL.B.l);break;
|
||||
case BIT7_xHL: I=RdZ80(R->HL.W);M_BIT(7,I);break;
|
||||
case BIT7_A: M_BIT(7,R->AF.B.h);break;
|
||||
|
||||
case RES0_B: M_RES(0,R->BC.B.h);break; case RES0_C: M_RES(0,R->BC.B.l);break;
|
||||
case RES0_D: M_RES(0,R->DE.B.h);break; case RES0_E: M_RES(0,R->DE.B.l);break;
|
||||
case RES0_H: M_RES(0,R->HL.B.h);break; case RES0_L: M_RES(0,R->HL.B.l);break;
|
||||
case RES0_xHL: I=RdZ80(R->HL.W);M_RES(0,I);WrZ80(R->HL.W,I);break;
|
||||
case RES0_A: M_RES(0,R->AF.B.h);break;
|
||||
|
||||
case RES1_B: M_RES(1,R->BC.B.h);break; case RES1_C: M_RES(1,R->BC.B.l);break;
|
||||
case RES1_D: M_RES(1,R->DE.B.h);break; case RES1_E: M_RES(1,R->DE.B.l);break;
|
||||
case RES1_H: M_RES(1,R->HL.B.h);break; case RES1_L: M_RES(1,R->HL.B.l);break;
|
||||
case RES1_xHL: I=RdZ80(R->HL.W);M_RES(1,I);WrZ80(R->HL.W,I);break;
|
||||
case RES1_A: M_RES(1,R->AF.B.h);break;
|
||||
|
||||
case RES2_B: M_RES(2,R->BC.B.h);break; case RES2_C: M_RES(2,R->BC.B.l);break;
|
||||
case RES2_D: M_RES(2,R->DE.B.h);break; case RES2_E: M_RES(2,R->DE.B.l);break;
|
||||
case RES2_H: M_RES(2,R->HL.B.h);break; case RES2_L: M_RES(2,R->HL.B.l);break;
|
||||
case RES2_xHL: I=RdZ80(R->HL.W);M_RES(2,I);WrZ80(R->HL.W,I);break;
|
||||
case RES2_A: M_RES(2,R->AF.B.h);break;
|
||||
|
||||
case RES3_B: M_RES(3,R->BC.B.h);break; case RES3_C: M_RES(3,R->BC.B.l);break;
|
||||
case RES3_D: M_RES(3,R->DE.B.h);break; case RES3_E: M_RES(3,R->DE.B.l);break;
|
||||
case RES3_H: M_RES(3,R->HL.B.h);break; case RES3_L: M_RES(3,R->HL.B.l);break;
|
||||
case RES3_xHL: I=RdZ80(R->HL.W);M_RES(3,I);WrZ80(R->HL.W,I);break;
|
||||
case RES3_A: M_RES(3,R->AF.B.h);break;
|
||||
|
||||
case RES4_B: M_RES(4,R->BC.B.h);break; case RES4_C: M_RES(4,R->BC.B.l);break;
|
||||
case RES4_D: M_RES(4,R->DE.B.h);break; case RES4_E: M_RES(4,R->DE.B.l);break;
|
||||
case RES4_H: M_RES(4,R->HL.B.h);break; case RES4_L: M_RES(4,R->HL.B.l);break;
|
||||
case RES4_xHL: I=RdZ80(R->HL.W);M_RES(4,I);WrZ80(R->HL.W,I);break;
|
||||
case RES4_A: M_RES(4,R->AF.B.h);break;
|
||||
|
||||
case RES5_B: M_RES(5,R->BC.B.h);break; case RES5_C: M_RES(5,R->BC.B.l);break;
|
||||
case RES5_D: M_RES(5,R->DE.B.h);break; case RES5_E: M_RES(5,R->DE.B.l);break;
|
||||
case RES5_H: M_RES(5,R->HL.B.h);break; case RES5_L: M_RES(5,R->HL.B.l);break;
|
||||
case RES5_xHL: I=RdZ80(R->HL.W);M_RES(5,I);WrZ80(R->HL.W,I);break;
|
||||
case RES5_A: M_RES(5,R->AF.B.h);break;
|
||||
|
||||
case RES6_B: M_RES(6,R->BC.B.h);break; case RES6_C: M_RES(6,R->BC.B.l);break;
|
||||
case RES6_D: M_RES(6,R->DE.B.h);break; case RES6_E: M_RES(6,R->DE.B.l);break;
|
||||
case RES6_H: M_RES(6,R->HL.B.h);break; case RES6_L: M_RES(6,R->HL.B.l);break;
|
||||
case RES6_xHL: I=RdZ80(R->HL.W);M_RES(6,I);WrZ80(R->HL.W,I);break;
|
||||
case RES6_A: M_RES(6,R->AF.B.h);break;
|
||||
|
||||
case RES7_B: M_RES(7,R->BC.B.h);break; case RES7_C: M_RES(7,R->BC.B.l);break;
|
||||
case RES7_D: M_RES(7,R->DE.B.h);break; case RES7_E: M_RES(7,R->DE.B.l);break;
|
||||
case RES7_H: M_RES(7,R->HL.B.h);break; case RES7_L: M_RES(7,R->HL.B.l);break;
|
||||
case RES7_xHL: I=RdZ80(R->HL.W);M_RES(7,I);WrZ80(R->HL.W,I);break;
|
||||
case RES7_A: M_RES(7,R->AF.B.h);break;
|
||||
|
||||
case SET0_B: M_SET(0,R->BC.B.h);break; case SET0_C: M_SET(0,R->BC.B.l);break;
|
||||
case SET0_D: M_SET(0,R->DE.B.h);break; case SET0_E: M_SET(0,R->DE.B.l);break;
|
||||
case SET0_H: M_SET(0,R->HL.B.h);break; case SET0_L: M_SET(0,R->HL.B.l);break;
|
||||
case SET0_xHL: I=RdZ80(R->HL.W);M_SET(0,I);WrZ80(R->HL.W,I);break;
|
||||
case SET0_A: M_SET(0,R->AF.B.h);break;
|
||||
|
||||
case SET1_B: M_SET(1,R->BC.B.h);break; case SET1_C: M_SET(1,R->BC.B.l);break;
|
||||
case SET1_D: M_SET(1,R->DE.B.h);break; case SET1_E: M_SET(1,R->DE.B.l);break;
|
||||
case SET1_H: M_SET(1,R->HL.B.h);break; case SET1_L: M_SET(1,R->HL.B.l);break;
|
||||
case SET1_xHL: I=RdZ80(R->HL.W);M_SET(1,I);WrZ80(R->HL.W,I);break;
|
||||
case SET1_A: M_SET(1,R->AF.B.h);break;
|
||||
|
||||
case SET2_B: M_SET(2,R->BC.B.h);break; case SET2_C: M_SET(2,R->BC.B.l);break;
|
||||
case SET2_D: M_SET(2,R->DE.B.h);break; case SET2_E: M_SET(2,R->DE.B.l);break;
|
||||
case SET2_H: M_SET(2,R->HL.B.h);break; case SET2_L: M_SET(2,R->HL.B.l);break;
|
||||
case SET2_xHL: I=RdZ80(R->HL.W);M_SET(2,I);WrZ80(R->HL.W,I);break;
|
||||
case SET2_A: M_SET(2,R->AF.B.h);break;
|
||||
|
||||
case SET3_B: M_SET(3,R->BC.B.h);break; case SET3_C: M_SET(3,R->BC.B.l);break;
|
||||
case SET3_D: M_SET(3,R->DE.B.h);break; case SET3_E: M_SET(3,R->DE.B.l);break;
|
||||
case SET3_H: M_SET(3,R->HL.B.h);break; case SET3_L: M_SET(3,R->HL.B.l);break;
|
||||
case SET3_xHL: I=RdZ80(R->HL.W);M_SET(3,I);WrZ80(R->HL.W,I);break;
|
||||
case SET3_A: M_SET(3,R->AF.B.h);break;
|
||||
|
||||
case SET4_B: M_SET(4,R->BC.B.h);break; case SET4_C: M_SET(4,R->BC.B.l);break;
|
||||
case SET4_D: M_SET(4,R->DE.B.h);break; case SET4_E: M_SET(4,R->DE.B.l);break;
|
||||
case SET4_H: M_SET(4,R->HL.B.h);break; case SET4_L: M_SET(4,R->HL.B.l);break;
|
||||
case SET4_xHL: I=RdZ80(R->HL.W);M_SET(4,I);WrZ80(R->HL.W,I);break;
|
||||
case SET4_A: M_SET(4,R->AF.B.h);break;
|
||||
|
||||
case SET5_B: M_SET(5,R->BC.B.h);break; case SET5_C: M_SET(5,R->BC.B.l);break;
|
||||
case SET5_D: M_SET(5,R->DE.B.h);break; case SET5_E: M_SET(5,R->DE.B.l);break;
|
||||
case SET5_H: M_SET(5,R->HL.B.h);break; case SET5_L: M_SET(5,R->HL.B.l);break;
|
||||
case SET5_xHL: I=RdZ80(R->HL.W);M_SET(5,I);WrZ80(R->HL.W,I);break;
|
||||
case SET5_A: M_SET(5,R->AF.B.h);break;
|
||||
|
||||
case SET6_B: M_SET(6,R->BC.B.h);break; case SET6_C: M_SET(6,R->BC.B.l);break;
|
||||
case SET6_D: M_SET(6,R->DE.B.h);break; case SET6_E: M_SET(6,R->DE.B.l);break;
|
||||
case SET6_H: M_SET(6,R->HL.B.h);break; case SET6_L: M_SET(6,R->HL.B.l);break;
|
||||
case SET6_xHL: I=RdZ80(R->HL.W);M_SET(6,I);WrZ80(R->HL.W,I);break;
|
||||
case SET6_A: M_SET(6,R->AF.B.h);break;
|
||||
|
||||
case SET7_B: M_SET(7,R->BC.B.h);break; case SET7_C: M_SET(7,R->BC.B.l);break;
|
||||
case SET7_D: M_SET(7,R->DE.B.h);break; case SET7_E: M_SET(7,R->DE.B.l);break;
|
||||
case SET7_H: M_SET(7,R->HL.B.h);break; case SET7_L: M_SET(7,R->HL.B.l);break;
|
||||
case SET7_xHL: I=RdZ80(R->HL.W);M_SET(7,I);WrZ80(R->HL.W,I);break;
|
||||
case SET7_A: M_SET(7,R->AF.B.h);break;
|
||||
|
|
|
|||
|
|
@ -1,282 +1,304 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesED.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the ED table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
/** This is a special patch for emulating BIOS calls: ********/
|
||||
case DB_FE: PatchZ80(R);break;
|
||||
/*************************************************************/
|
||||
|
||||
case ADC_HL_BC: M_ADCW(BC);break;
|
||||
case ADC_HL_DE: M_ADCW(DE);break;
|
||||
case ADC_HL_HL: M_ADCW(HL);break;
|
||||
case ADC_HL_SP: M_ADCW(SP);break;
|
||||
|
||||
case SBC_HL_BC: M_SBCW(BC);break;
|
||||
case SBC_HL_DE: M_SBCW(DE);break;
|
||||
case SBC_HL_HL: M_SBCW(HL);break;
|
||||
case SBC_HL_SP: M_SBCW(SP);break;
|
||||
|
||||
case LD_xWORDe_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->HL.B.l);
|
||||
WrZ80(J.W,R->HL.B.h);
|
||||
break;
|
||||
case LD_xWORDe_DE:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->DE.B.l);
|
||||
WrZ80(J.W,R->DE.B.h);
|
||||
break;
|
||||
case LD_xWORDe_BC:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->BC.B.l);
|
||||
WrZ80(J.W,R->BC.B.h);
|
||||
break;
|
||||
case LD_xWORDe_SP:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->SP.B.l);
|
||||
WrZ80(J.W,R->SP.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->HL.B.l=RdZ80(J.W++);
|
||||
R->HL.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_DE_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->DE.B.l=RdZ80(J.W++);
|
||||
R->DE.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_BC_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->BC.B.l=RdZ80(J.W++);
|
||||
R->BC.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_SP_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->SP.B.l=RdZ80(J.W++);
|
||||
R->SP.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case RRD:
|
||||
I=RdZ80(R->HL.W);
|
||||
J.B.l=(I>>4)|(R->AF.B.h<<4);
|
||||
WrZ80(R->HL.W,J.B.l);
|
||||
R->AF.B.h=(I&0x0F)|(R->AF.B.h&0xF0);
|
||||
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG);
|
||||
break;
|
||||
case RLD:
|
||||
I=RdZ80(R->HL.W);
|
||||
J.B.l=(I<<4)|(R->AF.B.h&0x0F);
|
||||
WrZ80(R->HL.W,J.B.l);
|
||||
R->AF.B.h=(I>>4)|(R->AF.B.h&0xF0);
|
||||
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG);
|
||||
break;
|
||||
|
||||
case LD_A_I:
|
||||
R->AF.B.h=R->I;
|
||||
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&1? P_FLAG:0)|ZSTable[R->AF.B.h];
|
||||
break;
|
||||
|
||||
case LD_A_R:
|
||||
R->R++;
|
||||
R->AF.B.h=(byte)(R->R-R->ICount);
|
||||
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&1? P_FLAG:0)|ZSTable[R->AF.B.h];
|
||||
break;
|
||||
|
||||
case LD_I_A: R->I=R->AF.B.h;break;
|
||||
case LD_R_A: break;
|
||||
|
||||
case IM_0: R->IFF&=0xF9;break;
|
||||
case IM_1: R->IFF=(R->IFF&0xF9)|2;break;
|
||||
case IM_2: R->IFF=(R->IFF&0xF9)|4;break;
|
||||
|
||||
case RETI: M_RET;break;
|
||||
case RETN: if(R->IFF&0x40) R->IFF|=0x01; else R->IFF&=0xFE;
|
||||
M_RET;break;
|
||||
|
||||
case NEG: I=R->AF.B.h;R->AF.B.h=0;M_SUB(I);break;
|
||||
|
||||
case IN_B_xC: M_IN(R->BC.B.h);break;
|
||||
case IN_C_xC: M_IN(R->BC.B.l);break;
|
||||
case IN_D_xC: M_IN(R->DE.B.h);break;
|
||||
case IN_E_xC: M_IN(R->DE.B.l);break;
|
||||
case IN_H_xC: M_IN(R->HL.B.h);break;
|
||||
case IN_L_xC: M_IN(R->HL.B.l);break;
|
||||
case IN_A_xC: M_IN(R->AF.B.h);break;
|
||||
case IN_F_xC: M_IN(J.B.l);break;
|
||||
|
||||
case OUT_xC_B: OutZ80(R->BC.B.l,R->BC.B.h);break;
|
||||
case OUT_xC_C: OutZ80(R->BC.B.l,R->BC.B.l);break;
|
||||
case OUT_xC_D: OutZ80(R->BC.B.l,R->DE.B.h);break;
|
||||
case OUT_xC_E: OutZ80(R->BC.B.l,R->DE.B.l);break;
|
||||
case OUT_xC_H: OutZ80(R->BC.B.l,R->HL.B.h);break;
|
||||
case OUT_xC_L: OutZ80(R->BC.B.l,R->HL.B.l);break;
|
||||
case OUT_xC_A: OutZ80(R->BC.B.l,R->AF.B.h);break;
|
||||
|
||||
case INI:
|
||||
WrZ80(R->HL.W++,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case INIR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->HL.W++,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case IND:
|
||||
WrZ80(R->HL.W--,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case INDR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->HL.W--,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case OUTI:
|
||||
OutZ80(R->BC.B.l,RdZ80(R->HL.W++));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case OTIR:
|
||||
do
|
||||
{
|
||||
OutZ80(R->BC.B.l,RdZ80(R->HL.W++));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case OUTD:
|
||||
OutZ80(R->BC.B.l,RdZ80(R->HL.W--));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case OTDR:
|
||||
do
|
||||
{
|
||||
OutZ80(R->BC.B.l,RdZ80(R->HL.W--));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case LDI:
|
||||
WrZ80(R->DE.W++,RdZ80(R->HL.W++));
|
||||
R->BC.W--;
|
||||
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case LDIR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->DE.W++,RdZ80(R->HL.W++));
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&(R->ICount>0));
|
||||
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG);
|
||||
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; }
|
||||
else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case LDD:
|
||||
WrZ80(R->DE.W--,RdZ80(R->HL.W--));
|
||||
R->BC.W--;
|
||||
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case LDDR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->DE.W--,RdZ80(R->HL.W--));
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&(R->ICount>0));
|
||||
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG);
|
||||
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; }
|
||||
else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case CPI:
|
||||
I=RdZ80(R->HL.W++);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case CPIR:
|
||||
do
|
||||
{
|
||||
I=RdZ80(R->HL.W++);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&J.B.l&&(R->ICount>0));
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case CPD:
|
||||
I=RdZ80(R->HL.W--);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case CPDR:
|
||||
do
|
||||
{
|
||||
I=RdZ80(R->HL.W--);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&J.B.l);
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5;
|
||||
break;
|
||||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesED.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for the ED table of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
/** This is a special patch for emulating BIOS calls: ********/
|
||||
case DB_FE: PatchZ80(R);break;
|
||||
/*************************************************************/
|
||||
|
||||
case ADC_HL_BC: M_ADCW(BC);break;
|
||||
case ADC_HL_DE: M_ADCW(DE);break;
|
||||
case ADC_HL_HL: M_ADCW(HL);break;
|
||||
case ADC_HL_SP: M_ADCW(SP);break;
|
||||
|
||||
case SBC_HL_BC: M_SBCW(BC);break;
|
||||
case SBC_HL_DE: M_SBCW(DE);break;
|
||||
case SBC_HL_HL: M_SBCW(HL);break;
|
||||
case SBC_HL_SP: M_SBCW(SP);break;
|
||||
|
||||
case LD_xWORDe_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->HL.B.l);
|
||||
WrZ80(J.W,R->HL.B.h);
|
||||
break;
|
||||
case LD_xWORDe_DE:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->DE.B.l);
|
||||
WrZ80(J.W,R->DE.B.h);
|
||||
break;
|
||||
case LD_xWORDe_BC:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->BC.B.l);
|
||||
WrZ80(J.W,R->BC.B.h);
|
||||
break;
|
||||
case LD_xWORDe_SP:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->SP.B.l);
|
||||
WrZ80(J.W,R->SP.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->HL.B.l=RdZ80(J.W++);
|
||||
R->HL.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_DE_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->DE.B.l=RdZ80(J.W++);
|
||||
R->DE.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_BC_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->BC.B.l=RdZ80(J.W++);
|
||||
R->BC.B.h=RdZ80(J.W);
|
||||
break;
|
||||
case LD_SP_xWORDe:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->SP.B.l=RdZ80(J.W++);
|
||||
R->SP.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case RRD:
|
||||
I=RdZ80(R->HL.W);
|
||||
J.B.l=(I>>4)|(R->AF.B.h<<4);
|
||||
WrZ80(R->HL.W,J.B.l);
|
||||
R->AF.B.h=(I&0x0F)|(R->AF.B.h&0xF0);
|
||||
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG);
|
||||
break;
|
||||
case RLD:
|
||||
I=RdZ80(R->HL.W);
|
||||
J.B.l=(I<<4)|(R->AF.B.h&0x0F);
|
||||
WrZ80(R->HL.W,J.B.l);
|
||||
R->AF.B.h=(I>>4)|(R->AF.B.h&0xF0);
|
||||
R->AF.B.l=PZSTable[R->AF.B.h]|(R->AF.B.l&C_FLAG);
|
||||
break;
|
||||
|
||||
case LD_A_I:
|
||||
R->AF.B.h=R->I;
|
||||
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&IFF_2? P_FLAG:0)|ZSTable[R->AF.B.h];
|
||||
break;
|
||||
|
||||
case LD_A_R:
|
||||
R->R++;
|
||||
R->AF.B.h=(byte)(R->R-R->ICount);
|
||||
R->AF.B.l=(R->AF.B.l&C_FLAG)|(R->IFF&IFF_2? P_FLAG:0)|ZSTable[R->AF.B.h];
|
||||
break;
|
||||
|
||||
case LD_I_A: R->I=R->AF.B.h;break;
|
||||
case LD_R_A: break;
|
||||
|
||||
case IM_0: R->IFF&=~(IFF_IM1|IFF_IM2);break;
|
||||
case IM_1: R->IFF=(R->IFF&~IFF_IM2)|IFF_IM1;break;
|
||||
case IM_2: R->IFF=(R->IFF&~IFF_IM1)|IFF_IM2;break;
|
||||
|
||||
case RETI: M_RET;break;
|
||||
case RETN: if(R->IFF&IFF_2) R->IFF|=IFF_1; else R->IFF&=~IFF_1;
|
||||
M_RET;break;
|
||||
|
||||
case NEG: I=R->AF.B.h;R->AF.B.h=0;M_SUB(I);break;
|
||||
|
||||
case IN_B_xC: M_IN(R->BC.B.h);break;
|
||||
case IN_C_xC: M_IN(R->BC.B.l);break;
|
||||
case IN_D_xC: M_IN(R->DE.B.h);break;
|
||||
case IN_E_xC: M_IN(R->DE.B.l);break;
|
||||
case IN_H_xC: M_IN(R->HL.B.h);break;
|
||||
case IN_L_xC: M_IN(R->HL.B.l);break;
|
||||
case IN_A_xC: M_IN(R->AF.B.h);break;
|
||||
case IN_F_xC: M_IN(J.B.l);break;
|
||||
|
||||
case OUT_xC_B: OutZ80(R->BC.B.l,R->BC.B.h);break;
|
||||
case OUT_xC_C: OutZ80(R->BC.B.l,R->BC.B.l);break;
|
||||
case OUT_xC_D: OutZ80(R->BC.B.l,R->DE.B.h);break;
|
||||
case OUT_xC_E: OutZ80(R->BC.B.l,R->DE.B.l);break;
|
||||
case OUT_xC_H: OutZ80(R->BC.B.l,R->HL.B.h);break;
|
||||
case OUT_xC_L: OutZ80(R->BC.B.l,R->HL.B.l);break;
|
||||
case OUT_xC_A: OutZ80(R->BC.B.l,R->AF.B.h);break;
|
||||
|
||||
case INI:
|
||||
WrZ80(R->HL.W++,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case INIR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->HL.W++,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case IND:
|
||||
WrZ80(R->HL.W--,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG);
|
||||
break;
|
||||
|
||||
case INDR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->HL.W--,InZ80(R->BC.B.l));
|
||||
R->BC.B.h--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h) { R->AF.B.l=N_FLAG;R->PC.W-=2; }
|
||||
else { R->AF.B.l=Z_FLAG|N_FLAG;R->ICount+=5; }
|
||||
break;
|
||||
|
||||
case OUTI:
|
||||
I=RdZ80(R->HL.W++);
|
||||
OutZ80(R->BC.B.l,I);
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG)|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0);
|
||||
break;
|
||||
|
||||
case OTIR:
|
||||
do
|
||||
{
|
||||
I=RdZ80(R->HL.W++);
|
||||
OutZ80(R->BC.B.l,I);
|
||||
R->BC.B.h--;
|
||||
R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h)
|
||||
{
|
||||
R->AF.B.l=N_FLAG|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0);
|
||||
R->PC.W-=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
R->AF.B.l=Z_FLAG|N_FLAG|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0);
|
||||
R->ICount+=5;
|
||||
}
|
||||
break;
|
||||
|
||||
case OUTD:
|
||||
I=RdZ80(R->HL.W--);
|
||||
OutZ80(R->BC.B.l,I);
|
||||
R->BC.B.h--;
|
||||
R->AF.B.l=N_FLAG|(R->BC.B.h? 0:Z_FLAG)|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0);
|
||||
break;
|
||||
|
||||
case OTDR:
|
||||
do
|
||||
{
|
||||
I=RdZ80(R->HL.W--);
|
||||
OutZ80(R->BC.B.l,I);
|
||||
R->BC.B.h--;
|
||||
R->ICount-=21;
|
||||
}
|
||||
while(R->BC.B.h&&(R->ICount>0));
|
||||
if(R->BC.B.h)
|
||||
{
|
||||
R->AF.B.l=N_FLAG|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0);
|
||||
R->PC.W-=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
R->AF.B.l=Z_FLAG|N_FLAG|(R->HL.B.l+I>255? (C_FLAG|H_FLAG):0);
|
||||
R->ICount+=5;
|
||||
}
|
||||
break;
|
||||
|
||||
case LDI:
|
||||
WrZ80(R->DE.W++,RdZ80(R->HL.W++));
|
||||
R->BC.W--;
|
||||
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case LDIR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->DE.W++,RdZ80(R->HL.W++));
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&(R->ICount>0));
|
||||
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG);
|
||||
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; }
|
||||
else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case LDD:
|
||||
WrZ80(R->DE.W--,RdZ80(R->HL.W--));
|
||||
R->BC.W--;
|
||||
R->AF.B.l=(R->AF.B.l&~(N_FLAG|H_FLAG|P_FLAG))|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case LDDR:
|
||||
do
|
||||
{
|
||||
WrZ80(R->DE.W--,RdZ80(R->HL.W--));
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&(R->ICount>0));
|
||||
R->AF.B.l&=~(N_FLAG|H_FLAG|P_FLAG);
|
||||
if(R->BC.W) { R->AF.B.l|=N_FLAG;R->PC.W-=2; }
|
||||
else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case CPI:
|
||||
I=RdZ80(R->HL.W++);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case CPIR:
|
||||
do
|
||||
{
|
||||
I=RdZ80(R->HL.W++);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&J.B.l&&(R->ICount>0));
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5;
|
||||
break;
|
||||
|
||||
case CPD:
|
||||
I=RdZ80(R->HL.W--);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
break;
|
||||
|
||||
case CPDR:
|
||||
do
|
||||
{
|
||||
I=RdZ80(R->HL.W--);
|
||||
J.B.l=R->AF.B.h-I;
|
||||
R->BC.W--;R->ICount-=21;
|
||||
}
|
||||
while(R->BC.W&&J.B.l);
|
||||
R->AF.B.l =
|
||||
N_FLAG|(R->AF.B.l&C_FLAG)|ZSTable[J.B.l]|
|
||||
((R->AF.B.h^I^J.B.l)&H_FLAG)|(R->BC.W? P_FLAG:0);
|
||||
if(R->BC.W&&J.B.l) R->PC.W-=2; else R->ICount+=5;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,64 +1,64 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesXCB.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for FD/DD-CB tables **/
|
||||
/** of Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case RLC_xHL: I=RdZ80(J.W);M_RLC(I);WrZ80(J.W,I);break;
|
||||
case RRC_xHL: I=RdZ80(J.W);M_RRC(I);WrZ80(J.W,I);break;
|
||||
case RL_xHL: I=RdZ80(J.W);M_RL(I);WrZ80(J.W,I);break;
|
||||
case RR_xHL: I=RdZ80(J.W);M_RR(I);WrZ80(J.W,I);break;
|
||||
case SLA_xHL: I=RdZ80(J.W);M_SLA(I);WrZ80(J.W,I);break;
|
||||
case SRA_xHL: I=RdZ80(J.W);M_SRA(I);WrZ80(J.W,I);break;
|
||||
case SLL_xHL: I=RdZ80(J.W);M_SLL(I);WrZ80(J.W,I);break;
|
||||
case SRL_xHL: I=RdZ80(J.W);M_SRL(I);WrZ80(J.W,I);break;
|
||||
|
||||
case BIT0_B: case BIT0_C: case BIT0_D: case BIT0_E:
|
||||
case BIT0_H: case BIT0_L: case BIT0_A:
|
||||
case BIT0_xHL: I=RdZ80(J.W);M_BIT(0,I);break;
|
||||
case BIT1_B: case BIT1_C: case BIT1_D: case BIT1_E:
|
||||
case BIT1_H: case BIT1_L: case BIT1_A:
|
||||
case BIT1_xHL: I=RdZ80(J.W);M_BIT(1,I);break;
|
||||
case BIT2_B: case BIT2_C: case BIT2_D: case BIT2_E:
|
||||
case BIT2_H: case BIT2_L: case BIT2_A:
|
||||
case BIT2_xHL: I=RdZ80(J.W);M_BIT(2,I);break;
|
||||
case BIT3_B: case BIT3_C: case BIT3_D: case BIT3_E:
|
||||
case BIT3_H: case BIT3_L: case BIT3_A:
|
||||
case BIT3_xHL: I=RdZ80(J.W);M_BIT(3,I);break;
|
||||
case BIT4_B: case BIT4_C: case BIT4_D: case BIT4_E:
|
||||
case BIT4_H: case BIT4_L: case BIT4_A:
|
||||
case BIT4_xHL: I=RdZ80(J.W);M_BIT(4,I);break;
|
||||
case BIT5_B: case BIT5_C: case BIT5_D: case BIT5_E:
|
||||
case BIT5_H: case BIT5_L: case BIT5_A:
|
||||
case BIT5_xHL: I=RdZ80(J.W);M_BIT(5,I);break;
|
||||
case BIT6_B: case BIT6_C: case BIT6_D: case BIT6_E:
|
||||
case BIT6_H: case BIT6_L: case BIT6_A:
|
||||
case BIT6_xHL: I=RdZ80(J.W);M_BIT(6,I);break;
|
||||
case BIT7_B: case BIT7_C: case BIT7_D: case BIT7_E:
|
||||
case BIT7_H: case BIT7_L: case BIT7_A:
|
||||
case BIT7_xHL: I=RdZ80(J.W);M_BIT(7,I);break;
|
||||
|
||||
case RES0_xHL: I=RdZ80(J.W);M_RES(0,I);WrZ80(J.W,I);break;
|
||||
case RES1_xHL: I=RdZ80(J.W);M_RES(1,I);WrZ80(J.W,I);break;
|
||||
case RES2_xHL: I=RdZ80(J.W);M_RES(2,I);WrZ80(J.W,I);break;
|
||||
case RES3_xHL: I=RdZ80(J.W);M_RES(3,I);WrZ80(J.W,I);break;
|
||||
case RES4_xHL: I=RdZ80(J.W);M_RES(4,I);WrZ80(J.W,I);break;
|
||||
case RES5_xHL: I=RdZ80(J.W);M_RES(5,I);WrZ80(J.W,I);break;
|
||||
case RES6_xHL: I=RdZ80(J.W);M_RES(6,I);WrZ80(J.W,I);break;
|
||||
case RES7_xHL: I=RdZ80(J.W);M_RES(7,I);WrZ80(J.W,I);break;
|
||||
|
||||
case SET0_xHL: I=RdZ80(J.W);M_SET(0,I);WrZ80(J.W,I);break;
|
||||
case SET1_xHL: I=RdZ80(J.W);M_SET(1,I);WrZ80(J.W,I);break;
|
||||
case SET2_xHL: I=RdZ80(J.W);M_SET(2,I);WrZ80(J.W,I);break;
|
||||
case SET3_xHL: I=RdZ80(J.W);M_SET(3,I);WrZ80(J.W,I);break;
|
||||
case SET4_xHL: I=RdZ80(J.W);M_SET(4,I);WrZ80(J.W,I);break;
|
||||
case SET5_xHL: I=RdZ80(J.W);M_SET(5,I);WrZ80(J.W,I);break;
|
||||
case SET6_xHL: I=RdZ80(J.W);M_SET(6,I);WrZ80(J.W,I);break;
|
||||
case SET7_xHL: I=RdZ80(J.W);M_SET(7,I);WrZ80(J.W,I);break;
|
||||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesXCB.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for FD/DD-CB tables **/
|
||||
/** of Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case RLC_xHL: I=RdZ80(J.W);M_RLC(I);WrZ80(J.W,I);break;
|
||||
case RRC_xHL: I=RdZ80(J.W);M_RRC(I);WrZ80(J.W,I);break;
|
||||
case RL_xHL: I=RdZ80(J.W);M_RL(I);WrZ80(J.W,I);break;
|
||||
case RR_xHL: I=RdZ80(J.W);M_RR(I);WrZ80(J.W,I);break;
|
||||
case SLA_xHL: I=RdZ80(J.W);M_SLA(I);WrZ80(J.W,I);break;
|
||||
case SRA_xHL: I=RdZ80(J.W);M_SRA(I);WrZ80(J.W,I);break;
|
||||
case SLL_xHL: I=RdZ80(J.W);M_SLL(I);WrZ80(J.W,I);break;
|
||||
case SRL_xHL: I=RdZ80(J.W);M_SRL(I);WrZ80(J.W,I);break;
|
||||
|
||||
case BIT0_B: case BIT0_C: case BIT0_D: case BIT0_E:
|
||||
case BIT0_H: case BIT0_L: case BIT0_A:
|
||||
case BIT0_xHL: I=RdZ80(J.W);M_BIT(0,I);break;
|
||||
case BIT1_B: case BIT1_C: case BIT1_D: case BIT1_E:
|
||||
case BIT1_H: case BIT1_L: case BIT1_A:
|
||||
case BIT1_xHL: I=RdZ80(J.W);M_BIT(1,I);break;
|
||||
case BIT2_B: case BIT2_C: case BIT2_D: case BIT2_E:
|
||||
case BIT2_H: case BIT2_L: case BIT2_A:
|
||||
case BIT2_xHL: I=RdZ80(J.W);M_BIT(2,I);break;
|
||||
case BIT3_B: case BIT3_C: case BIT3_D: case BIT3_E:
|
||||
case BIT3_H: case BIT3_L: case BIT3_A:
|
||||
case BIT3_xHL: I=RdZ80(J.W);M_BIT(3,I);break;
|
||||
case BIT4_B: case BIT4_C: case BIT4_D: case BIT4_E:
|
||||
case BIT4_H: case BIT4_L: case BIT4_A:
|
||||
case BIT4_xHL: I=RdZ80(J.W);M_BIT(4,I);break;
|
||||
case BIT5_B: case BIT5_C: case BIT5_D: case BIT5_E:
|
||||
case BIT5_H: case BIT5_L: case BIT5_A:
|
||||
case BIT5_xHL: I=RdZ80(J.W);M_BIT(5,I);break;
|
||||
case BIT6_B: case BIT6_C: case BIT6_D: case BIT6_E:
|
||||
case BIT6_H: case BIT6_L: case BIT6_A:
|
||||
case BIT6_xHL: I=RdZ80(J.W);M_BIT(6,I);break;
|
||||
case BIT7_B: case BIT7_C: case BIT7_D: case BIT7_E:
|
||||
case BIT7_H: case BIT7_L: case BIT7_A:
|
||||
case BIT7_xHL: I=RdZ80(J.W);M_BIT(7,I);break;
|
||||
|
||||
case RES0_xHL: I=RdZ80(J.W);M_RES(0,I);WrZ80(J.W,I);break;
|
||||
case RES1_xHL: I=RdZ80(J.W);M_RES(1,I);WrZ80(J.W,I);break;
|
||||
case RES2_xHL: I=RdZ80(J.W);M_RES(2,I);WrZ80(J.W,I);break;
|
||||
case RES3_xHL: I=RdZ80(J.W);M_RES(3,I);WrZ80(J.W,I);break;
|
||||
case RES4_xHL: I=RdZ80(J.W);M_RES(4,I);WrZ80(J.W,I);break;
|
||||
case RES5_xHL: I=RdZ80(J.W);M_RES(5,I);WrZ80(J.W,I);break;
|
||||
case RES6_xHL: I=RdZ80(J.W);M_RES(6,I);WrZ80(J.W,I);break;
|
||||
case RES7_xHL: I=RdZ80(J.W);M_RES(7,I);WrZ80(J.W,I);break;
|
||||
|
||||
case SET0_xHL: I=RdZ80(J.W);M_SET(0,I);WrZ80(J.W,I);break;
|
||||
case SET1_xHL: I=RdZ80(J.W);M_SET(1,I);WrZ80(J.W,I);break;
|
||||
case SET2_xHL: I=RdZ80(J.W);M_SET(2,I);WrZ80(J.W,I);break;
|
||||
case SET3_xHL: I=RdZ80(J.W);M_SET(3,I);WrZ80(J.W,I);break;
|
||||
case SET4_xHL: I=RdZ80(J.W);M_SET(4,I);WrZ80(J.W,I);break;
|
||||
case SET5_xHL: I=RdZ80(J.W);M_SET(5,I);WrZ80(J.W,I);break;
|
||||
case SET6_xHL: I=RdZ80(J.W);M_SET(6,I);WrZ80(J.W,I);break;
|
||||
case SET7_xHL: I=RdZ80(J.W);M_SET(7,I);WrZ80(J.W,I);break;
|
||||
|
|
|
|||
|
|
@ -1,388 +1,396 @@
|
|||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesXX.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for FD/DD tables of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-1998 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case JR_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W++; else { M_JR; } break;
|
||||
case JR_NC: if(R->AF.B.l&C_FLAG) R->PC.W++; else { M_JR; } break;
|
||||
case JR_Z: if(R->AF.B.l&Z_FLAG) { M_JR; } else R->PC.W++; break;
|
||||
case JR_C: if(R->AF.B.l&C_FLAG) { M_JR; } else R->PC.W++; break;
|
||||
|
||||
case JP_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_Z: if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_C: if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_PE: if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_M: if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
|
||||
case RET_NZ: if(!(R->AF.B.l&Z_FLAG)) { M_RET; } break;
|
||||
case RET_NC: if(!(R->AF.B.l&C_FLAG)) { M_RET; } break;
|
||||
case RET_PO: if(!(R->AF.B.l&P_FLAG)) { M_RET; } break;
|
||||
case RET_P: if(!(R->AF.B.l&S_FLAG)) { M_RET; } break;
|
||||
case RET_Z: if(R->AF.B.l&Z_FLAG) { M_RET; } break;
|
||||
case RET_C: if(R->AF.B.l&C_FLAG) { M_RET; } break;
|
||||
case RET_PE: if(R->AF.B.l&P_FLAG) { M_RET; } break;
|
||||
case RET_M: if(R->AF.B.l&S_FLAG) { M_RET; } break;
|
||||
|
||||
case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||
case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||
case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||
case CALL_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_CALL; } break;
|
||||
case CALL_Z: if(R->AF.B.l&Z_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_C: if(R->AF.B.l&C_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_PE: if(R->AF.B.l&P_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_M: if(R->AF.B.l&S_FLAG) { M_CALL; } else R->PC.W+=2; break;
|
||||
|
||||
case ADD_B: M_ADD(R->BC.B.h);break;
|
||||
case ADD_C: M_ADD(R->BC.B.l);break;
|
||||
case ADD_D: M_ADD(R->DE.B.h);break;
|
||||
case ADD_E: M_ADD(R->DE.B.l);break;
|
||||
case ADD_H: M_ADD(R->XX.B.h);break;
|
||||
case ADD_L: M_ADD(R->XX.B.l);break;
|
||||
case ADD_A: M_ADD(R->AF.B.h);break;
|
||||
case ADD_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_ADD(I);break;
|
||||
case ADD_BYTE: I=RdZ80(R->PC.W++);M_ADD(I);break;
|
||||
|
||||
case SUB_B: M_SUB(R->BC.B.h);break;
|
||||
case SUB_C: M_SUB(R->BC.B.l);break;
|
||||
case SUB_D: M_SUB(R->DE.B.h);break;
|
||||
case SUB_E: M_SUB(R->DE.B.l);break;
|
||||
case SUB_H: M_SUB(R->XX.B.h);break;
|
||||
case SUB_L: M_SUB(R->XX.B.l);break;
|
||||
case SUB_A: R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case SUB_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_SUB(I);break;
|
||||
case SUB_BYTE: I=RdZ80(R->PC.W++);M_SUB(I);break;
|
||||
|
||||
case AND_B: M_AND(R->BC.B.h);break;
|
||||
case AND_C: M_AND(R->BC.B.l);break;
|
||||
case AND_D: M_AND(R->DE.B.h);break;
|
||||
case AND_E: M_AND(R->DE.B.l);break;
|
||||
case AND_H: M_AND(R->XX.B.h);break;
|
||||
case AND_L: M_AND(R->XX.B.l);break;
|
||||
case AND_A: M_AND(R->AF.B.h);break;
|
||||
case AND_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_AND(I);break;
|
||||
case AND_BYTE: I=RdZ80(R->PC.W++);M_AND(I);break;
|
||||
|
||||
case OR_B: M_OR(R->BC.B.h);break;
|
||||
case OR_C: M_OR(R->BC.B.l);break;
|
||||
case OR_D: M_OR(R->DE.B.h);break;
|
||||
case OR_E: M_OR(R->DE.B.l);break;
|
||||
case OR_H: M_OR(R->XX.B.h);break;
|
||||
case OR_L: M_OR(R->XX.B.l);break;
|
||||
case OR_A: M_OR(R->AF.B.h);break;
|
||||
case OR_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_OR(I);break;
|
||||
case OR_BYTE: I=RdZ80(R->PC.W++);M_OR(I);break;
|
||||
|
||||
case ADC_B: M_ADC(R->BC.B.h);break;
|
||||
case ADC_C: M_ADC(R->BC.B.l);break;
|
||||
case ADC_D: M_ADC(R->DE.B.h);break;
|
||||
case ADC_E: M_ADC(R->DE.B.l);break;
|
||||
case ADC_H: M_ADC(R->XX.B.h);break;
|
||||
case ADC_L: M_ADC(R->XX.B.l);break;
|
||||
case ADC_A: M_ADC(R->AF.B.h);break;
|
||||
case ADC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_ADC(I);break;
|
||||
case ADC_BYTE: I=RdZ80(R->PC.W++);M_ADC(I);break;
|
||||
|
||||
case SBC_B: M_SBC(R->BC.B.h);break;
|
||||
case SBC_C: M_SBC(R->BC.B.l);break;
|
||||
case SBC_D: M_SBC(R->DE.B.h);break;
|
||||
case SBC_E: M_SBC(R->DE.B.l);break;
|
||||
case SBC_H: M_SBC(R->XX.B.h);break;
|
||||
case SBC_L: M_SBC(R->XX.B.l);break;
|
||||
case SBC_A: M_SBC(R->AF.B.h);break;
|
||||
case SBC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_SBC(I);break;
|
||||
case SBC_BYTE: I=RdZ80(R->PC.W++);M_SBC(I);break;
|
||||
|
||||
case XOR_B: M_XOR(R->BC.B.h);break;
|
||||
case XOR_C: M_XOR(R->BC.B.l);break;
|
||||
case XOR_D: M_XOR(R->DE.B.h);break;
|
||||
case XOR_E: M_XOR(R->DE.B.l);break;
|
||||
case XOR_H: M_XOR(R->XX.B.h);break;
|
||||
case XOR_L: M_XOR(R->XX.B.l);break;
|
||||
case XOR_A: R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
|
||||
case XOR_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_XOR(I);break;
|
||||
case XOR_BYTE: I=RdZ80(R->PC.W++);M_XOR(I);break;
|
||||
|
||||
case CP_B: M_CP(R->BC.B.h);break;
|
||||
case CP_C: M_CP(R->BC.B.l);break;
|
||||
case CP_D: M_CP(R->DE.B.h);break;
|
||||
case CP_E: M_CP(R->DE.B.l);break;
|
||||
case CP_H: M_CP(R->XX.B.h);break;
|
||||
case CP_L: M_CP(R->XX.B.l);break;
|
||||
case CP_A: R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case CP_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_CP(I);break;
|
||||
case CP_BYTE: I=RdZ80(R->PC.W++);M_CP(I);break;
|
||||
|
||||
case LD_BC_WORD: M_LDWORD(BC);break;
|
||||
case LD_DE_WORD: M_LDWORD(DE);break;
|
||||
case LD_HL_WORD: M_LDWORD(XX);break;
|
||||
case LD_SP_WORD: M_LDWORD(SP);break;
|
||||
|
||||
case LD_PC_HL: R->PC.W=R->XX.W;break;
|
||||
case LD_SP_HL: R->SP.W=R->XX.W;break;
|
||||
case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
|
||||
case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
|
||||
|
||||
case ADD_HL_BC: M_ADDW(XX,BC);break;
|
||||
case ADD_HL_DE: M_ADDW(XX,DE);break;
|
||||
case ADD_HL_HL: M_ADDW(XX,XX);break;
|
||||
case ADD_HL_SP: M_ADDW(XX,SP);break;
|
||||
|
||||
case DEC_BC: R->BC.W--;break;
|
||||
case DEC_DE: R->DE.W--;break;
|
||||
case DEC_HL: R->XX.W--;break;
|
||||
case DEC_SP: R->SP.W--;break;
|
||||
|
||||
case INC_BC: R->BC.W++;break;
|
||||
case INC_DE: R->DE.W++;break;
|
||||
case INC_HL: R->XX.W++;break;
|
||||
case INC_SP: R->SP.W++;break;
|
||||
|
||||
case DEC_B: M_DEC(R->BC.B.h);break;
|
||||
case DEC_C: M_DEC(R->BC.B.l);break;
|
||||
case DEC_D: M_DEC(R->DE.B.h);break;
|
||||
case DEC_E: M_DEC(R->DE.B.l);break;
|
||||
case DEC_H: M_DEC(R->XX.B.h);break;
|
||||
case DEC_L: M_DEC(R->XX.B.l);break;
|
||||
case DEC_A: M_DEC(R->AF.B.h);break;
|
||||
case DEC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W));M_DEC(I);
|
||||
WrZ80(R->XX.W+(offset)RdZ80(R->PC.W++),I);
|
||||
break;
|
||||
|
||||
case INC_B: M_INC(R->BC.B.h);break;
|
||||
case INC_C: M_INC(R->BC.B.l);break;
|
||||
case INC_D: M_INC(R->DE.B.h);break;
|
||||
case INC_E: M_INC(R->DE.B.l);break;
|
||||
case INC_H: M_INC(R->XX.B.h);break;
|
||||
case INC_L: M_INC(R->XX.B.l);break;
|
||||
case INC_A: M_INC(R->AF.B.h);break;
|
||||
case INC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W));M_INC(I);
|
||||
WrZ80(R->XX.W+(offset)RdZ80(R->PC.W++),I);
|
||||
break;
|
||||
|
||||
case RLCA:
|
||||
I=(R->AF.B.h&0x80? C_FLAG:0);
|
||||
R->AF.B.h=(R->AF.B.h<<1)|I;
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RLA:
|
||||
I=(R->AF.B.h&0x80? C_FLAG:0);
|
||||
R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRCA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
|
||||
case RST00: M_RST(0x0000);break;
|
||||
case RST08: M_RST(0x0008);break;
|
||||
case RST10: M_RST(0x0010);break;
|
||||
case RST18: M_RST(0x0018);break;
|
||||
case RST20: M_RST(0x0020);break;
|
||||
case RST28: M_RST(0x0028);break;
|
||||
case RST30: M_RST(0x0030);break;
|
||||
case RST38: M_RST(0x0038);break;
|
||||
|
||||
case PUSH_BC: M_PUSH(BC);break;
|
||||
case PUSH_DE: M_PUSH(DE);break;
|
||||
case PUSH_HL: M_PUSH(XX);break;
|
||||
case PUSH_AF: M_PUSH(AF);break;
|
||||
|
||||
case POP_BC: M_POP(BC);break;
|
||||
case POP_DE: M_POP(DE);break;
|
||||
case POP_HL: M_POP(XX);break;
|
||||
case POP_AF: M_POP(AF);break;
|
||||
|
||||
case DJNZ: if(--R->BC.B.h) { M_JR; } else R->PC.W++;break;
|
||||
case JP: M_JP;break;
|
||||
case JR: M_JR;break;
|
||||
case CALL: M_CALL;break;
|
||||
case RET: M_RET;break;
|
||||
case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break;
|
||||
case CPL: R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
|
||||
case NOP: break;
|
||||
case OUTA: OutZ80(RdZ80(R->PC.W++),R->AF.B.h);break;
|
||||
case INA: R->AF.B.h=InZ80(RdZ80(R->PC.W++));break;
|
||||
|
||||
case DI:
|
||||
R->IFF&=0xFE;
|
||||
break;
|
||||
case EI:
|
||||
R->IFF|=0x01;
|
||||
if(R->IRequest!=INT_NONE)
|
||||
{
|
||||
R->IFF|=0x20;
|
||||
R->IBackup=R->ICount;
|
||||
R->ICount=1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CCF:
|
||||
R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
|
||||
R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
|
||||
break;
|
||||
|
||||
case EXX:
|
||||
J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
|
||||
J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
|
||||
J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
|
||||
break;
|
||||
|
||||
case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
|
||||
case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
|
||||
|
||||
case LD_B_B: R->BC.B.h=R->BC.B.h;break;
|
||||
case LD_C_B: R->BC.B.l=R->BC.B.h;break;
|
||||
case LD_D_B: R->DE.B.h=R->BC.B.h;break;
|
||||
case LD_E_B: R->DE.B.l=R->BC.B.h;break;
|
||||
case LD_H_B: R->XX.B.h=R->BC.B.h;break;
|
||||
case LD_L_B: R->XX.B.l=R->BC.B.h;break;
|
||||
case LD_A_B: R->AF.B.h=R->BC.B.h;break;
|
||||
case LD_xHL_B: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->BC.B.h);break;
|
||||
|
||||
case LD_B_C: R->BC.B.h=R->BC.B.l;break;
|
||||
case LD_C_C: R->BC.B.l=R->BC.B.l;break;
|
||||
case LD_D_C: R->DE.B.h=R->BC.B.l;break;
|
||||
case LD_E_C: R->DE.B.l=R->BC.B.l;break;
|
||||
case LD_H_C: R->XX.B.h=R->BC.B.l;break;
|
||||
case LD_L_C: R->XX.B.l=R->BC.B.l;break;
|
||||
case LD_A_C: R->AF.B.h=R->BC.B.l;break;
|
||||
case LD_xHL_C: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->BC.B.l);break;
|
||||
|
||||
case LD_B_D: R->BC.B.h=R->DE.B.h;break;
|
||||
case LD_C_D: R->BC.B.l=R->DE.B.h;break;
|
||||
case LD_D_D: R->DE.B.h=R->DE.B.h;break;
|
||||
case LD_E_D: R->DE.B.l=R->DE.B.h;break;
|
||||
case LD_H_D: R->XX.B.h=R->DE.B.h;break;
|
||||
case LD_L_D: R->XX.B.l=R->DE.B.h;break;
|
||||
case LD_A_D: R->AF.B.h=R->DE.B.h;break;
|
||||
case LD_xHL_D: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->DE.B.h);break;
|
||||
|
||||
case LD_B_E: R->BC.B.h=R->DE.B.l;break;
|
||||
case LD_C_E: R->BC.B.l=R->DE.B.l;break;
|
||||
case LD_D_E: R->DE.B.h=R->DE.B.l;break;
|
||||
case LD_E_E: R->DE.B.l=R->DE.B.l;break;
|
||||
case LD_H_E: R->XX.B.h=R->DE.B.l;break;
|
||||
case LD_L_E: R->XX.B.l=R->DE.B.l;break;
|
||||
case LD_A_E: R->AF.B.h=R->DE.B.l;break;
|
||||
case LD_xHL_E: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->DE.B.l);break;
|
||||
|
||||
case LD_B_H: R->BC.B.h=R->XX.B.h;break;
|
||||
case LD_C_H: R->BC.B.l=R->XX.B.h;break;
|
||||
case LD_D_H: R->DE.B.h=R->XX.B.h;break;
|
||||
case LD_E_H: R->DE.B.l=R->XX.B.h;break;
|
||||
case LD_H_H: R->XX.B.h=R->XX.B.h;break;
|
||||
case LD_L_H: R->XX.B.l=R->XX.B.h;break;
|
||||
case LD_A_H: R->AF.B.h=R->XX.B.h;break;
|
||||
case LD_xHL_H: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->HL.B.h);break;
|
||||
|
||||
case LD_B_L: R->BC.B.h=R->XX.B.l;break;
|
||||
case LD_C_L: R->BC.B.l=R->XX.B.l;break;
|
||||
case LD_D_L: R->DE.B.h=R->XX.B.l;break;
|
||||
case LD_E_L: R->DE.B.l=R->XX.B.l;break;
|
||||
case LD_H_L: R->XX.B.h=R->XX.B.l;break;
|
||||
case LD_L_L: R->XX.B.l=R->XX.B.l;break;
|
||||
case LD_A_L: R->AF.B.h=R->XX.B.l;break;
|
||||
case LD_xHL_L: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->HL.B.l);break;
|
||||
|
||||
case LD_B_A: R->BC.B.h=R->AF.B.h;break;
|
||||
case LD_C_A: R->BC.B.l=R->AF.B.h;break;
|
||||
case LD_D_A: R->DE.B.h=R->AF.B.h;break;
|
||||
case LD_E_A: R->DE.B.l=R->AF.B.h;break;
|
||||
case LD_H_A: R->XX.B.h=R->AF.B.h;break;
|
||||
case LD_L_A: R->XX.B.l=R->AF.B.h;break;
|
||||
case LD_A_A: R->AF.B.h=R->AF.B.h;break;
|
||||
case LD_xHL_A: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);break;
|
||||
|
||||
case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
|
||||
case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
|
||||
|
||||
case LD_B_xHL: R->BC.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_C_xHL: R->BC.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_D_xHL: R->DE.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_E_xHL: R->DE.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_H_xHL: R->HL.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_L_xHL: R->HL.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_A_xHL: R->AF.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_B_BYTE: R->BC.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_C_BYTE: R->BC.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_D_BYTE: R->DE.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_E_BYTE: R->DE.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_H_BYTE: R->XX.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_L_BYTE: R->XX.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_A_BYTE: R->AF.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_xHL_BYTE: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_xWORD_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->XX.B.l);
|
||||
WrZ80(J.W,R->XX.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->XX.B.l=RdZ80(J.W++);
|
||||
R->XX.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_A_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->AF.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_xWORD_A:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);
|
||||
break;
|
||||
|
||||
case EX_HL_xSP:
|
||||
J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->XX.B.l);
|
||||
J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->XX.B.h);
|
||||
R->XX.W=J.W;
|
||||
break;
|
||||
|
||||
case DAA:
|
||||
J.W=R->AF.B.h;
|
||||
if(R->AF.B.l&C_FLAG) J.W|=256;
|
||||
if(R->AF.B.l&H_FLAG) J.W|=512;
|
||||
if(R->AF.B.l&N_FLAG) J.W|=1024;
|
||||
R->AF.W=DAATable[J.W];
|
||||
break;
|
||||
/** Z80: portable Z80 emulator *******************************/
|
||||
/** **/
|
||||
/** CodesXX.h **/
|
||||
/** **/
|
||||
/** This file contains implementation for FD/DD tables of **/
|
||||
/** Z80 commands. It is included from Z80.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
case JR_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||
case JR_NC: if(R->AF.B.l&C_FLAG) R->PC.W++; else { R->ICount-=5;M_JR; } break;
|
||||
case JR_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||
case JR_C: if(R->AF.B.l&C_FLAG) { R->ICount-=5;M_JR; } else R->PC.W++; break;
|
||||
|
||||
case JP_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { M_JP; } break;
|
||||
case JP_Z: if(R->AF.B.l&Z_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_C: if(R->AF.B.l&C_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_PE: if(R->AF.B.l&P_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
case JP_M: if(R->AF.B.l&S_FLAG) { M_JP; } else R->PC.W+=2; break;
|
||||
|
||||
case RET_NZ: if(!(R->AF.B.l&Z_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_NC: if(!(R->AF.B.l&C_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_PO: if(!(R->AF.B.l&P_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_P: if(!(R->AF.B.l&S_FLAG)) { R->ICount-=6;M_RET; } break;
|
||||
case RET_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_C: if(R->AF.B.l&C_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
case RET_M: if(R->AF.B.l&S_FLAG) { R->ICount-=6;M_RET; } break;
|
||||
|
||||
case CALL_NZ: if(R->AF.B.l&Z_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_NC: if(R->AF.B.l&C_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_PO: if(R->AF.B.l&P_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_P: if(R->AF.B.l&S_FLAG) R->PC.W+=2; else { R->ICount-=7;M_CALL; } break;
|
||||
case CALL_Z: if(R->AF.B.l&Z_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_C: if(R->AF.B.l&C_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_PE: if(R->AF.B.l&P_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
case CALL_M: if(R->AF.B.l&S_FLAG) { R->ICount-=7;M_CALL; } else R->PC.W+=2; break;
|
||||
|
||||
case ADD_B: M_ADD(R->BC.B.h);break;
|
||||
case ADD_C: M_ADD(R->BC.B.l);break;
|
||||
case ADD_D: M_ADD(R->DE.B.h);break;
|
||||
case ADD_E: M_ADD(R->DE.B.l);break;
|
||||
case ADD_H: M_ADD(R->XX.B.h);break;
|
||||
case ADD_L: M_ADD(R->XX.B.l);break;
|
||||
case ADD_A: M_ADD(R->AF.B.h);break;
|
||||
case ADD_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_ADD(I);break;
|
||||
case ADD_BYTE: I=RdZ80(R->PC.W++);M_ADD(I);break;
|
||||
|
||||
case SUB_B: M_SUB(R->BC.B.h);break;
|
||||
case SUB_C: M_SUB(R->BC.B.l);break;
|
||||
case SUB_D: M_SUB(R->DE.B.h);break;
|
||||
case SUB_E: M_SUB(R->DE.B.l);break;
|
||||
case SUB_H: M_SUB(R->XX.B.h);break;
|
||||
case SUB_L: M_SUB(R->XX.B.l);break;
|
||||
case SUB_A: R->AF.B.h=0;R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case SUB_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_SUB(I);break;
|
||||
case SUB_BYTE: I=RdZ80(R->PC.W++);M_SUB(I);break;
|
||||
|
||||
case AND_B: M_AND(R->BC.B.h);break;
|
||||
case AND_C: M_AND(R->BC.B.l);break;
|
||||
case AND_D: M_AND(R->DE.B.h);break;
|
||||
case AND_E: M_AND(R->DE.B.l);break;
|
||||
case AND_H: M_AND(R->XX.B.h);break;
|
||||
case AND_L: M_AND(R->XX.B.l);break;
|
||||
case AND_A: M_AND(R->AF.B.h);break;
|
||||
case AND_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_AND(I);break;
|
||||
case AND_BYTE: I=RdZ80(R->PC.W++);M_AND(I);break;
|
||||
|
||||
case OR_B: M_OR(R->BC.B.h);break;
|
||||
case OR_C: M_OR(R->BC.B.l);break;
|
||||
case OR_D: M_OR(R->DE.B.h);break;
|
||||
case OR_E: M_OR(R->DE.B.l);break;
|
||||
case OR_H: M_OR(R->XX.B.h);break;
|
||||
case OR_L: M_OR(R->XX.B.l);break;
|
||||
case OR_A: M_OR(R->AF.B.h);break;
|
||||
case OR_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_OR(I);break;
|
||||
case OR_BYTE: I=RdZ80(R->PC.W++);M_OR(I);break;
|
||||
|
||||
case ADC_B: M_ADC(R->BC.B.h);break;
|
||||
case ADC_C: M_ADC(R->BC.B.l);break;
|
||||
case ADC_D: M_ADC(R->DE.B.h);break;
|
||||
case ADC_E: M_ADC(R->DE.B.l);break;
|
||||
case ADC_H: M_ADC(R->XX.B.h);break;
|
||||
case ADC_L: M_ADC(R->XX.B.l);break;
|
||||
case ADC_A: M_ADC(R->AF.B.h);break;
|
||||
case ADC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_ADC(I);break;
|
||||
case ADC_BYTE: I=RdZ80(R->PC.W++);M_ADC(I);break;
|
||||
|
||||
case SBC_B: M_SBC(R->BC.B.h);break;
|
||||
case SBC_C: M_SBC(R->BC.B.l);break;
|
||||
case SBC_D: M_SBC(R->DE.B.h);break;
|
||||
case SBC_E: M_SBC(R->DE.B.l);break;
|
||||
case SBC_H: M_SBC(R->XX.B.h);break;
|
||||
case SBC_L: M_SBC(R->XX.B.l);break;
|
||||
case SBC_A: M_SBC(R->AF.B.h);break;
|
||||
case SBC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_SBC(I);break;
|
||||
case SBC_BYTE: I=RdZ80(R->PC.W++);M_SBC(I);break;
|
||||
|
||||
case XOR_B: M_XOR(R->BC.B.h);break;
|
||||
case XOR_C: M_XOR(R->BC.B.l);break;
|
||||
case XOR_D: M_XOR(R->DE.B.h);break;
|
||||
case XOR_E: M_XOR(R->DE.B.l);break;
|
||||
case XOR_H: M_XOR(R->XX.B.h);break;
|
||||
case XOR_L: M_XOR(R->XX.B.l);break;
|
||||
case XOR_A: R->AF.B.h=0;R->AF.B.l=P_FLAG|Z_FLAG;break;
|
||||
case XOR_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_XOR(I);break;
|
||||
case XOR_BYTE: I=RdZ80(R->PC.W++);M_XOR(I);break;
|
||||
|
||||
case CP_B: M_CP(R->BC.B.h);break;
|
||||
case CP_C: M_CP(R->BC.B.l);break;
|
||||
case CP_D: M_CP(R->DE.B.h);break;
|
||||
case CP_E: M_CP(R->DE.B.l);break;
|
||||
case CP_H: M_CP(R->XX.B.h);break;
|
||||
case CP_L: M_CP(R->XX.B.l);break;
|
||||
case CP_A: R->AF.B.l=N_FLAG|Z_FLAG;break;
|
||||
case CP_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));
|
||||
M_CP(I);break;
|
||||
case CP_BYTE: I=RdZ80(R->PC.W++);M_CP(I);break;
|
||||
|
||||
case LD_BC_WORD: M_LDWORD(BC);break;
|
||||
case LD_DE_WORD: M_LDWORD(DE);break;
|
||||
case LD_HL_WORD: M_LDWORD(XX);break;
|
||||
case LD_SP_WORD: M_LDWORD(SP);break;
|
||||
|
||||
case LD_PC_HL: R->PC.W=R->XX.W;break;
|
||||
case LD_SP_HL: R->SP.W=R->XX.W;break;
|
||||
case LD_A_xBC: R->AF.B.h=RdZ80(R->BC.W);break;
|
||||
case LD_A_xDE: R->AF.B.h=RdZ80(R->DE.W);break;
|
||||
|
||||
case ADD_HL_BC: M_ADDW(XX,BC);break;
|
||||
case ADD_HL_DE: M_ADDW(XX,DE);break;
|
||||
case ADD_HL_HL: M_ADDW(XX,XX);break;
|
||||
case ADD_HL_SP: M_ADDW(XX,SP);break;
|
||||
|
||||
case DEC_BC: R->BC.W--;break;
|
||||
case DEC_DE: R->DE.W--;break;
|
||||
case DEC_HL: R->XX.W--;break;
|
||||
case DEC_SP: R->SP.W--;break;
|
||||
|
||||
case INC_BC: R->BC.W++;break;
|
||||
case INC_DE: R->DE.W++;break;
|
||||
case INC_HL: R->XX.W++;break;
|
||||
case INC_SP: R->SP.W++;break;
|
||||
|
||||
case DEC_B: M_DEC(R->BC.B.h);break;
|
||||
case DEC_C: M_DEC(R->BC.B.l);break;
|
||||
case DEC_D: M_DEC(R->DE.B.h);break;
|
||||
case DEC_E: M_DEC(R->DE.B.l);break;
|
||||
case DEC_H: M_DEC(R->XX.B.h);break;
|
||||
case DEC_L: M_DEC(R->XX.B.l);break;
|
||||
case DEC_A: M_DEC(R->AF.B.h);break;
|
||||
case DEC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W));M_DEC(I);
|
||||
WrZ80(R->XX.W+(offset)RdZ80(R->PC.W++),I);
|
||||
break;
|
||||
|
||||
case INC_B: M_INC(R->BC.B.h);break;
|
||||
case INC_C: M_INC(R->BC.B.l);break;
|
||||
case INC_D: M_INC(R->DE.B.h);break;
|
||||
case INC_E: M_INC(R->DE.B.l);break;
|
||||
case INC_H: M_INC(R->XX.B.h);break;
|
||||
case INC_L: M_INC(R->XX.B.l);break;
|
||||
case INC_A: M_INC(R->AF.B.h);break;
|
||||
case INC_xHL: I=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W));M_INC(I);
|
||||
WrZ80(R->XX.W+(offset)RdZ80(R->PC.W++),I);
|
||||
break;
|
||||
|
||||
case RLCA:
|
||||
I=(R->AF.B.h&0x80? C_FLAG:0);
|
||||
R->AF.B.h=(R->AF.B.h<<1)|I;
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RLA:
|
||||
I=(R->AF.B.h&0x80? C_FLAG:0);
|
||||
R->AF.B.h=(R->AF.B.h<<1)|(R->AF.B.l&C_FLAG);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRCA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(I? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
case RRA:
|
||||
I=R->AF.B.h&0x01;
|
||||
R->AF.B.h=(R->AF.B.h>>1)|(R->AF.B.l&C_FLAG? 0x80:0);
|
||||
R->AF.B.l=(R->AF.B.l&~(C_FLAG|N_FLAG|H_FLAG))|I;
|
||||
break;
|
||||
|
||||
case RST00: M_RST(0x0000);break;
|
||||
case RST08: M_RST(0x0008);break;
|
||||
case RST10: M_RST(0x0010);break;
|
||||
case RST18: M_RST(0x0018);break;
|
||||
case RST20: M_RST(0x0020);break;
|
||||
case RST28: M_RST(0x0028);break;
|
||||
case RST30: M_RST(0x0030);break;
|
||||
case RST38: M_RST(0x0038);break;
|
||||
|
||||
case PUSH_BC: M_PUSH(BC);break;
|
||||
case PUSH_DE: M_PUSH(DE);break;
|
||||
case PUSH_HL: M_PUSH(XX);break;
|
||||
case PUSH_AF: M_PUSH(AF);break;
|
||||
|
||||
case POP_BC: M_POP(BC);break;
|
||||
case POP_DE: M_POP(DE);break;
|
||||
case POP_HL: M_POP(XX);break;
|
||||
case POP_AF: M_POP(AF);break;
|
||||
|
||||
case DJNZ: if(--R->BC.B.h) { R->ICount-=5;M_JR; } else R->PC.W++;break;
|
||||
case JP: M_JP;break;
|
||||
case JR: M_JR;break;
|
||||
case CALL: M_CALL;break;
|
||||
case RET: M_RET;break;
|
||||
case SCF: S(C_FLAG);R(N_FLAG|H_FLAG);break;
|
||||
case CPL: R->AF.B.h=~R->AF.B.h;S(N_FLAG|H_FLAG);break;
|
||||
case NOP: break;
|
||||
case OUTA: OutZ80(RdZ80(R->PC.W++),R->AF.B.h);break;
|
||||
case INA: R->AF.B.h=InZ80(RdZ80(R->PC.W++));break;
|
||||
|
||||
case HALT:
|
||||
R->PC.W--;
|
||||
R->IFF|=IFF_HALT;
|
||||
R->IBackup=0;
|
||||
R->ICount=0;
|
||||
break;
|
||||
|
||||
case DI:
|
||||
if(R->IFF&IFF_EI) R->ICount+=R->IBackup-1;
|
||||
R->IFF&=~(IFF_1|IFF_2|IFF_EI);
|
||||
break;
|
||||
|
||||
case EI:
|
||||
if(!(R->IFF&(IFF_1|IFF_EI)))
|
||||
{
|
||||
R->IFF|=IFF_2|IFF_EI;
|
||||
R->IBackup=R->ICount;
|
||||
R->ICount=1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CCF:
|
||||
R->AF.B.l^=C_FLAG;R(N_FLAG|H_FLAG);
|
||||
R->AF.B.l|=R->AF.B.l&C_FLAG? 0:H_FLAG;
|
||||
break;
|
||||
|
||||
case EXX:
|
||||
J.W=R->BC.W;R->BC.W=R->BC1.W;R->BC1.W=J.W;
|
||||
J.W=R->DE.W;R->DE.W=R->DE1.W;R->DE1.W=J.W;
|
||||
J.W=R->HL.W;R->HL.W=R->HL1.W;R->HL1.W=J.W;
|
||||
break;
|
||||
|
||||
case EX_DE_HL: J.W=R->DE.W;R->DE.W=R->HL.W;R->HL.W=J.W;break;
|
||||
case EX_AF_AF: J.W=R->AF.W;R->AF.W=R->AF1.W;R->AF1.W=J.W;break;
|
||||
|
||||
case LD_B_B: R->BC.B.h=R->BC.B.h;break;
|
||||
case LD_C_B: R->BC.B.l=R->BC.B.h;break;
|
||||
case LD_D_B: R->DE.B.h=R->BC.B.h;break;
|
||||
case LD_E_B: R->DE.B.l=R->BC.B.h;break;
|
||||
case LD_H_B: R->XX.B.h=R->BC.B.h;break;
|
||||
case LD_L_B: R->XX.B.l=R->BC.B.h;break;
|
||||
case LD_A_B: R->AF.B.h=R->BC.B.h;break;
|
||||
case LD_xHL_B: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->BC.B.h);break;
|
||||
|
||||
case LD_B_C: R->BC.B.h=R->BC.B.l;break;
|
||||
case LD_C_C: R->BC.B.l=R->BC.B.l;break;
|
||||
case LD_D_C: R->DE.B.h=R->BC.B.l;break;
|
||||
case LD_E_C: R->DE.B.l=R->BC.B.l;break;
|
||||
case LD_H_C: R->XX.B.h=R->BC.B.l;break;
|
||||
case LD_L_C: R->XX.B.l=R->BC.B.l;break;
|
||||
case LD_A_C: R->AF.B.h=R->BC.B.l;break;
|
||||
case LD_xHL_C: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->BC.B.l);break;
|
||||
|
||||
case LD_B_D: R->BC.B.h=R->DE.B.h;break;
|
||||
case LD_C_D: R->BC.B.l=R->DE.B.h;break;
|
||||
case LD_D_D: R->DE.B.h=R->DE.B.h;break;
|
||||
case LD_E_D: R->DE.B.l=R->DE.B.h;break;
|
||||
case LD_H_D: R->XX.B.h=R->DE.B.h;break;
|
||||
case LD_L_D: R->XX.B.l=R->DE.B.h;break;
|
||||
case LD_A_D: R->AF.B.h=R->DE.B.h;break;
|
||||
case LD_xHL_D: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->DE.B.h);break;
|
||||
|
||||
case LD_B_E: R->BC.B.h=R->DE.B.l;break;
|
||||
case LD_C_E: R->BC.B.l=R->DE.B.l;break;
|
||||
case LD_D_E: R->DE.B.h=R->DE.B.l;break;
|
||||
case LD_E_E: R->DE.B.l=R->DE.B.l;break;
|
||||
case LD_H_E: R->XX.B.h=R->DE.B.l;break;
|
||||
case LD_L_E: R->XX.B.l=R->DE.B.l;break;
|
||||
case LD_A_E: R->AF.B.h=R->DE.B.l;break;
|
||||
case LD_xHL_E: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->DE.B.l);break;
|
||||
|
||||
case LD_B_H: R->BC.B.h=R->XX.B.h;break;
|
||||
case LD_C_H: R->BC.B.l=R->XX.B.h;break;
|
||||
case LD_D_H: R->DE.B.h=R->XX.B.h;break;
|
||||
case LD_E_H: R->DE.B.l=R->XX.B.h;break;
|
||||
case LD_H_H: R->XX.B.h=R->XX.B.h;break;
|
||||
case LD_L_H: R->XX.B.l=R->XX.B.h;break;
|
||||
case LD_A_H: R->AF.B.h=R->XX.B.h;break;
|
||||
case LD_xHL_H: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->HL.B.h);break;
|
||||
|
||||
case LD_B_L: R->BC.B.h=R->XX.B.l;break;
|
||||
case LD_C_L: R->BC.B.l=R->XX.B.l;break;
|
||||
case LD_D_L: R->DE.B.h=R->XX.B.l;break;
|
||||
case LD_E_L: R->DE.B.l=R->XX.B.l;break;
|
||||
case LD_H_L: R->XX.B.h=R->XX.B.l;break;
|
||||
case LD_L_L: R->XX.B.l=R->XX.B.l;break;
|
||||
case LD_A_L: R->AF.B.h=R->XX.B.l;break;
|
||||
case LD_xHL_L: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->HL.B.l);break;
|
||||
|
||||
case LD_B_A: R->BC.B.h=R->AF.B.h;break;
|
||||
case LD_C_A: R->BC.B.l=R->AF.B.h;break;
|
||||
case LD_D_A: R->DE.B.h=R->AF.B.h;break;
|
||||
case LD_E_A: R->DE.B.l=R->AF.B.h;break;
|
||||
case LD_H_A: R->XX.B.h=R->AF.B.h;break;
|
||||
case LD_L_A: R->XX.B.l=R->AF.B.h;break;
|
||||
case LD_A_A: R->AF.B.h=R->AF.B.h;break;
|
||||
case LD_xHL_A: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);break;
|
||||
|
||||
case LD_xBC_A: WrZ80(R->BC.W,R->AF.B.h);break;
|
||||
case LD_xDE_A: WrZ80(R->DE.W,R->AF.B.h);break;
|
||||
|
||||
case LD_B_xHL: R->BC.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_C_xHL: R->BC.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_D_xHL: R->DE.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_E_xHL: R->DE.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_H_xHL: R->HL.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_L_xHL: R->HL.B.l=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
case LD_A_xHL: R->AF.B.h=RdZ80(R->XX.W+(offset)RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_B_BYTE: R->BC.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_C_BYTE: R->BC.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_D_BYTE: R->DE.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_E_BYTE: R->DE.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_H_BYTE: R->XX.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_L_BYTE: R->XX.B.l=RdZ80(R->PC.W++);break;
|
||||
case LD_A_BYTE: R->AF.B.h=RdZ80(R->PC.W++);break;
|
||||
case LD_xHL_BYTE: J.W=R->XX.W+(offset)RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,RdZ80(R->PC.W++));break;
|
||||
|
||||
case LD_xWORD_HL:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W++,R->XX.B.l);
|
||||
WrZ80(J.W,R->XX.B.h);
|
||||
break;
|
||||
|
||||
case LD_HL_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->XX.B.l=RdZ80(J.W++);
|
||||
R->XX.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_A_xWORD:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
R->AF.B.h=RdZ80(J.W);
|
||||
break;
|
||||
|
||||
case LD_xWORD_A:
|
||||
J.B.l=RdZ80(R->PC.W++);
|
||||
J.B.h=RdZ80(R->PC.W++);
|
||||
WrZ80(J.W,R->AF.B.h);
|
||||
break;
|
||||
|
||||
case EX_HL_xSP:
|
||||
J.B.l=RdZ80(R->SP.W);WrZ80(R->SP.W++,R->XX.B.l);
|
||||
J.B.h=RdZ80(R->SP.W);WrZ80(R->SP.W--,R->XX.B.h);
|
||||
R->XX.W=J.W;
|
||||
break;
|
||||
|
||||
case DAA:
|
||||
J.W=R->AF.B.h;
|
||||
if(R->AF.B.l&C_FLAG) J.W|=256;
|
||||
if(R->AF.B.l&H_FLAG) J.W|=512;
|
||||
if(R->AF.B.l&N_FLAG) J.W|=1024;
|
||||
R->AF.W=DAATable[J.W];
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,95 +1,95 @@
|
|||
/*************************************************************/
|
||||
/** **/
|
||||
/** diskwork.h **/
|
||||
/** **/
|
||||
/** Common definitions for programs working with **/
|
||||
/** disk-images that can be used with fMSX **/
|
||||
/** **/
|
||||
/** **/
|
||||
/** Copyright (c) Arnold Metselaar 1996 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#define usint unsigned short int
|
||||
#define byte unsigned char
|
||||
|
||||
#define EOF_FAT 0xFFF /* signals EOF in FAT */
|
||||
|
||||
typedef struct de {
|
||||
char d_fname[8];
|
||||
char d_ext[3];
|
||||
char d_attrib;
|
||||
char d_reserv[10]; /* unused */
|
||||
byte d_time[2]; /* byte-ordering of ints is machine-dependent */
|
||||
byte d_date[2];
|
||||
byte d_first[2];
|
||||
byte d_size[4];
|
||||
} DirEntry;
|
||||
|
||||
/* macros to change DirEntries */
|
||||
#define setsh(x,y) {x[0]=y;x[1]=y>>8;}
|
||||
#define setlg(x,y) {x[0]=y;x[1]=y>>8;x[2]=y>>16;x[3]=y>>24;}
|
||||
|
||||
/* macros to read DirEntries */
|
||||
#define rdsh(x) (x[0]+(x[1]<<8))
|
||||
#define rdlg(x) (x[0]+(x[1]<<8)+(x[2]<<16)+(x[3]<<24))
|
||||
|
||||
#define PError(x) { fprintf(stderr,"%s: ",progname); perror(x); }
|
||||
|
||||
#define seclen 512 /* length of sector */
|
||||
#define cluslen 1024 /* length of cluster */
|
||||
|
||||
void *xalloc(size_t len)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!(p=malloc(len)))
|
||||
{
|
||||
puts("Out of memory\n"); exit(2);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
extern byte *FAT;
|
||||
|
||||
/* read FAT-entry from FAT in memory */
|
||||
usint ReadFAT(usint clnr)
|
||||
{ register byte *P;
|
||||
|
||||
P=FAT+(clnr*3)/2;
|
||||
return (clnr&1)? (P[0]>>4)+(P[1]<<4) : P[0]+((P[1]&0x0F)<<8);
|
||||
}
|
||||
|
||||
/* write an entry to FAT in memory */
|
||||
void WriteFAT(usint clnr, usint val)
|
||||
{ register byte *P;
|
||||
|
||||
P=FAT+(clnr*3)/2;
|
||||
if (clnr&1)
|
||||
{
|
||||
P[0]=(P[0]&0x0F)+(val<<4);
|
||||
P[1]=val>>4;
|
||||
}
|
||||
else
|
||||
{
|
||||
P[0]=val;
|
||||
P[1]=(P[1]&0xF0)+((val>>8)&0x0F);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
/** **/
|
||||
/** diskwork.h **/
|
||||
/** **/
|
||||
/** Common definitions for programs working with **/
|
||||
/** disk-images that can be used with fMSX **/
|
||||
/** **/
|
||||
/** **/
|
||||
/** Copyright (c) Arnold Metselaar 1996 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#define usint unsigned short int
|
||||
#define byte unsigned char
|
||||
|
||||
#define EOF_FAT 0xFFF /* signals EOF in FAT */
|
||||
|
||||
typedef struct de {
|
||||
char d_fname[8];
|
||||
char d_ext[3];
|
||||
char d_attrib;
|
||||
char d_reserv[10]; /* unused */
|
||||
byte d_time[2]; /* byte-ordering of ints is machine-dependent */
|
||||
byte d_date[2];
|
||||
byte d_first[2];
|
||||
byte d_size[4];
|
||||
} DirEntry;
|
||||
|
||||
/* macros to change DirEntries */
|
||||
#define setsh(x,y) {x[0]=y;x[1]=y>>8;}
|
||||
#define setlg(x,y) {x[0]=y;x[1]=y>>8;x[2]=y>>16;x[3]=y>>24;}
|
||||
|
||||
/* macros to read DirEntries */
|
||||
#define rdsh(x) (x[0]+(x[1]<<8))
|
||||
#define rdlg(x) (x[0]+(x[1]<<8)+(x[2]<<16)+(x[3]<<24))
|
||||
|
||||
#define PError(x) { fprintf(stderr,"%s: ",progname); perror(x); }
|
||||
|
||||
#define seclen 512 /* length of sector */
|
||||
#define cluslen 1024 /* length of cluster */
|
||||
|
||||
void *xalloc(size_t len)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!(p=malloc(len)))
|
||||
{
|
||||
puts("Out of memory\n"); exit(2);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
extern byte *FAT;
|
||||
|
||||
/* read FAT-entry from FAT in memory */
|
||||
usint ReadFAT(usint clnr)
|
||||
{ register byte *P;
|
||||
|
||||
P=FAT+(clnr*3)/2;
|
||||
return (clnr&1)? (P[0]>>4)+(P[1]<<4) : P[0]+((P[1]&0x0F)<<8);
|
||||
}
|
||||
|
||||
/* write an entry to FAT in memory */
|
||||
void WriteFAT(usint clnr, usint val)
|
||||
{ register byte *P;
|
||||
|
||||
P=FAT+(clnr*3)/2;
|
||||
if (clnr&1)
|
||||
{
|
||||
P[0]=(P[0]&0x0F)+(val<<4);
|
||||
P[1]=val>>4;
|
||||
}
|
||||
else
|
||||
{
|
||||
P[0]=val;
|
||||
P[1]=(P[1]&0xF0)+((val>>8)&0x0F);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,196 +1,196 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** I8251.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the Intel 8251 UART **/
|
||||
/** chip and the 8253 timer chip implementing a generic **/
|
||||
/** RS232 interface. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 2003 **/
|
||||
/** Maarten ter Huurne 2000 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#include "I8251.h"
|
||||
|
||||
/** Reset8251 ************************************************/
|
||||
/** Reset 8251 chip, assigning In and Out to the input and **/
|
||||
/** output streams. **/
|
||||
/*************************************************************/
|
||||
void Reset8251(register I8251 *D,FILE *In,FILE *Out)
|
||||
{
|
||||
D->IRQMask = 0x0F; /* All interrupts on */
|
||||
D->IRQs = 0x00; /* No interrupts yet */
|
||||
D->Mode = 1; /* Setting mode next */
|
||||
D->Flow = 0x00; /* Flow control off */
|
||||
D->NextChr = -1; /* No data yet */
|
||||
|
||||
/* Assign input and output streams */
|
||||
D->In = In? In:stdin;
|
||||
D->Out = Out? Out:stdout;
|
||||
}
|
||||
|
||||
/** Rd8251 ***************************************************/
|
||||
/** Read a byte from a given 8251 register. All values of R **/
|
||||
/** will be truncated to 3 bits as there are only 8 regs. **/
|
||||
/*************************************************************/
|
||||
byte Rd8251(register I8251 *D,register byte R)
|
||||
{
|
||||
register int J;
|
||||
|
||||
/* We only have 8 addressable ports */
|
||||
R&=0x07;
|
||||
|
||||
switch(R)
|
||||
{
|
||||
case 0: /* Data */
|
||||
if(D->Flow)
|
||||
{
|
||||
if(D->NextChr<0) D->NextChr=fgetc(D->In);
|
||||
J=D->NextChr;
|
||||
D->NextChr=-1;
|
||||
return((J<0? 0xFF:J)&((0x20<<((D->Control&0x0C)>>2))-1));
|
||||
}
|
||||
return(0xFF);
|
||||
|
||||
case 1: /* Status */
|
||||
if(D->NextChr<0) D->NextChr=fgetc(D->In);
|
||||
return(D->Flow&&(D->NextChr>=0)? 0x87:0x85);
|
||||
/*
|
||||
76543210
|
||||
1....... data set ready (dsr)
|
||||
.1...... sync detect, sync only
|
||||
..1..... framing error (fe), async only
|
||||
...1.... overrun error (oe)
|
||||
....1... parity error (pe)
|
||||
.....1.. transmitter empty
|
||||
......1. receiver ready
|
||||
.......1 transmitter ready
|
||||
|
||||
D->Flow is checked first, so that stdin input doesn't block
|
||||
fMSX until it's actually being read by the emulated MSX.
|
||||
*/
|
||||
|
||||
case 0x82: /* Status of CTS, timer/counter 2, RI and CD */
|
||||
return(0x7F);
|
||||
/*
|
||||
76543210
|
||||
1....... CTS (Clear To Send) 0=asserted
|
||||
.1...... timer/counter output-2 from 8253
|
||||
..XXXX.. reserved
|
||||
......1. RI (Ring Indicator) 0=asserted
|
||||
.......1 CD (Carrier Detect) 0=asserted
|
||||
|
||||
RI and CD are optional. If only one of them is implemented,
|
||||
it must be CD. Implemented like this:
|
||||
- CTS always returns 0 (asserted)
|
||||
- Everything else is not implemented
|
||||
*/
|
||||
}
|
||||
|
||||
/* Other RS232 ports:
|
||||
3: not standardised - unused
|
||||
4: 8253 counter 0 - not implemented
|
||||
5: 8253 counter 1 - not implemented
|
||||
6: 8253 counter 2 - not implemented
|
||||
7: 8253 mode register - write only
|
||||
*/
|
||||
|
||||
return(0xFF);
|
||||
}
|
||||
|
||||
/** Wr8251 ***************************************************/
|
||||
/** Write a byte to a given 8251 register. All values of R **/
|
||||
/** will be truncated to 3 bits as there are only 8 regs. **/
|
||||
/*************************************************************/
|
||||
void Wr8251(register I8251 *D,register byte R,register byte V)
|
||||
{
|
||||
/* We only have 8 addressable ports */
|
||||
R&=0x07;
|
||||
|
||||
switch(R)
|
||||
{
|
||||
case 0: /* Data */
|
||||
fputc(V&((0x20<<((D->Control&0x0C)>>2))-1),D->Out);
|
||||
fflush(D->Out);
|
||||
return;
|
||||
/*
|
||||
TODO: Flush the stream at appropriate intervals, instead of
|
||||
flushing for every single character. If flushing after every
|
||||
character remains, make the stream unbuffered.
|
||||
*/
|
||||
|
||||
case 1: /* Command */
|
||||
if(D->Mode)
|
||||
{
|
||||
D->Control=V;
|
||||
D->Mode=0;
|
||||
/* Set mode:
|
||||
......00 sync mode
|
||||
......01 async, baud rate factor is 1
|
||||
......10 async, baud rate factor is 16
|
||||
......11 async, baud rate factor is 64
|
||||
....00.. character length is 5 bits
|
||||
....01.. character length is 6 bits
|
||||
....10.. character length is 7 bits
|
||||
....11.. character length is 8 bits
|
||||
...1.... parity enable
|
||||
..1..... even/odd parity
|
||||
.1...... sync: external sync detect (syndet) is an input/output
|
||||
1....... sync: single/double character sync
|
||||
00...... async: invalid
|
||||
01...... async: 1 stop bit
|
||||
10...... async: 1.5 stop bits
|
||||
11...... async: 2 stop bits
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
D->Mode=V&0x40;
|
||||
D->Flow=(V>>4)&0x02;
|
||||
/* Execute command:
|
||||
76543210
|
||||
1....... enter hunt mode (enable search for sync characters)
|
||||
.1...... internal reset
|
||||
..1..... request to send (rts)
|
||||
...1.... reset error flags (pe,oe,fe)
|
||||
....1... send break character
|
||||
.....1.. receive enable
|
||||
......1. data terminal ready (dtr)
|
||||
.......1 transmit enable
|
||||
|
||||
Only RESET (bit6) and DTR (bit2) are implemented.
|
||||
*/
|
||||
}
|
||||
return;
|
||||
|
||||
case 2: /* Interrupt mask register */
|
||||
D->IRQMask=V;
|
||||
return;
|
||||
/*
|
||||
76543210
|
||||
XXXX.... reserved
|
||||
....1... timer interrupt from 8253 channel-2 (0=enable int)
|
||||
.....1.. sync character detect/break detect (0=enable int)
|
||||
......1. transmit data ready (TxReady) (0=enable int)
|
||||
.......1 receive data ready (RxReady) (0=enable int)
|
||||
|
||||
Initially all interrupts are disabled. RxReady interrupt must be
|
||||
implemented, the others are optional.
|
||||
|
||||
However, currently no interrupt at all is implemented. The result
|
||||
is that only one character is read per VDP interrupt, so serial
|
||||
communication is 50/60 baud.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Other RS232 ports:
|
||||
3: not standardised - unused
|
||||
4: 8253 counter 0 - not implemented
|
||||
5: 8253 counter 1 - not implemented
|
||||
6: 8253 counter 2 - not implemented
|
||||
7: 8253 mode register - not implemented
|
||||
*/
|
||||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** I8251.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the Intel 8251 UART **/
|
||||
/** chip and the 8253 timer chip implementing a generic **/
|
||||
/** RS232 interface. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 2004-2005 **/
|
||||
/** Maarten ter Huurne 2000 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#include "I8251.h"
|
||||
|
||||
/** Reset8251 ************************************************/
|
||||
/** Reset 8251 chip, assigning In and Out to the input and **/
|
||||
/** output streams. **/
|
||||
/*************************************************************/
|
||||
void Reset8251(register I8251 *D,FILE *In,FILE *Out)
|
||||
{
|
||||
D->IRQMask = 0x0F; /* All interrupts on */
|
||||
D->IRQs = 0x00; /* No interrupts yet */
|
||||
D->Mode = 1; /* Setting mode next */
|
||||
D->Flow = 0x00; /* Flow control off */
|
||||
D->NextChr = -1; /* No data yet */
|
||||
|
||||
/* Assign input and output streams */
|
||||
D->In = In? In:stdin;
|
||||
D->Out = Out? Out:stdout;
|
||||
}
|
||||
|
||||
/** Rd8251 ***************************************************/
|
||||
/** Read a byte from a given 8251 register. All values of R **/
|
||||
/** will be truncated to 3 bits as there are only 8 regs. **/
|
||||
/*************************************************************/
|
||||
byte Rd8251(register I8251 *D,register byte R)
|
||||
{
|
||||
register int J;
|
||||
|
||||
/* We only have 8 addressable ports */
|
||||
R&=0x07;
|
||||
|
||||
switch(R)
|
||||
{
|
||||
case 0: /* Data */
|
||||
if(D->Flow)
|
||||
{
|
||||
if(D->NextChr<0) D->NextChr=fgetc(D->In);
|
||||
J=D->NextChr;
|
||||
D->NextChr=-1;
|
||||
return((J<0? 0xFF:J)&((0x20<<((D->Control&0x0C)>>2))-1));
|
||||
}
|
||||
return(0xFF);
|
||||
|
||||
case 1: /* Status */
|
||||
if(D->NextChr<0) D->NextChr=fgetc(D->In);
|
||||
return(D->Flow&&(D->NextChr>=0)? 0x87:0x85);
|
||||
/*
|
||||
76543210
|
||||
1....... data set ready (dsr)
|
||||
.1...... sync detect, sync only
|
||||
..1..... framing error (fe), async only
|
||||
...1.... overrun error (oe)
|
||||
....1... parity error (pe)
|
||||
.....1.. transmitter empty
|
||||
......1. receiver ready
|
||||
.......1 transmitter ready
|
||||
|
||||
D->Flow is checked first, so that stdin input doesn't block
|
||||
fMSX until it's actually being read by the emulated MSX.
|
||||
*/
|
||||
|
||||
case 0x82: /* Status of CTS, timer/counter 2, RI and CD */
|
||||
return(0x7F);
|
||||
/*
|
||||
76543210
|
||||
1....... CTS (Clear To Send) 0=asserted
|
||||
.1...... timer/counter output-2 from 8253
|
||||
..XXXX.. reserved
|
||||
......1. RI (Ring Indicator) 0=asserted
|
||||
.......1 CD (Carrier Detect) 0=asserted
|
||||
|
||||
RI and CD are optional. If only one of them is implemented,
|
||||
it must be CD. Implemented like this:
|
||||
- CTS always returns 0 (asserted)
|
||||
- Everything else is not implemented
|
||||
*/
|
||||
}
|
||||
|
||||
/* Other RS232 ports:
|
||||
3: not standardised - unused
|
||||
4: 8253 counter 0 - not implemented
|
||||
5: 8253 counter 1 - not implemented
|
||||
6: 8253 counter 2 - not implemented
|
||||
7: 8253 mode register - write only
|
||||
*/
|
||||
|
||||
return(0xFF);
|
||||
}
|
||||
|
||||
/** Wr8251 ***************************************************/
|
||||
/** Write a byte to a given 8251 register. All values of R **/
|
||||
/** will be truncated to 3 bits as there are only 8 regs. **/
|
||||
/*************************************************************/
|
||||
void Wr8251(register I8251 *D,register byte R,register byte V)
|
||||
{
|
||||
/* We only have 8 addressable ports */
|
||||
R&=0x07;
|
||||
|
||||
switch(R)
|
||||
{
|
||||
case 0: /* Data */
|
||||
fputc(V&((0x20<<((D->Control&0x0C)>>2))-1),D->Out);
|
||||
fflush(D->Out);
|
||||
return;
|
||||
/*
|
||||
TODO: Flush the stream at appropriate intervals, instead of
|
||||
flushing for every single character. If flushing after every
|
||||
character remains, make the stream unbuffered.
|
||||
*/
|
||||
|
||||
case 1: /* Command */
|
||||
if(D->Mode)
|
||||
{
|
||||
D->Control=V;
|
||||
D->Mode=0;
|
||||
/* Set mode:
|
||||
......00 sync mode
|
||||
......01 async, baud rate factor is 1
|
||||
......10 async, baud rate factor is 16
|
||||
......11 async, baud rate factor is 64
|
||||
....00.. character length is 5 bits
|
||||
....01.. character length is 6 bits
|
||||
....10.. character length is 7 bits
|
||||
....11.. character length is 8 bits
|
||||
...1.... parity enable
|
||||
..1..... even/odd parity
|
||||
.1...... sync: external sync detect (syndet) is an input/output
|
||||
1....... sync: single/double character sync
|
||||
00...... async: invalid
|
||||
01...... async: 1 stop bit
|
||||
10...... async: 1.5 stop bits
|
||||
11...... async: 2 stop bits
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
D->Mode=V&0x40;
|
||||
D->Flow=(V>>4)&0x02;
|
||||
/* Execute command:
|
||||
76543210
|
||||
1....... enter hunt mode (enable search for sync characters)
|
||||
.1...... internal reset
|
||||
..1..... request to send (rts)
|
||||
...1.... reset error flags (pe,oe,fe)
|
||||
....1... send break character
|
||||
.....1.. receive enable
|
||||
......1. data terminal ready (dtr)
|
||||
.......1 transmit enable
|
||||
|
||||
Only RESET (bit6) and DTR (bit2) are implemented.
|
||||
*/
|
||||
}
|
||||
return;
|
||||
|
||||
case 2: /* Interrupt mask register */
|
||||
D->IRQMask=V;
|
||||
return;
|
||||
/*
|
||||
76543210
|
||||
XXXX.... reserved
|
||||
....1... timer interrupt from 8253 channel-2 (0=enable int)
|
||||
.....1.. sync character detect/break detect (0=enable int)
|
||||
......1. transmit data ready (TxReady) (0=enable int)
|
||||
.......1 receive data ready (RxReady) (0=enable int)
|
||||
|
||||
Initially all interrupts are disabled. RxReady interrupt must be
|
||||
implemented, the others are optional.
|
||||
|
||||
However, currently no interrupt at all is implemented. The result
|
||||
is that only one character is read per VDP interrupt, so serial
|
||||
communication is 50/60 baud.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Other RS232 ports:
|
||||
3: not standardised - unused
|
||||
4: 8253 counter 0 - not implemented
|
||||
5: 8253 counter 1 - not implemented
|
||||
6: 8253 counter 2 - not implemented
|
||||
7: 8253 mode register - not implemented
|
||||
*/
|
||||
}
|
||||
|
|
@ -1,57 +1,57 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** I8251.h **/
|
||||
/** **/
|
||||
/** This file contains definitions and declarations for **/
|
||||
/** routines in I8251.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 2003 **/
|
||||
/** Maarten ter Huurne 2000 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#ifndef I8251_H
|
||||
#define I8251_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef BYTE_TYPE_DEFINED
|
||||
#define BYTE_TYPE_DEFINED
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
/** I8251 ****************************************************/
|
||||
/** This data structure stores I8251 state. **/
|
||||
/*************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
byte Control; /* 8251 ACIA control reg. */
|
||||
byte IRQMask; /* RS232 interrupt mask */
|
||||
byte IRQs; /* RS232 interrupts */
|
||||
byte Mode; /* 8251 mode/cmd select */
|
||||
byte Flow; /* Flow control state */
|
||||
int NextChr; /* Next char or -1 */
|
||||
FILE *In; /* Input stream */
|
||||
FILE *Out; /* Output stream */
|
||||
} I8251;
|
||||
|
||||
/** Reset8251 ************************************************/
|
||||
/** Reset 8251 chip, assigning In and Out to the input and **/
|
||||
/** output streams. **/
|
||||
/*************************************************************/
|
||||
void Reset8251(register I8251 *D,FILE *In,FILE *Out);
|
||||
|
||||
/** Rd8251 ***************************************************/
|
||||
/** Read a byte from a given 8251 register. All values of R **/
|
||||
/** will be truncated to 3 bits as there are only 8 regs. **/
|
||||
/*************************************************************/
|
||||
byte Rd8251(register I8251 *D,register byte R);
|
||||
|
||||
/** Wr8251 ***************************************************/
|
||||
/** Write a byte to a given 8251 register. All values of R **/
|
||||
/** will be truncated to 3 bits as there are only 8 regs. **/
|
||||
/*************************************************************/
|
||||
void Wr8251(register I8251 *D,register byte R,register byte V);
|
||||
|
||||
#endif /* I8251_H */
|
||||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** I8251.h **/
|
||||
/** **/
|
||||
/** This file contains definitions and declarations for **/
|
||||
/** routines in I8251.c. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 2004-2005 **/
|
||||
/** Maarten ter Huurne 2000 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#ifndef I8251_H
|
||||
#define I8251_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef BYTE_TYPE_DEFINED
|
||||
#define BYTE_TYPE_DEFINED
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
/** I8251 ****************************************************/
|
||||
/** This data structure stores I8251 state. **/
|
||||
/*************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
byte Control; /* 8251 ACIA control reg. */
|
||||
byte IRQMask; /* RS232 interrupt mask */
|
||||
byte IRQs; /* RS232 interrupts */
|
||||
byte Mode; /* 8251 mode/cmd select */
|
||||
byte Flow; /* Flow control state */
|
||||
int NextChr; /* Next char or -1 */
|
||||
FILE *In; /* Input stream */
|
||||
FILE *Out; /* Output stream */
|
||||
} I8251;
|
||||
|
||||
/** Reset8251 ************************************************/
|
||||
/** Reset 8251 chip, assigning In and Out to the input and **/
|
||||
/** output streams. **/
|
||||
/*************************************************************/
|
||||
void Reset8251(register I8251 *D,FILE *In,FILE *Out);
|
||||
|
||||
/** Rd8251 ***************************************************/
|
||||
/** Read a byte from a given 8251 register. All values of R **/
|
||||
/** will be truncated to 3 bits as there are only 8 regs. **/
|
||||
/*************************************************************/
|
||||
byte Rd8251(register I8251 *D,register byte R);
|
||||
|
||||
/** Wr8251 ***************************************************/
|
||||
/** Write a byte to a given 8251 register. All values of R **/
|
||||
/** will be truncated to 3 bits as there are only 8 regs. **/
|
||||
/*************************************************************/
|
||||
void Wr8251(register I8251 *D,register byte R,register byte V);
|
||||
|
||||
#endif /* I8251_H */
|
||||
|
|
|
|||
|
|
@ -1,88 +1,88 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** I8255.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the i8255 parallel **/
|
||||
/** port interface (PPI) chip from Intel. See I8255.h for **/
|
||||
/** declarations. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 2001-2003 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#include "I8255.h"
|
||||
|
||||
/** Reset8255 ************************************************/
|
||||
/** Reset the chip. Set all data to 0x00. Set all ports to **/
|
||||
/** "input" mode. **/
|
||||
/*************************************************************/
|
||||
void Reset8255(register I8255 *D)
|
||||
{
|
||||
/* Initialize all registers and ports */
|
||||
D->R[0]=D->Rout[0]=D->Rin[0]=0x00;
|
||||
D->R[1]=D->Rout[1]=D->Rin[1]=0x00;
|
||||
D->R[2]=D->Rout[2]=D->Rin[2]=0x00;
|
||||
D->R[3]=0x9B;
|
||||
}
|
||||
|
||||
/** Write8255 ************************************************/
|
||||
/** Write value V into i8255 register A. Returns 0 when A **/
|
||||
/** is out of range, 1 otherwise. **/
|
||||
/*************************************************************/
|
||||
byte Write8255(register I8255 *D,register byte A,register byte V)
|
||||
{
|
||||
switch(A)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
/* Data registers */
|
||||
D->R[A]=V;
|
||||
break;
|
||||
case 3:
|
||||
/* Control register */
|
||||
if(V&0x80) D->R[A]=V;
|
||||
else
|
||||
{
|
||||
A=1<<((V&0x0E)>>1);
|
||||
if(V&0x01) D->R[2]|=A; else D->R[2]&=~A;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Invalid register */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Set output ports */
|
||||
V=D->R[3];
|
||||
D->Rout[0] = V&0x10? 0x00:D->R[0];
|
||||
D->Rout[1] = V&0x02? 0x00:D->R[1];
|
||||
D->Rout[2] = ((V&0x01? 0x00:D->R[2])&0x0F)
|
||||
| ((V&0x08? 0x00:D->R[2])&0xF0);
|
||||
|
||||
/* Done */
|
||||
return(1);
|
||||
}
|
||||
|
||||
/** Read8255 *************************************************/
|
||||
/** Read value from an i8255 register A. Returns 0 when A **/
|
||||
/** is out of range. **/
|
||||
/*************************************************************/
|
||||
byte Read8255(register I8255 *D,register byte A)
|
||||
{
|
||||
switch(A)
|
||||
{
|
||||
case 0: return(D->R[3]&0x10? D->Rin[0]:D->R[0]);
|
||||
case 1: return(D->R[3]&0x02? D->Rin[1]:D->R[1]);
|
||||
case 2: return
|
||||
(
|
||||
((D->R[3]&0x01? D->Rin[2]:D->R[2])&0x0F)|
|
||||
((D->R[3]&0x08? D->Rin[2]:D->R[2])&0xF0)
|
||||
);
|
||||
case 3: return(D->R[3]);
|
||||
}
|
||||
|
||||
/* Invalid address */
|
||||
return(0x00);
|
||||
}
|
||||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** I8255.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the i8255 parallel **/
|
||||
/** port interface (PPI) chip from Intel. See I8255.h for **/
|
||||
/** declarations. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 2001-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#include "I8255.h"
|
||||
|
||||
/** Reset8255 ************************************************/
|
||||
/** Reset the chip. Set all data to 0x00. Set all ports to **/
|
||||
/** "input" mode. **/
|
||||
/*************************************************************/
|
||||
void Reset8255(register I8255 *D)
|
||||
{
|
||||
/* Initialize all registers and ports */
|
||||
D->R[0]=D->Rout[0]=D->Rin[0]=0x00;
|
||||
D->R[1]=D->Rout[1]=D->Rin[1]=0x00;
|
||||
D->R[2]=D->Rout[2]=D->Rin[2]=0x00;
|
||||
D->R[3]=0x9B;
|
||||
}
|
||||
|
||||
/** Write8255 ************************************************/
|
||||
/** Write value V into i8255 register A. Returns 0 when A **/
|
||||
/** is out of range, 1 otherwise. **/
|
||||
/*************************************************************/
|
||||
byte Write8255(register I8255 *D,register byte A,register byte V)
|
||||
{
|
||||
switch(A)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
/* Data registers */
|
||||
D->R[A]=V;
|
||||
break;
|
||||
case 3:
|
||||
/* Control register */
|
||||
if(V&0x80) D->R[A]=V;
|
||||
else
|
||||
{
|
||||
A=1<<((V&0x0E)>>1);
|
||||
if(V&0x01) D->R[2]|=A; else D->R[2]&=~A;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Invalid register */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Set output ports */
|
||||
V=D->R[3];
|
||||
D->Rout[0] = V&0x10? 0x00:D->R[0];
|
||||
D->Rout[1] = V&0x02? 0x00:D->R[1];
|
||||
D->Rout[2] = ((V&0x01? 0x00:D->R[2])&0x0F)
|
||||
| ((V&0x08? 0x00:D->R[2])&0xF0);
|
||||
|
||||
/* Done */
|
||||
return(1);
|
||||
}
|
||||
|
||||
/** Read8255 *************************************************/
|
||||
/** Read value from an i8255 register A. Returns 0 when A **/
|
||||
/** is out of range. **/
|
||||
/*************************************************************/
|
||||
byte Read8255(register I8255 *D,register byte A)
|
||||
{
|
||||
switch(A)
|
||||
{
|
||||
case 0: return(D->R[3]&0x10? D->Rin[0]:D->R[0]);
|
||||
case 1: return(D->R[3]&0x02? D->Rin[1]:D->R[1]);
|
||||
case 2: return
|
||||
(
|
||||
((D->R[3]&0x01? D->Rin[2]:D->R[2])&0x0F)|
|
||||
((D->R[3]&0x08? D->Rin[2]:D->R[2])&0xF0)
|
||||
);
|
||||
case 3: return(D->R[3]);
|
||||
}
|
||||
|
||||
/* Invalid address */
|
||||
return(0x00);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +1,50 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** I8255.h **/
|
||||
/** **/
|
||||
/** This file contains emulation for the i8255 parallel **/
|
||||
/** port interface (PPI) chip from Intel. See I8255.h for **/
|
||||
/** the actual code. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 2001-2003 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#ifndef I8255_H
|
||||
#define I8255_H
|
||||
|
||||
#ifndef BYTE_TYPE_DEFINED
|
||||
#define BYTE_TYPE_DEFINED
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
/** I8255 ****************************************************/
|
||||
/** This data structure stores i8255 state and port values. **/
|
||||
/*************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
byte R[4]; /* Registers */
|
||||
byte Rout[3]; /* Output ports */
|
||||
byte Rin[3]; /* Input ports */
|
||||
} I8255;
|
||||
|
||||
/** Reset8255 ************************************************/
|
||||
/** Reset the i8255 chip. Set all data to 0x00. Set all **/
|
||||
/** ports to "input" mode. **/
|
||||
/*************************************************************/
|
||||
void Reset8255(register I8255 *D);
|
||||
|
||||
/** Write8255 ************************************************/
|
||||
/** Write value V into i8255 register A. Returns 0 when A **/
|
||||
/** is out of range, 1 otherwise. **/
|
||||
/*************************************************************/
|
||||
byte Write8255(register I8255 *D,register byte A,register byte V);
|
||||
|
||||
/** Read8255 *************************************************/
|
||||
/** Read value from an i8255 register A. Returns 0 when A **/
|
||||
/** is out of range. **/
|
||||
/*************************************************************/
|
||||
byte Read8255(register I8255 *D,register byte A);
|
||||
|
||||
#endif /* I8255_H */
|
||||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** I8255.h **/
|
||||
/** **/
|
||||
/** This file contains emulation for the i8255 parallel **/
|
||||
/** port interface (PPI) chip from Intel. See I8255.h for **/
|
||||
/** the actual code. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 2001-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#ifndef I8255_H
|
||||
#define I8255_H
|
||||
|
||||
#ifndef BYTE_TYPE_DEFINED
|
||||
#define BYTE_TYPE_DEFINED
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
/** I8255 ****************************************************/
|
||||
/** This data structure stores i8255 state and port values. **/
|
||||
/*************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
byte R[4]; /* Registers */
|
||||
byte Rout[3]; /* Output ports */
|
||||
byte Rin[3]; /* Input ports */
|
||||
} I8255;
|
||||
|
||||
/** Reset8255 ************************************************/
|
||||
/** Reset the i8255 chip. Set all data to 0x00. Set all **/
|
||||
/** ports to "input" mode. **/
|
||||
/*************************************************************/
|
||||
void Reset8255(register I8255 *D);
|
||||
|
||||
/** Write8255 ************************************************/
|
||||
/** Write value V into i8255 register A. Returns 0 when A **/
|
||||
/** is out of range, 1 otherwise. **/
|
||||
/*************************************************************/
|
||||
byte Write8255(register I8255 *D,register byte A,register byte V);
|
||||
|
||||
/** Read8255 *************************************************/
|
||||
/** Read value from an i8255 register A. Returns 0 when A **/
|
||||
/** is out of range. **/
|
||||
/*************************************************************/
|
||||
byte Read8255(register I8255 *D,register byte A);
|
||||
|
||||
#endif /* I8255_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -5,11 +5,12 @@
|
|||
/** This file contains implementation for the PatchZ80() **/
|
||||
/** function necessary for emulating MSX disk and tape IO. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-2003 **/
|
||||
/** Copyright (C) Marat Fayzullin 1994-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#include "MSX.h"
|
||||
#include "Boot.h"
|
||||
#include <stdio.h>
|
||||
|
|
@ -351,6 +352,7 @@ case 0x00E1:
|
|||
|
||||
rewind(CasStream);
|
||||
}
|
||||
|
||||
if(Verbose&0x04) puts("FAILED");
|
||||
#endif
|
||||
return;
|
||||
|
|
@ -373,6 +375,7 @@ case 0x00E4:
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x00E7:
|
||||
/** TAPIOF: *****************************************************
|
||||
****************************************************************/
|
||||
|
|
|
|||
|
|
@ -1,187 +1,187 @@
|
|||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** SCC.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the SCC sound chip **/
|
||||
/** produced by Konami. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-2003 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#include "SCC.h"
|
||||
#include "Sound.h"
|
||||
#include <string.h>
|
||||
|
||||
/** ResetSCC() ***********************************************/
|
||||
/** Reset the sound chip and use sound channels from the **/
|
||||
/** one given in First. **/
|
||||
/*************************************************************/
|
||||
void ResetSCC(register SCC *D,int First)
|
||||
{
|
||||
int J;
|
||||
|
||||
/* Reset registers */
|
||||
memset(D->R,0x00,sizeof(D->R));
|
||||
|
||||
/* Set instruments, frequencies, volumes */
|
||||
for(J=0;J<SCC_CHANNELS;J++)
|
||||
{
|
||||
SetSound(0+First,SND_MELODIC);
|
||||
D->Freq[J]=D->Volume[J]=0;
|
||||
}
|
||||
|
||||
D->First = First;
|
||||
D->Sync = SCC_ASYNC;
|
||||
D->Changed = 0x00;
|
||||
D->WChanged = 0x00;
|
||||
}
|
||||
|
||||
/** ReadSCC() ************************************************/
|
||||
/** Call this function to read contents of the generic SCC **/
|
||||
/** sound chip registers. **/
|
||||
/*************************************************************/
|
||||
byte ReadSCC(register SCC *D,register byte R)
|
||||
{
|
||||
return(R<0x80? D->R[R]:0xFF);
|
||||
}
|
||||
|
||||
/** ReadSCCP() ***********************************************/
|
||||
/** Call this function to read contents of the newer SCC+ **/
|
||||
/** sound chip registers. **/
|
||||
/*************************************************************/
|
||||
byte ReadSCCP(register SCC *D,register byte R)
|
||||
{
|
||||
return(R<0xA0? D->R[R]:0xFF);
|
||||
}
|
||||
|
||||
/** WriteSCC() ***********************************************/
|
||||
/** Call this function to output a value V into the generic **/
|
||||
/** SCC sound chip. **/
|
||||
/*************************************************************/
|
||||
void WriteSCC(register SCC *D,register byte R,register byte V)
|
||||
{
|
||||
/* Prevent rollover */
|
||||
if(R>=0xE0) return;
|
||||
/* Generic SCC has one waveform less than SCC+ */
|
||||
if(R>=0x80) { WriteSCCP(D,R+0x20,V);return; }
|
||||
/* The last waveform applies to both channels 3 and 4 */
|
||||
if(R>=0x60) { WriteSCCP(D,R,V);WriteSCCP(D,R+0x20,V);return; }
|
||||
/* Other waveforms are the same */
|
||||
WriteSCCP(D,R,V);
|
||||
}
|
||||
|
||||
/** WriteSCCP() **********************************************/
|
||||
/** Call this function to output a value V into the newer **/
|
||||
/** SCC+ sound chip. **/
|
||||
/*************************************************************/
|
||||
void WriteSCCP(register SCC *D,register byte R,register byte V)
|
||||
{
|
||||
register int J;
|
||||
register byte I;
|
||||
|
||||
/* Exit if no change */
|
||||
if(V==D->R[R]) return;
|
||||
|
||||
if((R&0xE0)==0xA0)
|
||||
{
|
||||
/* Emulate melodic features */
|
||||
|
||||
/* Save active channel mask in I */
|
||||
I=D->R[0xAF];
|
||||
/* Write to a register */
|
||||
R&=0xEF;
|
||||
D->R[R]=D->R[R+0x10]=V;
|
||||
|
||||
/* Melodic register number 0..15 */
|
||||
R&=0x0F;
|
||||
switch(R)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4:
|
||||
case 5: case 6: case 7: case 8: case 9:
|
||||
/* Exit if the channel is silenced */
|
||||
if(!(I&(1<<(R>>1)))) return;
|
||||
/* Go to the first register of the pair */
|
||||
R=(R&0xFE)+0xA0;
|
||||
/* Compute frequency */
|
||||
J=((int)(D->R[R+1]&0x0F)<<8)+D->R[R];
|
||||
/* Compute channel number */
|
||||
R=(R&0x0F)>>1;
|
||||
/* Assign frequency */
|
||||
D->Freq[R]=J? SCC_BASE/J:0;
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=1<<R;
|
||||
break;
|
||||
|
||||
case 10: case 11: case 12: case 13: case 14:
|
||||
/* Compute channel number */
|
||||
R-=10;
|
||||
/* Compute and assign new volume */
|
||||
D->Volume[R]=255*(V&0x0F)/15;
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=(1<<R)&I;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
/* Find changed channels */
|
||||
R=(V^I)&0x1F;
|
||||
D->Changed|=R;
|
||||
/* Update frequencies */
|
||||
for(I=0;R&&(I<SCC_CHANNELS);I++,R>>=1,V>>=1)
|
||||
if(R&1)
|
||||
{
|
||||
if(!(V&1)) D->Freq[I]=0;
|
||||
else
|
||||
{
|
||||
J=I*2+0xA0;
|
||||
J=((int)(D->R[J+1]&0x0F)<<8)+D->R[J];
|
||||
D->Freq[I]=J? SCC_BASE/J:0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Wrong register, do nothing */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Emulate wave table features */
|
||||
|
||||
/* Write data to SCC */
|
||||
D->R[R]=V;
|
||||
/* Wrong register, do nothing */
|
||||
if(R>=0xA0) return;
|
||||
/* Mark channel waveform as changed */
|
||||
D->WChanged|=1<<(R>>5);
|
||||
}
|
||||
|
||||
/* For asynchronous mode, make Sound() calls right away */
|
||||
if(!D->Sync&&(D->Changed||D->WChanged)) SyncSCC(D,SCC_FLUSH);
|
||||
}
|
||||
|
||||
/** SyncSCC() ************************************************/
|
||||
/** Flush all accumulated changes by issuing Sound() calls **/
|
||||
/** and set the synchronization on/off. The second argument **/
|
||||
/** should be SCC_SYNC/SCC_ASYNC to set/reset sync, or **/
|
||||
/** SCC_FLUSH to leave sync mode as it is. **/
|
||||
/*************************************************************/
|
||||
void SyncSCC(register SCC *D,register byte Sync)
|
||||
{
|
||||
register int J,I;
|
||||
|
||||
if(Sync!=SCC_FLUSH) D->Sync=Sync;
|
||||
|
||||
/* Modify waveforms */
|
||||
for(J=0,I=D->WChanged;I&&(J<SCC_CHANNELS);J++,I>>=1)
|
||||
if(I&1) SetWave(J+D->First,(signed char *)(D->R+(J<<5)),32,0);
|
||||
|
||||
/* Modify frequencies and volumes */
|
||||
for(J=0,I=D->Changed;I&&(J<SCC_CHANNELS);J++,I>>=1)
|
||||
if(I&1) Sound(J+D->First,D->Freq[J],D->Volume[J]);
|
||||
|
||||
D->Changed=D->WChanged=0x00;
|
||||
}
|
||||
/** EMULib Emulation Library *********************************/
|
||||
/** **/
|
||||
/** SCC.c **/
|
||||
/** **/
|
||||
/** This file contains emulation for the SCC sound chip **/
|
||||
/** produced by Konami. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-2005 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
#include "SCC.h"
|
||||
#include "Sound.h"
|
||||
#include <string.h>
|
||||
|
||||
/** ResetSCC() ***********************************************/
|
||||
/** Reset the sound chip and use sound channels from the **/
|
||||
/** one given in First. **/
|
||||
/*************************************************************/
|
||||
void ResetSCC(register SCC *D,int First)
|
||||
{
|
||||
int J;
|
||||
|
||||
/* Reset registers */
|
||||
memset(D->R,0x00,sizeof(D->R));
|
||||
|
||||
/* Set instruments, frequencies, volumes */
|
||||
for(J=0;J<SCC_CHANNELS;J++)
|
||||
{
|
||||
SetSound(0+First,SND_MELODIC);
|
||||
D->Freq[J]=D->Volume[J]=0;
|
||||
}
|
||||
|
||||
D->First = First;
|
||||
D->Sync = SCC_ASYNC;
|
||||
D->Changed = 0x00;
|
||||
D->WChanged = 0x00;
|
||||
}
|
||||
|
||||
/** ReadSCC() ************************************************/
|
||||
/** Call this function to read contents of the generic SCC **/
|
||||
/** sound chip registers. **/
|
||||
/*************************************************************/
|
||||
byte ReadSCC(register SCC *D,register byte R)
|
||||
{
|
||||
return(R<0x80? D->R[R]:0xFF);
|
||||
}
|
||||
|
||||
/** ReadSCCP() ***********************************************/
|
||||
/** Call this function to read contents of the newer SCC+ **/
|
||||
/** sound chip registers. **/
|
||||
/*************************************************************/
|
||||
byte ReadSCCP(register SCC *D,register byte R)
|
||||
{
|
||||
return(R<0xA0? D->R[R]:0xFF);
|
||||
}
|
||||
|
||||
/** WriteSCC() ***********************************************/
|
||||
/** Call this function to output a value V into the generic **/
|
||||
/** SCC sound chip. **/
|
||||
/*************************************************************/
|
||||
void WriteSCC(register SCC *D,register byte R,register byte V)
|
||||
{
|
||||
/* Prevent rollover */
|
||||
if(R>=0xE0) return;
|
||||
/* Generic SCC has one waveform less than SCC+ */
|
||||
if(R>=0x80) { WriteSCCP(D,R+0x20,V);return; }
|
||||
/* The last waveform applies to both channels 3 and 4 */
|
||||
if(R>=0x60) { WriteSCCP(D,R,V);WriteSCCP(D,R+0x20,V);return; }
|
||||
/* Other waveforms are the same */
|
||||
WriteSCCP(D,R,V);
|
||||
}
|
||||
|
||||
/** WriteSCCP() **********************************************/
|
||||
/** Call this function to output a value V into the newer **/
|
||||
/** SCC+ sound chip. **/
|
||||
/*************************************************************/
|
||||
void WriteSCCP(register SCC *D,register byte R,register byte V)
|
||||
{
|
||||
register int J;
|
||||
register byte I;
|
||||
|
||||
/* Exit if no change */
|
||||
if(V==D->R[R]) return;
|
||||
|
||||
if((R&0xE0)==0xA0)
|
||||
{
|
||||
/* Emulate melodic features */
|
||||
|
||||
/* Save active channel mask in I */
|
||||
I=D->R[0xAF];
|
||||
/* Write to a register */
|
||||
R&=0xEF;
|
||||
D->R[R]=D->R[R+0x10]=V;
|
||||
|
||||
/* Melodic register number 0..15 */
|
||||
R&=0x0F;
|
||||
switch(R)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4:
|
||||
case 5: case 6: case 7: case 8: case 9:
|
||||
/* Exit if the channel is silenced */
|
||||
if(!(I&(1<<(R>>1)))) return;
|
||||
/* Go to the first register of the pair */
|
||||
R=(R&0xFE)+0xA0;
|
||||
/* Compute frequency */
|
||||
J=((int)(D->R[R+1]&0x0F)<<8)+D->R[R];
|
||||
/* Compute channel number */
|
||||
R=(R&0x0F)>>1;
|
||||
/* Assign frequency */
|
||||
D->Freq[R]=J? SCC_BASE/J:0;
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=1<<R;
|
||||
break;
|
||||
|
||||
case 10: case 11: case 12: case 13: case 14:
|
||||
/* Compute channel number */
|
||||
R-=10;
|
||||
/* Compute and assign new volume */
|
||||
D->Volume[R]=255*(V&0x0F)/15;
|
||||
/* Compute changed channels mask */
|
||||
D->Changed|=(1<<R)&I;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
/* Find changed channels */
|
||||
R=(V^I)&0x1F;
|
||||
D->Changed|=R;
|
||||
/* Update frequencies */
|
||||
for(I=0;R&&(I<SCC_CHANNELS);I++,R>>=1,V>>=1)
|
||||
if(R&1)
|
||||
{
|
||||
if(!(V&1)) D->Freq[I]=0;
|
||||
else
|
||||
{
|
||||
J=I*2+0xA0;
|
||||
J=((int)(D->R[J+1]&0x0F)<<8)+D->R[J];
|
||||
D->Freq[I]=J? SCC_BASE/J:0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Wrong register, do nothing */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Emulate wave table features */
|
||||
|
||||
/* Write data to SCC */
|
||||
D->R[R]=V;
|
||||
/* Wrong register, do nothing */
|
||||
if(R>=0xA0) return;
|
||||
/* Mark channel waveform as changed */
|
||||
D->WChanged|=1<<(R>>5);
|
||||
}
|
||||
|
||||
/* For asynchronous mode, make Sound() calls right away */
|
||||
if(!D->Sync&&(D->Changed||D->WChanged)) SyncSCC(D,SCC_FLUSH);
|
||||
}
|
||||
|
||||
/** SyncSCC() ************************************************/
|
||||
/** Flush all accumulated changes by issuing Sound() calls **/
|
||||
/** and set the synchronization on/off. The second argument **/
|
||||
/** should be SCC_SYNC/SCC_ASYNC to set/reset sync, or **/
|
||||
/** SCC_FLUSH to leave sync mode as it is. **/
|
||||
/*************************************************************/
|
||||
void SyncSCC(register SCC *D,register byte Sync)
|
||||
{
|
||||
register int J,I;
|
||||
|
||||
if(Sync!=SCC_FLUSH) D->Sync=Sync;
|
||||
|
||||
/* Modify waveforms */
|
||||
for(J=0,I=D->WChanged;I&&(J<SCC_CHANNELS);J++,I>>=1)
|
||||
if(I&1) SetWave(J+D->First,(signed char *)(D->R+(J<<5)),32,0);
|
||||
|
||||
/* Modify frequencies and volumes */
|
||||
for(J=0,I=D->Changed;I&&(J<SCC_CHANNELS);J++,I>>=1)
|
||||
if(I&1) Sound(J+D->First,D->Freq[J],D->Volume[J]);
|
||||
|
||||
D->Changed=D->WChanged=0x00;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue