Код:
#define DEBUG_ENB 1
#if DEBUG_ENB
#include <stdarg.h>
#define DEBUG(...) realdprintf(__FILE__, __LINE__, __func__, __VA_ARGS__)
#else
#define DEBUG(...)
#endif
void realdprintf (char const *file, int line, char const *func, unsigned delay, char const *format, ...);
/*
There may be global variables and user-defined functions, for example
int a, b, c;
void Test(void) {
PSW[256] = PSW[256] + 1;
return;
}
etc...
*/
/* DEBUG Print */
void realdprintf (char const *file, int line, char const *func, unsigned delay, char const *format, ...)
{
#define winNo 5004 //Debug window number
#define LTOTAL 6 //Number of lines in the debug window
#define CTOTAL 56 //Number of characters in one line of the debug window
#define INPUT PSW[136] //Window control buttons
#define SCRADDR PSW[139] //Initial address of the screen buffer
#define TIC (*(DWORD*) (PSW + 38)) //System timer
#define TABS 8
#define OK 0
#define LEFT 1
#define RIGHT 2
#define KbdStatus(bitno) ((INPUT) & (1 << (bitno)))
#define FORWARD 1
#define BACKWARD -1
char *pBuffScr;
char *pBuffPrint = Malloc((LTOTAL -1) * CTOTAL);
BYTE *saveREGS = Malloc(LTOTAL * CTOTAL);
WORD saveREG1, saveREG2;
static int Xpos = 0, Ypos = 0;
register int t, len2;
int len1, len3, dir;
unsigned long tm;
va_list arg;
/* Save working registers */
saveREG1 = INPUT;
saveREG2 = SCRADDR;
/* Calculate the initial address of the screen buffer */
SCRADDR = PSW[10] - LTOTAL * CTOTAL/2;
pBuffScr = (char*) &PSW[SCRADDR];
/* Save the registers of the screen buffer area */
memcpy(saveREGS, pBuffScr, LTOTAL * CTOTAL);
/* Clear screen buffer */
memset(pBuffScr, ' ', LTOTAL * CTOTAL);
/* Print to screen line #1 */
len1 = sprintf(pBuffScr, "> %s line %d in %s ", func, line, file);
len2 = CTOTAL + Max(0, len1-CTOTAL);
/* remaining print lines in the buffer */
va_start(arg, format);
len3 = vsnprintf (pBuffPrint, LTOTAL * CTOTAL - len2 - 1, format, arg);
va_end(arg);
pBuffPrint[len3] = '\0';
/* Display buffer on screen */
t= 0;
do {
switch(pBuffPrint[t]) {
case '\a': //Bell
Beep();
break;
case '\t': //Tab
len2 = len2 - len2 % TABS + TABS;
break;
case '\n': //LF
len2 = len2 - len2 % CTOTAL + CTOTAL;
break;
default:
pBuffScr[len2] = pBuffPrint[t];
len2++;
}
t++;
} while (pBuffPrint[t] !=0 && len2 < (LTOTAL * CTOTAL));
/* Call the debug window and control its position */
dir = FORWARD;
tm = TIC;
while(!(KbdStatus(OK) || (delay !=0 && (TIC-tm) >= delay*10)) ) {
if (KbdStatus(RIGHT)) {
tm = TIC;
CloseWindow(winNo);
Xpos = Xpos + 100;
}
if (KbdStatus(LEFT)) {
tm = TIC;
CloseWindow(winNo);
Xpos = Xpos - 100;
if (Xpos < 0) {
Xpos = 0;
Ypos = Ypos + dir * 100;
}
if (Ypos == 400) dir = BACKWARD;
if (Ypos == 0) dir = FORWARD;
}
OpenWindow(winNo, Xpos, Ypos);
INPUT = 0;
Delay(10);
}
CloseWindow(winNo);
/* Restore working registers */
memcpy(pBuffScr, saveREGS, LTOTAL * CTOTAL);
INPUT = saveREG1;
SCRADDR = saveREG2;
/* Deallocate memory blocks */
Free(pBuffPrint);
Free(saveREGS);
}