Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

videodll.c

Go to the documentation of this file.
00001 
00012 #include "../dllkit/dllkit.h"
00013 #include "../usrmsgs.h"
00014 #include "resource.h"
00015 #include <stdio.h>
00016 #include <tchar.h>
00017 
00021 #define MYTIMER 10001 
00022 
00023 #define PERIOD 50
00024 
00029 #define FWIDTH 8
00030 
00031 #define FHEIGHT 8
00032 
00033 #define YCOUNT 32
00034 
00035 #define XCOUNT 32
00036 
00037 #define WIDTH FWIDTH * XCOUNT
00038 
00039 #define HEIGHT FHEIGHT * YCOUNT
00040 
00044 #define GRMODE IOLO + 0
00045 #define LOADR IOLO + 1
00046 #define HIADR IOLO + 2
00047 #define LOCHR IOLO + 3
00048 #define HICHR IOLO + 4
00049 #define FGCOLR IOLO + 5
00050 #define FGCOLG IOLO + 6
00051 #define FGCOLB IOLO + 7
00052 #define BKCOLR IOLO + 8
00053 #define BKCOLG IOLO + 9
00054 #define BKCOLB IOLO + 10
00055 #define VIDEOON IOLO + 14
00056 #define COMMAND IOLO + 15
00057 
00061 unsigned char volatile _GrMode = 0;
00062 unsigned char volatile _LoAdr = 0x00;
00063 unsigned char volatile _HiAdr = 0xA0;
00064 unsigned char volatile _LoChr = 0x00;
00065 unsigned char volatile _HiChr = 0xC0;
00066 unsigned char volatile _BkColR = 0xFF;
00067 unsigned char volatile _BkColG = 0xFF;
00068 unsigned char volatile _BkColB = 0xFF;
00069 unsigned char volatile _FgColR = 0x00;
00070 unsigned char volatile _FgColG = 0x00;
00071 unsigned char volatile _FgColB = 0x00;
00072 /* */
00073 unsigned char volatile GrMode = 0;
00074 unsigned char volatile LoAdr = 0x00;
00075 unsigned char volatile HiAdr = 0xA0;
00076 unsigned char volatile LoChr = 0x00;
00077 unsigned char volatile HiChr = 0xC0;
00078 unsigned char volatile VideoOn = 0;
00081 #define ADR(X, Y) (((X) << 8) + (Y))
00082 
00085 UINT memStart = 0xA000;
00087 UINT memChrStart = 0xC000;
00088 
00089 
00091 struct b4iheader {
00092         BITMAPV4HEADER bmiHeader; 
00093         RGBQUAD bmiColors[2];
00094 } bGrInfo;
00095 
00097 char* OffScreen;
00098 
00100 HBITMAP hLogo;
00102 HDC hOffDC;
00103 
00104 
00107 HANDLE hThisModule;
00108 MSGLIST VideoMsgs;
00109 volatile BOOL Running = FALSE;
00110 INITDLLSTRUCT info;
00114 /* ----- begin forward declarations */
00115 
00117 void InitGraphics();
00118 
00120 VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
00121 
00123 void Repaint();
00124 
00134 void PaintScreen(HDC hdc); 
00135 
00148 void CopyChar(char* dest, UINT adr, int x, int y, BOOL invert);
00149 
00150 /* ----- end forward declarations */
00151 
00152 BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, 
00153                                           LPVOID lpReserved)
00154 {
00155         hThisModule = hModule;
00156         switch (ul_reason_for_call) {
00157         case DLL_PROCESS_ATTACH:
00158                 CreateMsgList(&VideoMsgs, 5);
00159                 OffScreen = malloc(WIDTH * HEIGHT * sizeof(char) / 8);
00160                 hLogo = LoadBitmap(hThisModule, MAKEINTRESOURCE(IDB_LOGO));
00161                 VideoOn = FALSE;
00162                 break;
00163         case DLL_PROCESS_DETACH:
00164                 Running = FALSE;
00165                 KillTimer(info.hWnd, MYTIMER);
00166                 DeleteObject(hLogo);
00167                 DeleteDC(hOffDC);
00168                 free(OffScreen);
00170                 break;
00171         }       
00172     return TRUE;
00173 }
00174 
00175 DLLEXPORT void __cdecl InitDll(INITDLLSTRUCT* ids, INITDLLINFO* idi)
00176 {
00177         /* Add Message list of messages to be catched */
00178         AddMessage(VideoMsgs, WM_COMMAND);
00179         AddMessage(VideoMsgs, WM_PAINT);
00180         AddMessage(VideoMsgs, CPURUNNING);
00181         AddMessage(VideoMsgs, CPUSTOPPED);
00182         AddMessage(VideoMsgs, STOPVIDEO);
00183 
00184         /* Copy informations passed to this dll */
00185         info.CSMemory = ids->CSMemory;
00186         info.hInst = ids->hInst;
00187         info.hWnd = ids->hWnd;
00188         info.memory = ids->memory;
00189         info.memgetb = ids->memgetb;
00190         info.memsetb = ids->memsetb;
00191         info.optional = ids->optional;
00192         info.rcPaint = ids->rcPaint;
00193 
00194         /* Initialize graphics settings */
00195 
00196         InitGraphics();
00197 
00198         idi->iolo = IOLO + 0;
00199         idi->iohi = IOLO + 20;
00200         idi->msglist = VideoMsgs;
00201 }
00202 
00203 
00204 void InitGraphics()
00205 {
00206         bGrInfo.bmiHeader.bV4Size = sizeof(bGrInfo.bmiHeader);
00207         bGrInfo.bmiHeader.bV4Width = WIDTH;
00208         bGrInfo.bmiHeader.bV4Height = -HEIGHT;  //Nohama na zemi
00209         bGrInfo.bmiHeader.bV4Planes = 1;
00210         bGrInfo.bmiHeader.bV4BitCount = 1;
00211         bGrInfo.bmiHeader.bV4V4Compression = BI_RGB;
00212         bGrInfo.bmiHeader.bV4SizeImage = 0;
00213         bGrInfo.bmiHeader.bV4ClrUsed = 0;
00214         bGrInfo.bmiHeader.bV4ClrImportant = 0;
00215         bGrInfo.bmiHeader.bV4AlphaMask = 0;
00216         bGrInfo.bmiHeader.bV4CSType = LCS_WINDOWS_COLOR_SPACE;
00217         bGrInfo.bmiColors[0].rgbRed = 255;
00218         bGrInfo.bmiColors[0].rgbGreen = 255;
00219         bGrInfo.bmiColors[0].rgbBlue = 255;
00220         bGrInfo.bmiColors[1].rgbRed = 0;
00221         bGrInfo.bmiColors[1].rgbGreen = 0;
00222         bGrInfo.bmiColors[1].rgbBlue = 0;
00223 
00224         hOffDC = CreateCompatibleDC(GetDC(info.hWnd));
00225         SelectObject(hOffDC, hLogo);
00226 }
00227 
00228 
00229 DLLEXPORT void __cdecl OnMessage(MESSAGEDLLSTRUCT* mds)
00230 {
00231         int wmId, wmEvent;
00232         HDC hdc;
00233         PAINTSTRUCT ps;
00234         RECT rect;
00235 
00236         switch (mds->message) {
00237         case STOPVIDEO:
00238                 VideoOn = 0;
00239                 Repaint();
00240                 break;
00241         case CPURUNNING:
00242                 Running = TRUE;
00243                 Repaint();
00244                 SetTimer(info.hWnd, MYTIMER, PERIOD, &TimerProc);
00245                 break;
00246         case CPUSTOPPED:
00247                 Running = FALSE;
00248                 KillTimer(info.hWnd, MYTIMER);
00249                 Repaint();
00250         case WM_COMMAND:
00251                 wmId = LOWORD(mds->wParam); 
00252                 wmEvent = HIWORD(mds->wParam); 
00253                 break;
00254         case WM_PAINT:
00255 
00256                 hdc = BeginPaint(info.hWnd, &ps);
00257                 
00258                 if (Running == TRUE) {
00259                         if (VideoOn != 0) {
00260                                 PaintScreen(hdc);
00261                         }
00262                         else {
00263                                 GetClientRect(info.hWnd, &rect);
00264                                 FillRect(hdc, &rect, (HBRUSH) (COLOR_APPWORKSPACE+1));
00265                         }
00266                 }
00267                 else {
00268                         BitBlt(hdc, info.rcPaint.left, info.rcPaint.top, 256, 256, hOffDC, 0, 0, SRCCOPY);
00269                 }
00270                 EndPaint(info.hWnd, &ps);
00271                 break;
00272         }
00273 }
00274 
00275 VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, 
00276                                                 DWORD dwTime)
00277 {
00278         if (VideoOn == 0) {
00279                 return;
00280         }
00281 
00282         Repaint();
00283         (*info.memsetb)(ISVBI, 1);
00284         SendMessage(info.hWnd, NMIMSG, 0, 0);
00285 }
00286 
00287 void Repaint()
00288 {
00289         InvalidateRect(info.hWnd, &(info.rcPaint), FALSE);
00290     UpdateWindow(info.hWnd);
00291 }
00292 
00293 #define IOSETGET(GVAR, SVAR) \
00294         if (mode == IOREAD) {   \
00295                 *data = GVAR;   \
00296         }       \
00297         else {  \
00298                 SVAR = *data;   \
00299         }
00300 
00301 DLLEXPORT void __cdecl IOFunc(UINT adr, unsigned char* data, 
00302                                                                                   iomode mode)
00303 {
00304         switch (adr) {
00305         case GRMODE:
00306                 IOSETGET(GrMode, _GrMode);
00307                 break;
00308         case LOADR:
00309                 IOSETGET(LoAdr, _LoAdr);
00310                 break;
00311         case HIADR:
00312                 IOSETGET(HiAdr, _HiAdr);
00313                 break;
00314         case BKCOLR:
00315                 IOSETGET(bGrInfo.bmiColors[0].rgbRed, _BkColR);
00316                 break;
00317         case BKCOLG:
00318                 IOSETGET(bGrInfo.bmiColors[0].rgbGreen, _BkColG);
00319                 break;
00320         case BKCOLB:
00321                 IOSETGET(bGrInfo.bmiColors[0].rgbBlue, _BkColB);
00322                 break;
00323         case FGCOLR:
00324                 IOSETGET(bGrInfo.bmiColors[1].rgbRed, _FgColR);
00325                 break;
00326         case FGCOLG:
00327                 IOSETGET(bGrInfo.bmiColors[1].rgbGreen, _FgColG);
00328                 break;
00329         case FGCOLB:
00330                 IOSETGET(bGrInfo.bmiColors[1].rgbBlue, _FgColB);
00331                 break;
00332         case LOCHR:
00333                 IOSETGET(LoChr, _LoChr);
00334                 break;
00335         case HICHR:
00336                 IOSETGET(HiChr, _HiChr);
00337                 break;
00338         case VIDEOON:
00339                 IOSETGET(VideoOn, VideoOn);
00340                 if (VideoOn == 0) {
00341                                 InvalidateRect(info.hWnd, &(info.rcPaint), FALSE);
00342                                 UpdateWindow(info.hWnd);
00343                 }
00344                 break;
00345         case COMMAND:
00346                 if (mode == IOREAD) {
00347                         *data = 0;
00348                 }
00349                 else {
00350                         GrMode = _GrMode;
00351                         LoAdr = _LoAdr;
00352                         HiAdr = _HiAdr;
00353                         LoChr = _LoChr;
00354                         HiChr = _HiChr;
00355                         memStart = ADR(HiAdr, LoAdr);
00356                         memChrStart = ADR(HiChr, LoChr);
00357 
00358                         bGrInfo.bmiColors[0].rgbRed = _BkColR;
00359                         bGrInfo.bmiColors[0].rgbGreen  = _BkColG;
00360                         bGrInfo.bmiColors[0].rgbBlue  = _BkColB;
00361                         bGrInfo.bmiColors[1].rgbRed = _FgColR;
00362                         bGrInfo.bmiColors[1].rgbGreen = _FgColG;
00363                         bGrInfo.bmiColors[1].rgbBlue = _FgColB;
00364                 }
00365                 break;
00366         }
00367 }
00368 
00369 void PaintScreen(HDC hdc)
00370 {
00371         UINT i, ic, j, jc;
00372         unsigned char data;
00373 
00374         switch(GrMode) {
00375         case 0:         /* TEXT MODE */
00376                 for(i = 0, ic = 0;      ic < XCOUNT; 
00377                                 i += FWIDTH, ic++) {
00378                         for(j = 0, jc = 0; jc < YCOUNT; 
00379                                         j += FHEIGHT, jc++) {
00380                                 data = (*info.memgetb)(memStart + ic + jc * XCOUNT);
00381                                 CopyChar(OffScreen, memChrStart + data * 8, 
00382                                         i, j, (data < 128) ? FALSE : TRUE);
00383                         }
00384                 }
00385                 SetDIBitsToDevice(hdc, info.rcPaint.left, info.rcPaint.top, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, (void*) OffScreen, (BITMAPINFO*) &bGrInfo, DIB_RGB_COLORS);
00386                 //SetDIBitsToDevice(hdc, 0, 0, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, (void*) OffScreen, (BITMAPINFO*) &bGrInfo, DIB_RGB_COLORS);
00387                 break;
00388         case 1:         /* GRAPHICS MODE */
00389                 EnterCriticalSection(&info.CSMemory);
00390                 SetDIBitsToDevice(hdc, info.rcPaint.left, info.rcPaint.top, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, (void*) (info.memory + memStart), (BITMAPINFO*) &bGrInfo, DIB_RGB_COLORS);
00391                 LeaveCriticalSection(&info.CSMemory);
00392                 break;
00393         }
00394 }
00395 
00396 void CopyChar(char* dest, UINT adr, int x, int y, BOOL invert)
00397 {
00398         int i;
00399         for (i = 0; i < FHEIGHT; i++) {
00400                 if (invert == FALSE) {
00401                         dest[(y + i) * (WIDTH / 8) + x / 8] = (*info.memgetb)(adr + i);
00402                 }
00403                 else {
00404                         dest[(y + i) * (WIDTH / 8) + x / 8] = ~(*info.memgetb)(adr + i - 128 * 8);
00405                 }
00406         }
00407 }

Generated on Fri Sep 6 18:32:15 2002 for Emu6502 by doxygen1.2.17