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, 4);
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_PAINT);
00179 AddMessage(VideoMsgs, CPURUNNING);
00180 AddMessage(VideoMsgs, CPUSTOPPED);
00181 AddMessage(VideoMsgs, STOPVIDEO);
00182
00183
00184 info.CSMemory = ids->CSMemory;
00185 info.hInst = ids->hInst;
00186 info.hWnd = ids->hWnd;
00187 info.memory = ids->memory;
00188 info.memgetb = ids->memgetb;
00189 info.memsetb = ids->memsetb;
00190 info.optional = ids->optional;
00191 info.rcPaint = ids->rcPaint;
00192
00193
00194
00195 InitGraphics();
00196
00197 idi->iolo = IOLO + 0;
00198 idi->iohi = IOLO + 20;
00199 idi->msglist = VideoMsgs;
00200 }
00201
00202
00203 void InitGraphics()
00204 {
00205 bGrInfo.bmiHeader.bV4Size = sizeof(bGrInfo.bmiHeader);
00206 bGrInfo.bmiHeader.bV4Width = WIDTH;
00207 bGrInfo.bmiHeader.bV4Height = -HEIGHT;
00208 bGrInfo.bmiHeader.bV4Planes = 1;
00209 bGrInfo.bmiHeader.bV4BitCount = 1;
00210 bGrInfo.bmiHeader.bV4V4Compression = BI_RGB;
00211 bGrInfo.bmiHeader.bV4SizeImage = 0;
00212 bGrInfo.bmiHeader.bV4ClrUsed = 0;
00213 bGrInfo.bmiHeader.bV4ClrImportant = 0;
00214 bGrInfo.bmiHeader.bV4AlphaMask = 0;
00215 bGrInfo.bmiHeader.bV4CSType = LCS_WINDOWS_COLOR_SPACE;
00216 bGrInfo.bmiColors[0].rgbRed = 255;
00217 bGrInfo.bmiColors[0].rgbGreen = 255;
00218 bGrInfo.bmiColors[0].rgbBlue = 255;
00219 bGrInfo.bmiColors[1].rgbRed = 0;
00220 bGrInfo.bmiColors[1].rgbGreen = 0;
00221 bGrInfo.bmiColors[1].rgbBlue = 0;
00222
00223 hOffDC = CreateCompatibleDC(GetDC(info.hWnd));
00224 SelectObject(hOffDC, hLogo);
00225 }
00226
00227
00228 DLLEXPORT void __cdecl OnMessage(MESSAGEDLLSTRUCT* mds)
00229 {
00230 int wmId, wmEvent;
00231 HDC hdc;
00232 PAINTSTRUCT ps;
00233 RECT rect;
00234
00235 switch (mds->message) {
00236 case STOPVIDEO:
00237 VideoOn = 0;
00238 Repaint();
00239 break;
00240 case CPURUNNING:
00241 Running = TRUE;
00242 Repaint();
00243 SetTimer(info.hWnd, MYTIMER, PERIOD, &TimerProc);
00244 break;
00245 case CPUSTOPPED:
00246 Running = FALSE;
00247 KillTimer(info.hWnd, MYTIMER);
00248 Repaint();
00249 break;
00250 case WM_PAINT:
00251
00252 hdc = BeginPaint(info.hWnd, &ps);
00253
00254 if (Running == TRUE) {
00255 if (VideoOn != 0) {
00256 PaintScreen(hdc);
00257 }
00258 else {
00259 GetClientRect(info.hWnd, &rect);
00260 FillRect(hdc, &rect, (HBRUSH) (COLOR_APPWORKSPACE+1));
00261 }
00262 }
00263 else {
00264 BitBlt(hdc, info.rcPaint.left, info.rcPaint.top, 256, 256, hOffDC, 0, 0, SRCCOPY);
00265 }
00266 EndPaint(info.hWnd, &ps);
00267 break;
00268 }
00269 }
00270
00271 VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent,
00272 DWORD dwTime)
00273 {
00274 if (VideoOn == 0) {
00275 return;
00276 }
00277
00278 Repaint();
00279 (*info.memsetb)(ISVBI, 1);
00280 SendMessage(info.hWnd, NMIMSG, 0, 0);
00281 }
00282
00283 void Repaint()
00284 {
00285 InvalidateRect(info.hWnd, &(info.rcPaint), FALSE);
00286 UpdateWindow(info.hWnd);
00287 }
00288
00289 #define IOSETGET(GVAR, SVAR) \
00290 if (mode == IOREAD) { \
00291 *data = GVAR; \
00292 } \
00293 else { \
00294 SVAR = *data; \
00295 }
00296
00297 DLLEXPORT void __cdecl IOFunc(UINT adr, unsigned char* data,
00298 iomode mode)
00299 {
00300 switch (adr) {
00301 case GRMODE:
00302 IOSETGET(GrMode, _GrMode);
00303 break;
00304 case LOADR:
00305 IOSETGET(LoAdr, _LoAdr);
00306 break;
00307 case HIADR:
00308 IOSETGET(HiAdr, _HiAdr);
00309 break;
00310 case BKCOLR:
00311 IOSETGET(bGrInfo.bmiColors[0].rgbRed, _BkColR);
00312 break;
00313 case BKCOLG:
00314 IOSETGET(bGrInfo.bmiColors[0].rgbGreen, _BkColG);
00315 break;
00316 case BKCOLB:
00317 IOSETGET(bGrInfo.bmiColors[0].rgbBlue, _BkColB);
00318 break;
00319 case FGCOLR:
00320 IOSETGET(bGrInfo.bmiColors[1].rgbRed, _FgColR);
00321 break;
00322 case FGCOLG:
00323 IOSETGET(bGrInfo.bmiColors[1].rgbGreen, _FgColG);
00324 break;
00325 case FGCOLB:
00326 IOSETGET(bGrInfo.bmiColors[1].rgbBlue, _FgColB);
00327 break;
00328 case LOCHR:
00329 IOSETGET(LoChr, _LoChr);
00330 break;
00331 case HICHR:
00332 IOSETGET(HiChr, _HiChr);
00333 break;
00334 case VIDEOON:
00335 IOSETGET(VideoOn, VideoOn);
00336 if (VideoOn == 0) {
00337 InvalidateRect(info.hWnd, &(info.rcPaint), FALSE);
00338 UpdateWindow(info.hWnd);
00339 }
00340 break;
00341 case COMMAND:
00342 if (mode == IOREAD) {
00343 *data = 0;
00344 }
00345 else {
00346 GrMode = _GrMode;
00347 LoAdr = _LoAdr;
00348 HiAdr = _HiAdr;
00349 LoChr = _LoChr;
00350 HiChr = _HiChr;
00351 memStart = ADR(HiAdr, LoAdr);
00352 memChrStart = ADR(HiChr, LoChr);
00353
00354 bGrInfo.bmiColors[0].rgbRed = _BkColR;
00355 bGrInfo.bmiColors[0].rgbGreen = _BkColG;
00356 bGrInfo.bmiColors[0].rgbBlue = _BkColB;
00357 bGrInfo.bmiColors[1].rgbRed = _FgColR;
00358 bGrInfo.bmiColors[1].rgbGreen = _FgColG;
00359 bGrInfo.bmiColors[1].rgbBlue = _FgColB;
00360 }
00361 break;
00362 }
00363 }
00364
00365 void PaintScreen(HDC hdc)
00366 {
00367 UINT i, ic, j, jc;
00368 unsigned char data;
00369
00370 switch(GrMode) {
00371 case 0:
00372 for(i = 0, ic = 0; ic < XCOUNT;
00373 i += FWIDTH, ic++) {
00374 for(j = 0, jc = 0; jc < YCOUNT;
00375 j += FHEIGHT, jc++) {
00376 data = (*info.memgetb)(memStart + ic + jc * XCOUNT);
00377 CopyChar(OffScreen, memChrStart + data * 8,
00378 i, j, (data < 128) ? FALSE : TRUE);
00379 }
00380 }
00381 SetDIBitsToDevice(hdc, info.rcPaint.left, info.rcPaint.top, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, (void*) OffScreen, (BITMAPINFO*) &bGrInfo, DIB_RGB_COLORS);
00382
00383 break;
00384 case 1:
00385 EnterCriticalSection(&info.CSMemory);
00386 SetDIBitsToDevice(hdc, info.rcPaint.left, info.rcPaint.top, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, (void*) (info.memory + memStart), (BITMAPINFO*) &bGrInfo, DIB_RGB_COLORS);
00387 LeaveCriticalSection(&info.CSMemory);
00388 break;
00389 }
00390 }
00391
00392 void CopyChar(char* dest, UINT adr, int x, int y, BOOL invert)
00393 {
00394 int i;
00395 for (i = 0; i < FHEIGHT; i++) {
00396 if (invert == FALSE) {
00397 dest[(y + i) * (WIDTH / 8) + x / 8] = (*info.memgetb)(adr + i);
00398 }
00399 else {
00400 dest[(y + i) * (WIDTH / 8) + x / 8] = ~(*info.memgetb)(adr + i - 128 * 8);
00401 }
00402 }
00403 }