445 lines
10 KiB
C
445 lines
10 KiB
C
// nonstandard extension used : nameless struct/union
|
|
#pragma warning (disable : 4201)
|
|
// unreferenced inline function has been removed
|
|
#pragma warning (disable : 4514)
|
|
|
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
|
#include <windows.h>
|
|
#include "emul.h"
|
|
#include <tchar.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <windef.h>
|
|
|
|
|
|
// Global Variables:
|
|
static TCHAR *szWindowClass = _T("ConsoleW");
|
|
static HWND hWnd = NULL;
|
|
static HANDLE hThread = NULL;
|
|
static HANDLE hThreadKB = NULL;
|
|
static HANDLE hKeyLock = NULL;
|
|
static int iMainRetVal = -1;
|
|
static int ZOOM = 1;
|
|
|
|
#define KEY_BUFFER_LENGTH 16
|
|
|
|
typedef struct
|
|
{
|
|
int miKeyBuffer[KEY_BUFFER_LENGTH];
|
|
int miKeyUsed;
|
|
HANDLE mhEvent;
|
|
}GETCH_CONTEXT;
|
|
|
|
|
|
static GETCH_CONTEXT gGetchContext = {0};
|
|
|
|
static LRESULT CALLBACK MsgHandler(HWND,UINT,WPARAM,LPARAM);
|
|
static LRESULT CALLBACK EditBoxMsgHandler(HWND,UINT,WPARAM,LPARAM);
|
|
|
|
|
|
static DWORD __stdcall ThreadProc(void *pContext);
|
|
|
|
static void ConsoleWrite(IN const char *pszText);
|
|
void KeyHandler(int iKey)
|
|
{
|
|
/*if(iKey == VK_RETURN)
|
|
{
|
|
iKey = '\n';
|
|
}*/
|
|
WaitForSingleObject(hKeyLock,INFINITE);
|
|
if(gGetchContext.miKeyUsed < KEY_BUFFER_LENGTH)
|
|
{
|
|
gGetchContext.miKeyBuffer[gGetchContext.miKeyUsed] = iKey;
|
|
gGetchContext.miKeyUsed++;
|
|
}
|
|
SetEvent(gGetchContext.mhEvent);
|
|
ReleaseMutex(hKeyLock);
|
|
}
|
|
|
|
int main(int argc,char *argv[])
|
|
{
|
|
MSG msg;
|
|
{
|
|
WNDCLASS wcex = {0};
|
|
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
|
wcex.lpfnWndProc = MsgHandler;
|
|
wcex.cbClsExtra = 0;
|
|
wcex.cbWndExtra = 0;
|
|
wcex.hInstance = NULL;
|
|
wcex.hIcon = NULL;
|
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wcex.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
|
|
wcex.lpszMenuName = NULL;
|
|
wcex.lpszClassName = szWindowClass;
|
|
RegisterClass(&wcex);
|
|
}
|
|
|
|
hKeyLock = CreateMutex(NULL,0,NULL);
|
|
gGetchContext.mhEvent = CreateEvent(NULL,1,0,NULL);
|
|
|
|
hWnd = CreateWindow(szWindowClass, "Display", WS_OVERLAPPED,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, 0, NULL);
|
|
if (!hWnd)
|
|
{
|
|
return 0;
|
|
}
|
|
ShowWindow(hWnd, SW_SHOW);
|
|
SetWindowPos(hWnd,NULL,0,0,WIDTH*ZOOM+8,HEIGHT*ZOOM+23+4,SWP_NOMOVE|SWP_NOZORDER);
|
|
UpdateWindow(hWnd);
|
|
|
|
while (GetMessage(&msg, hWnd, 0, 0))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
CloseHandle(hKeyLock);
|
|
CloseHandle(gGetchContext.mhEvent);
|
|
CloseHandle(hThread);
|
|
CloseHandle(hThreadKB);
|
|
DestroyWindow(hWnd);
|
|
|
|
|
|
return iMainRetVal;
|
|
}
|
|
|
|
unsigned short VRAM1[WIDTH * HEIGHT] = {0};
|
|
unsigned short VRAM2[WIDTH * HEIGHT] = {0};
|
|
|
|
/*#if ((sizeof(void *)) != 4)
|
|
#error "only 32 bit platform is supported"
|
|
#endif
|
|
*/
|
|
unsigned int GetVRAMAddress( void )
|
|
{
|
|
return (int) ((void*)VRAM1);
|
|
}
|
|
|
|
static void Redraw(HWND hWnd)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hDC;
|
|
int a,b,x,y,i=0;
|
|
hDC = BeginPaint(hWnd, &ps);
|
|
|
|
for(y=0;y<HEIGHT;y++)
|
|
for(x=0;x<WIDTH;x++)
|
|
{
|
|
COLORREF c = 0;
|
|
BYTE *bc = (BYTE*)&c;
|
|
WORD p = VRAM1[i];
|
|
|
|
bc[0] = ((p >> 11) & 31)<<3;
|
|
bc[1] = ((p >> 5) & 63)<<2;
|
|
bc[2] = ((p >> 0) & 31)<<3;
|
|
for(a=0;a<ZOOM;a++)
|
|
{
|
|
for(b=0;b<ZOOM;b++)
|
|
{
|
|
SetPixel(hDC,x*ZOOM+b,y*ZOOM+a,c);
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
EndPaint(hWnd, &ps);
|
|
}
|
|
|
|
static void Redraw2(HWND hWnd)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hDC;
|
|
int a,b,x,y,i=0;
|
|
hDC = BeginPaint(hWnd, &ps);
|
|
|
|
for(y=0;y<HEIGHT;y++)
|
|
for(x=0;x<WIDTH;x++)
|
|
{
|
|
COLORREF c = 0;
|
|
BYTE *bc = (BYTE*)&c;
|
|
WORD p = VRAM1[i];
|
|
if(p != VRAM2[i])
|
|
{
|
|
bc[0] = ((p >> 11) & 31)<<3;
|
|
bc[1] = ((p >> 5) & 63)<<2;
|
|
bc[2] = ((p >> 0) & 31)<<3;
|
|
for(a=0;a<ZOOM;a++)
|
|
{
|
|
for(b=0;b<ZOOM;b++)
|
|
{
|
|
SetPixel(hDC,x*ZOOM+b,y*ZOOM+a,c);
|
|
}
|
|
}
|
|
VRAM2[i] = p;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
EndPaint(hWnd, &ps);
|
|
}
|
|
|
|
DWORD __stdcall KeyboardFunc(void *p);
|
|
static int giOptimize = 0;
|
|
static int giIsRedraw = 0;
|
|
static LRESULT CALLBACK MsgHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(message)
|
|
{
|
|
case WM_CREATE:
|
|
hThread = CreateThread(NULL,0,&ThreadProc,NULL,0,NULL);
|
|
hThreadKB = CreateThread(NULL,0,&KeyboardFunc,NULL,0,NULL);
|
|
break;
|
|
case WM_SIZE:
|
|
break;
|
|
case WM_CHAR:
|
|
//KeyHandler((int)wParam);
|
|
break;
|
|
case WM_CLOSE:
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
break;
|
|
case WM_PAINT:
|
|
//if(giOptimize)
|
|
Redraw2(hWnd);
|
|
giIsRedraw = 1;
|
|
//else
|
|
// Redraw(hWnd);
|
|
//giOptimize = 0;
|
|
break;
|
|
case WM_RBUTTONUP://switch zoom 1x <-> 2x
|
|
ZOOM = 3 - ZOOM;
|
|
SetWindowPos(hWnd,NULL,0,0,WIDTH*ZOOM+8,HEIGHT*ZOOM+23+4,SWP_NOMOVE|SWP_NOZORDER);
|
|
memset(VRAM2,0,sizeof(VRAM2));
|
|
InvalidateRect(hWnd,NULL,FALSE);
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
int Consolekbhit()
|
|
{
|
|
return WaitForSingleObject(gGetchContext.mhEvent,0) == WAIT_OBJECT_0;
|
|
}
|
|
int Consolegetch()
|
|
{
|
|
int iResult;
|
|
WaitForSingleObject(gGetchContext.mhEvent,INFINITE);
|
|
WaitForSingleObject(hKeyLock,INFINITE);
|
|
gGetchContext.miKeyUsed--;
|
|
iResult = gGetchContext.miKeyBuffer[gGetchContext.miKeyUsed];
|
|
if(gGetchContext.miKeyUsed == 0)
|
|
{
|
|
ResetEvent(gGetchContext.mhEvent);
|
|
}
|
|
ReleaseMutex(hKeyLock);
|
|
return iResult;
|
|
}
|
|
|
|
static DWORD __stdcall ThreadProc(void *pContext)
|
|
{
|
|
G3A_main();
|
|
PostMessage(hWnd, WM_CLOSE, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
void Bdisp_PutDisp_DD()
|
|
{
|
|
//Redraw2(hWnd);
|
|
giOptimize = 1;
|
|
giIsRedraw = 0;
|
|
InvalidateRect(hWnd,NULL,FALSE);
|
|
while(!giIsRedraw)Sleep(1);
|
|
}
|
|
|
|
extern int iKeyDown;
|
|
int PRGM_GetKey()
|
|
{
|
|
/*if(Consolekbhit())
|
|
{
|
|
return Consolegetch();
|
|
}*/
|
|
return iKeyDown;
|
|
}
|
|
|
|
|
|
void Bdisp_AllClr_VRAM( void )
|
|
{
|
|
memset(VRAM1,0,sizeof(VRAM1));
|
|
}
|
|
|
|
HANDLE ghPort = 0;
|
|
int Serial_Open( unsigned char *mode )
|
|
{
|
|
DWORD dwMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT;
|
|
ghPort = CreateFileA(
|
|
"\\\\.\\pipe\\seriak", // pipe name \\.\pipe\seriak
|
|
GENERIC_READ | // read and write access
|
|
GENERIC_WRITE,
|
|
0, // no sharing
|
|
NULL, // default security attributes
|
|
OPEN_EXISTING, // opens existing pipe
|
|
FILE_FLAG_WRITE_THROUGH, // default attributes
|
|
NULL); // no template file
|
|
|
|
|
|
SetNamedPipeHandleState(
|
|
ghPort, // pipe handle
|
|
&dwMode, // new pipe mode
|
|
NULL, // don't set maximum bytes
|
|
NULL); // don't set maximum time
|
|
return 0;
|
|
}
|
|
|
|
int Serial_Close( int mode )
|
|
{
|
|
CloseHandle(ghPort);
|
|
return 0;
|
|
}
|
|
|
|
int Serial_DirectTransmitOneByte( unsigned char byte_to_transmit )
|
|
{
|
|
DWORD dwSent;
|
|
WriteFile(ghPort,&byte_to_transmit,sizeof(byte_to_transmit),&dwSent,NULL);
|
|
return 0;
|
|
}
|
|
|
|
int Serial_CheckRX()
|
|
{
|
|
DWORD dwData = 0;
|
|
PeekNamedPipe(ghPort,NULL,0,0,&dwData,NULL);
|
|
//if(!dwData)Sleep(1);
|
|
return (int)dwData;
|
|
}
|
|
|
|
unsigned char Serial_Read()
|
|
{
|
|
DWORD dwData = 0;
|
|
BYTE byData;
|
|
ReadFile(ghPort,&byData,1,&dwData,NULL);
|
|
return byData;
|
|
}
|
|
|
|
|
|
//Returns the RTC-basecount in units of 1/128 s.
|
|
int RTC_GetTicks( void )
|
|
{
|
|
return GetTickCount()>> 3;//1000/128 is very near to 1000/125
|
|
}
|
|
|
|
//start_value has to be set with RTC_GetTicks.
|
|
//duration_in_ms is the duration, which has to elapse since start_value.
|
|
//returns 0 if duration_in_ms has not elapsed yet
|
|
//returns 1 if duration_in_ms has elapsed
|
|
|
|
int RTC_Elapsed_ms( int start_value, int duration_in_ms )
|
|
{
|
|
return (GetTickCount() - duration_in_ms) > (start_value << 3);
|
|
}
|
|
|
|
void assert(int iLine,const char *pszFilename,const char *pszAassert)
|
|
{
|
|
static int iDoAssert = 1;
|
|
printf("assert %s,%i: %s\n",pszFilename,iLine,pszAassert);
|
|
if(iDoAssert)
|
|
{
|
|
iDoAssert = 0;
|
|
}
|
|
}
|
|
|
|
//files
|
|
//int hFile = Bfile_OpenFile_OS(pFileName,0);
|
|
int Bfile_OpenFile_OS( const unsigned short*filename, int mode )
|
|
{
|
|
FILE *f;
|
|
char szFileName[1024];
|
|
int i = 0;
|
|
filename += 7;//\\fls0\
|
|
while(filename[0])
|
|
{
|
|
szFileName[i] = (char)filename[0];
|
|
filename++;i++;
|
|
}
|
|
szFileName[i] = 0;
|
|
f = fopen(szFileName,"rb");
|
|
return f?(int)f:-1;
|
|
}
|
|
|
|
int Bfile_SeekFile_OS( int HANDLE, int pos )
|
|
{
|
|
fseek((FILE*)HANDLE,pos,SEEK_SET);
|
|
return 0;
|
|
}
|
|
|
|
int Bfile_ReadFile_OS( int HANDLE, void *buf, int size, int readpos )
|
|
{
|
|
if(readpos != -1)
|
|
{
|
|
Bfile_SeekFile_OS(HANDLE, readpos );
|
|
}
|
|
//fread ( dest, size elements, count elements, FILE handle );
|
|
return fread(buf,1,size,(FILE*)HANDLE);
|
|
}
|
|
|
|
int Bfile_CloseFile_OS( int HANDLE )
|
|
{
|
|
fclose((FILE*)HANDLE);
|
|
return 0;
|
|
}
|
|
|
|
static unsigned char gcFlashBuffer[FLASH_PAGE_SIZE * FLASH_PAGE_COUNT] = {0};
|
|
const unsigned char *gpcFlashBuffer = gcFlashBuffer;
|
|
|
|
static const char *gpszFlashFileName = "flash.bin";
|
|
static void CreateFlash( const unsigned short*filename)
|
|
{
|
|
int f = Bfile_OpenFile_OS(filename,0);
|
|
int iRet;
|
|
int iIndex = 0;
|
|
|
|
for(;;)
|
|
{
|
|
// iIndex++;
|
|
|
|
iRet = Bfile_ReadFile_OS(f,gcFlashBuffer + (iIndex * FLASH_PAGE_SIZE), FLASH_PAGE_SIZE,-1);
|
|
iIndex++;
|
|
if(iRet < FLASH_PAGE_SIZE)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
Bfile_CloseFile_OS(f);
|
|
{
|
|
FILE *f = fopen(gpszFlashFileName,"wb");
|
|
fwrite(gcFlashBuffer,1,sizeof(gcFlashBuffer),f);
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
void InitFlashSimu( const unsigned short*filename)
|
|
{
|
|
DWORD dwFileSize;
|
|
HANDLE hMap;
|
|
HANDLE hFile=CreateFileA(gpszFlashFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
|
if(hFile==INVALID_HANDLE_VALUE)
|
|
{
|
|
CreateFlash( filename);
|
|
hFile=CreateFileA(gpszFlashFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
|
|
};
|
|
ASSERT(hFile!=INVALID_HANDLE_VALUE);
|
|
|
|
// create anonymous file mapping
|
|
hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
|
|
ASSERT(hMap!=NULL);
|
|
|
|
dwFileSize=GetFileSize(hFile,NULL); // get file size
|
|
|
|
// map buffer to local process space
|
|
gpcFlashBuffer =(unsigned char *)MapViewOfFile(hMap,FILE_MAP_READ,0,0,dwFileSize);
|
|
ASSERT(gpcFlashBuffer!=NULL);
|
|
} |