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
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
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
00178 AddMessage(VideoMsgs, WM_COMMAND);
00179 AddMessage(VideoMsgs, WM_PAINT);
00180 AddMessage(VideoMsgs, CPURUNNING);
00181 AddMessage(VideoMsgs, CPUSTOPPED);
00182 AddMessage(VideoMsgs, STOPVIDEO);
00183
00184
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
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;
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:
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
00387 break;
00388 case 1:
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 }