convert line ends
[canaan.git] / prj / tech / libsrc / mprintf / mprintf.c
blobaeb3ef1437c31383390aa38aa933978c8ff8397c
1 /*
2 * $Source: x:/prj/tech/libsrc/mprintf/RCS/mprintf.c $
3 * $Revision: 1.23 $
4 * $Author: TOML $
5 * $Date: 1997/07/28 19:25:35 $
7 * Monochrome printf.
8 */
10 /* things to do - logon/logoff w/o destroying fname */
12 #include <conio.h>
13 #include <io.h>
14 #include <fcntl.h>
15 #include <dos.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys\stat.h>
20 #ifdef _MSC_VER
21 #include <msconv.h>
22 #endif
23 #include <lgsprntf.h>
24 #include <mprintf.h>
25 #include <coremutx.h>
27 #define MONO_BASE 0xb0000
28 #define CGA_BASE 0xb8000
29 #define MONO_PAGE_SZ 0x01000
31 #define MONO_CARD 0
32 #define CGA_CARD 1
34 /* video bios constants. */
35 #define VBIOS_INT 0x10
36 #define VB_GET_COMBO 0x1a00
37 #define VB_SET_XY 0x0200
39 /* monochrome register ports. */
40 #define M_CNTRL 0x3b8 /* mono controller register */
41 #define M_SRX_ADR 0x3b4 /* mono sequencer address port */
42 #define M_SRX_DATA 0x3b5 /* mono sequencer data port */
43 #define SR_CTP 0x0a /* cursor top and bottom */
44 #define SR_CBT 0x0b
45 #define SR_AHI 0x0c /* page address hi and low */
46 #define SR_ALO 0x0d
47 #define SR_CLH 0x0e /* seq cursor location high */
48 #define SR_CLL 0x0f /* low */
50 #define C_SRX_ADR 0x3d4 /* cga sequencer address port */
51 #define C_SRX_DATA 0x3d5 /* cga sequencer data port */
53 #define COMBO_MONO 1
54 #define MONO_WID 80
55 #define MONO_HGT 25
56 #define MONO_ROW (2*MONO_WID)
57 #define MONO_OFF 0
58 #define MONO_ON 1
59 #define MONO_TOG 2
60 #define MONO_FILE "mprintf.log"
61 #define MONO_DUMP "mono.dmp"
63 #ifdef _WIN32
64 __declspec(dllimport)
65 void
66 __stdcall
67 OutputDebugStringA(
68 const char * lpOutputString
70 #define OutputDebugString(s) OutputDebugStringA(s)
71 #endif
73 bool mono_to_debugger = FALSE;
75 /* have we yet called mono_init()? */
76 static bool mono_done_init = FALSE;
78 /* TRUE if there's a monochrome screen present. */
79 static bool mono_screen = FALSE;
81 /* MONO_ON when monochrome printing enabled. */
82 static uchar mono_mode = MONO_OFF;
84 /* cursor position on the mono screen. - abs cursor pos */
85 static uchar mono_x = 0;
86 static uchar mono_y = 0;
88 typedef struct {
89 uchar axis;
90 char coord, win;
91 uchar w, h;
92 uchar x, y;
93 uchar *base;
94 uchar lcoor[MONO_WIN_MAX][2];
95 char lfocus;
96 uchar *addr;
97 uchar flags;
98 char *msg;
99 } page_parms;
101 static page_parms _mono_screens[MONO_MAX_PAGES];
102 /* last is for flip/unflip - init to 1 so setpage 0 at start does stuff */
103 static char _cur_mono_page=1, _last_mono_page=-1, _cur_mono_focus=0;
104 static uint _inited_mpages=0; /* bitfielded list of which pages are inited */
105 static uchar _cur_card=0; /* MDA */
107 static char *def_wrap_msg=MONO_WRAP_MESSAGE;
109 static int srx_adr[2]={M_SRX_ADR,C_SRX_ADR};
110 static int srx_data[2]={M_SRX_DATA,C_SRX_DATA};
112 #define cur_stru (_mono_screens[_cur_mono_page])
113 #define split_axis ((cur_stru).axis)
114 #define split_coord ((cur_stru).coord)
115 #define split_win ((cur_stru).win)
116 #define split_w ((cur_stru).w)
117 #define split_h ((cur_stru).h)
118 #define split_x ((cur_stru).x)
119 #define split_y ((cur_stru).y)
120 #define split_base ((cur_stru).base)
121 #define page_addr ((cur_stru).addr)
122 #define split_lcoor ((cur_stru).lcoor)
123 #define split_lfocus ((cur_stru).lfocus)
124 #define split_flags ((cur_stru).flags)
125 #define split_msg ((cur_stru).msg)
127 #ifdef OLD_WAY
128 /* static split screen stuff */
129 static uchar split_axis = MONO_AXIS_X;
130 static char split_coord = -1;
131 static char split_win = -1; /* which window is active, -1 for no windows, else 1 or 2 */
132 static uchar split_w=MONO_WID, split_h=MONO_HGT;
133 static uchar split_x=0, split_y=0;
134 static uchar *split_base=MONO_BASE;
135 static uchar split_lcoor[MONO_WIN_MAX][2]={{0xff,0xff},{0xff,0xff}};
136 static char split_lfocus=-1;
137 #endif
139 /* current drawing attribute */
140 static uchar mono_attr = 7; /* MA_NORMAL */
142 /* handle of the log file or -1 if no log file. */
143 static int mono_file = -1;
144 static uchar mlog=0; /* last/cur log file parms, mostly for which windows to log */
145 /* name of last log file */
146 static char last_lf[_MAX_PATH]=MONO_FILE; /* pretend default was last */
148 int _mprint(const char *s, int n);
150 // just extern this and set it if you want to see things go...
151 void (*mono_spc_func)(char *,int)=NULL;
153 #define _mono_spc_check(s,n) \
154 if (mono_spc_func!=NULL) \
155 (*mono_spc_func)(s,n)
157 /* memset that sets n shorts starting a s to c. */
158 #ifdef __WATCOMC__
159 void *smemset (void *s, short c, int n);
160 #pragma aux smemset= \
161 "push edi" \
162 "rep stosw" \
163 "pop eax" \
164 parm [edi] [eax] [ecx] \
165 modify [edi eax ecx];
166 #else
167 __inline void *smemset(void *s, short c, int n)
169 #pragma warning(disable : 4035) // disables no return value warning
170 __asm
172 mov edi, s
173 mov ax, c
174 mov ecx, n
175 push edi
176 rep stosw
177 pop eax
180 #endif
182 #define out_mda(reg,val) outp(M_SRX_ADR,reg); outp(M_SRX_DATA,val)
184 #ifdef __WATCOMC__
185 #define out_set(card,reg,val)\
186 outp(srx_adr[card],reg);\
187 outp(srx_data[card],val)
188 #else
189 #define out_set(card,reg,val)\
190 outp((ushort) srx_adr[card],reg);\
191 outp((ushort) srx_data[card],val)
192 #endif
194 #ifdef USE_OLD_MONO_DETECT
195 bool mono_detect(void)
197 union REGS r;
199 r.w.ax = VB_GET_COMBO;
200 int386 (VBIOS_INT, &r, &r);
201 return ((r.h.bh==COMBO_MONO)||(r.h.bl==COMBO_MONO));
203 #endif /* USE_OLD_MONO_DETECT */
205 #ifdef USE_VBIO_CALL
206 /* video bios call */
207 int vbio_call (int parm_ax)
209 union REGS r;
211 r.w.ax = parm_ax;
212 int386 (VBIOS_INT, &r, &r);
213 return r.w.bx;
215 #endif /* USE_VBIO_CALL */
217 #ifdef __WATCOMC__
218 int mono_get_combo(void);
219 #pragma aux mono_get_combo=\
220 "mov eax,0x1a00" \
221 "int 0x10" \
222 "mov eax,ebx" \
223 "and eax,0xffff" \
224 modify exact [ebx];
225 #else
226 __inline int mono_get_combo(void)
228 #pragma warning(disable : 4035) // disables no return value warning
229 __asm
231 mov eax, 0x1a00
232 int 0x10
233 mov eax, ebx
234 and eax, 0xffff
237 #endif
238 /* returns TRUE if the secondary display is monochrome. */
239 bool mono_detect(void)
241 #ifdef WIN32
242 char *pStr;
244 // Fake this out under Windows 95, for now assume there is a monochrome
245 // board at 0xB000 and monitor present and hope for the best. The more
246 // this crashes on other setups, the sooner we'll have to come up with
247 // something else. Under Windows NT, monochrome output is not supported.
249 if (pStr = getenv ("OS"))
250 if (! stricmp (pStr, "Windows_NT"))
251 return FALSE;
253 // Must be Windows 95
254 return TRUE;
255 #else
256 int combo;
258 combo=mono_get_combo();
259 // note the 5 is for Jaemz's machine which bites.
260 return (combo&0xff)==COMBO_MONO || (combo>>8)==COMBO_MONO || (combo>>8)==5;
261 #endif
264 /* sets the monochrome printing mode to the mode passed in. it can be one of
265 MONO_ON, MONO_OFF, or MONO_TOG. returns new mono mode. */
266 int mono_setmode (int mode)
268 if (mono_screen)
269 { /* lets do this only if we have a mono screen */
270 if (mode == MONO_TOG)
272 if (mono_mode == MONO_ON)
273 mono_mode = MONO_OFF;
274 else
275 mono_mode = MONO_ON;
277 else
278 mono_mode = mode;
280 // it really already should be this
281 // else mono_mode=MONO_OFF;
283 return mono_mode;
286 /* setup for wrapping on mono as opposed to scrolling */
287 void mono_set_flags(int flags, char *msg)
289 split_flags=flags;
290 if ((flags&MONO_FLG_MSG)&&(msg!=NULL))
291 split_msg=msg;
294 /* fire up the monochrome screen printer. returns TRUE if there is a
295 monochrome screen present. */
296 bool mono_init(void)
298 bool r;
300 mono_done_init=TRUE;
301 mono_x=mono_y=0;
302 mono_screen=mono_detect();
303 r=mono_setmode(mono_screen);
304 if (r) mono_setpage(0,TRUE); /* put cursor at upper left, get to page 0 */
305 return r;
308 /* fire up the monochrome screen printer. returns TRUE if there is a
309 monochrome screen present. */
310 bool mono_win_init(bool have_screen)
312 bool r;
314 mono_done_init=TRUE;
315 mono_x=mono_y=0;
316 mono_screen=have_screen?MONO_ON:MONO_OFF;
317 r=mono_setmode(mono_screen);
318 if (r) mono_setpage(0,TRUE); /* put cursor at upper left, get to page 0 */
319 return r;
323 /* Mono Logging functions, logon, logoff, logdel */
325 /* turn on logging of monochrome activities.
326 * if how&MONO_LOG_CON use the last file logged to
327 * if how&MONO_LOG_DEF always use default log
328 * if how&MONO_LOG_NEW erase existing log file
329 * if CON and DEF, CON overrides, so there
330 * which uses the MONO_LOG_ALLWIN, or FULLSC defines, or | together MONO_WIN_ONE,TWO,etc
332 int mono_logon (char *fn, int how, int which)
334 int open_flags=O_WRONLY|O_CREAT;
335 if (mono_file != -1)
336 return -1;
337 if (how&MONO_LOG_CON)
338 fn = last_lf; /* continue with last */
339 else if ((fn == NULL)||(how&MONO_LOG_DEF))
340 fn = MONO_FILE;
341 if (how&MONO_LOG_NEW)
342 open_flags|=O_TRUNC;
343 else
344 open_flags|=O_APPEND;
345 if (fn!=last_lf)
346 strcpy(last_lf,fn);
347 mono_file = open (fn, open_flags, S_IWRITE);
348 mlog=which;
349 return mono_file;
352 /* turn off logging of monochrome screen. */
353 void mono_logoff (void)
355 if (mono_file!=-1)
357 close (mono_file);
358 mono_file = -1;
362 /* delete log
363 * kill_last is last log/default log
364 * always is even if open delete
366 * this is bizarrely broken, what to return re:kill_last
368 bool mono_logdel (bool kill_last, bool always)
370 if (mono_file!=-1)
372 if (!always)
373 return FALSE;
374 else
376 close(mono_file);
377 mono_file=-1;
380 if (kill_last)
381 return remove(last_lf);
382 else
383 return remove(MONO_FILE);
386 /* internal routines for memory access, screen parameter setting */
388 /* this is called for a page we have never visited before */
389 void _mono_init_page(int pageid)
391 split_axis=MONO_AXIS_X; split_coord=split_win=split_lfocus-1;
392 split_x=split_y=0; split_w=MONO_WID; split_h=MONO_HGT;
393 memset(split_lcoor,0xff,4);
394 split_base=page_addr=(uchar *)(MONO_BASE+(pageid*MONO_PAGE_SZ));
395 split_flags=0; split_msg=def_wrap_msg;
396 _inited_mpages|=(1<<pageid);
399 /* get memory address of x,y in current window */
400 uchar *_maddr(int x, int y)
402 if ((x<split_w)&&(y<split_h))
403 return (uchar *)split_base+MONO_ROW*y+x*2;
404 else
405 return NULL;
408 /* returns whether the gotten coordinates are or are not on the screen */
409 static bool _mget(int *x, int *y, bool always)
411 if (always||(*x==-1)) *x=mono_x-split_x;
412 if (always||(*y==-1)) *y=mono_y-split_y;
413 return (!(((*x)<0)||((*x)>=MONO_WID)||((*y)<0)||((*y)>=MONO_HGT)));
416 static bool _mset(int x, int y)
418 if ((x<0)||(x>=split_w)||(y<0)||(y>split_h)) return FALSE;
419 mono_x=split_x+x; mono_y=split_y+y; return TRUE;
422 static bool _out_of_win(int x, int y)
424 return (((x!=-1)&&((x<0)||(x>=split_w)))||((y!=-1)&&((y<0)||(y>=split_h))));
427 /* the beginning of all mono_ external calls - returns true to really do it */
428 static bool _mono_top(void)
430 if (!mono_done_init) mono_init ();
431 return (mono_mode != MONO_OFF);
434 #define _mono_focused() (_cur_mono_focus==_cur_mono_page)
436 /* routines to get and put single characters */
437 /* returns -1 if out of range or no mono screen */
438 int mget(uchar *s, int x, int y) /* get current character (at x,y specified w/o moving cursor ) */
440 if ((_mono_top())&&(!_out_of_win(x,y))&&(_mget(&x,&y,FALSE)))
441 return (int)(*s=*_maddr(x,y));
442 else
443 { *s=0; return -1; }
446 int mput(uchar s, int x, int y) /* put single character ( or a -1 for x means at current loc) */
448 if ((_mono_top())&&(!_out_of_win(x,y))&&(_mget(&x,&y,FALSE)))
449 return (int)(*_maddr(x,y)=s);
450 else
451 return -1;
454 /* split screen stuff */
455 /* internal get/set correct window parameters */
456 static bool _mwin_set(int pick,int axe,int loc)
458 int save_focus=split_win;
460 split_win=pick; split_base=(uchar *)page_addr;
461 split_w=MONO_WID; split_h=MONO_HGT; split_x=split_y=0;
462 if (pick==-1) goto no_split;
463 if (axe==MONO_AXIS_X)
465 #ifdef FULL_CHECKING
466 if (loc>=MONO_WID) goto no_split;
467 #endif
468 if (pick==1) split_w=loc;
469 else { split_w=MONO_WID-loc; split_base+=2*loc; split_x=loc; }
471 else
473 #ifdef FULL_CHECKING
474 if (loc>=MONO_HGT) goto no_split;
475 #endif
476 if (pick==1) split_h=loc;
477 else { split_h=MONO_HGT-loc; split_base+=MONO_ROW*loc; split_y=loc; }
479 split_axis=axe; split_coord=loc;
480 if (split_lfocus==-1) /* brand new split */
481 memset(split_lcoor,0,(MONO_WIN_MAX*2));
482 mono_setxy(split_lcoor[split_win-1][0],split_lcoor[split_win-1][1]); /* go to correct position */
483 split_lfocus=split_win;
484 return TRUE;
485 no_split:
486 split_lfocus=save_focus;
487 return (pick==-1);
490 /* externals */
491 /* split returns number of windows, or -1 if there are already windows */
492 int mono_split (int axe, int loc)
494 int save_focus=split_lfocus, focus=1;
495 if (split_win!=-1) return -1; /* already an open window */
496 if (axe==MONO_AXIS_R) { axe=split_axis; loc=split_coord; focus=split_lfocus; } else split_lfocus=-1;
497 if (_mwin_set(focus,axe,loc)) return MONO_WIN_MAX; /* there are 2 windows */
498 else { split_lfocus=save_focus; return -1; }
501 /* returns false if it cannot unsplit the window */
502 bool mono_unsplit (void)
504 return (split_win!=-1)&&(_mwin_set(-1,-1,-1));
507 /* returns whether the pickwin was succesful, ie. whether you passed legal in */
508 bool mono_setwin (int which)
510 #ifdef FULL_CHECKING
511 if ((split_win==-1)||(which<0)||(which>MONO_WIN_NXT)) return FALSE;
512 #endif
513 if (which==split_win) return TRUE; /* already focused on this window */
514 if (which==MONO_WIN_NXT)
515 if ((which=split_win+1)==MONO_WIN_MAX+1) which=1;
516 _mwin_set(which,split_axis,split_coord);
517 return TRUE;
520 int mono_getwin(void)
522 // printf("Axe %d, loc %d, cur %d, last %d scr %d %d %d %d\n",split_axis,split_coord,split_win,split_lfocus,split_x,split_y,split_w,split_h);
523 return split_win;
526 /* direct page set/get */
527 bool mono_setpage(int pageid, bool focus)
529 if (!_mono_top()) return FALSE;
530 if (_cur_mono_page==pageid) return FALSE;
531 if (pageid>=MONO_MAX_PAGES) return FALSE;
532 _cur_mono_page=pageid;
533 if ((_inited_mpages&(1<<pageid))==0)
535 _mono_init_page(pageid);
536 mono_setxy(0,0);
538 if (focus)
539 mono_setfocus(pageid);
540 return TRUE;
543 int mono_getpage(void)
545 return _cur_mono_page;
548 int mono_setfocus(int pageid)
550 int page_offs;
551 if (!_mono_top()) return FALSE;
552 if (_cur_mono_focus==pageid) return FALSE;
553 if (pageid<MONO_NUM_PAGES)
554 { _cur_card=MONO_CARD; page_offs=(int)(page_addr-MONO_BASE); }
555 else
556 { _cur_card=CGA_CARD; page_offs=(int)(page_addr-CGA_BASE)>>1; }
557 // printf("Trying to set to %x on card %d\n",page_offs,_cur_card);
558 out_set(_cur_card,SR_AHI,(page_offs)>>8);
559 out_set(_cur_card,SR_ALO,(page_offs)&0xff);
560 // vbio_call(0x0500+pageid-(_cur_card==CGA_CARD?8:0));
561 return TRUE;
564 int mono_getfocus(void)
566 return _cur_mono_focus;
569 /* goofy turn off screen thing */
570 void mono_scr_disable(void)
572 int ostate=inp (M_CNTRL);
573 ostate&=(~(1<<3));
574 outp(M_CNTRL,ostate);
577 void mono_scr_enable(void)
579 int ostate=inp (M_CNTRL);
580 ostate|=(1<<3);
581 outp(M_CNTRL,ostate);
584 /* warning, bizarrly broken on some mono cards */
585 void mono_cursor(bool cur_mon, int start, int stop)
587 int card=MONO_CARD;
588 if (start>stop) {int tmp=start; start=stop; stop=tmp; }
589 if (cur_mon) card=_cur_card;
590 out_set(card,SR_CTP,start);
591 out_set(card,SR_CBT,stop);
594 /* screen flip stuff */
595 bool mono_flip(int pageid)
597 int old_page=_cur_mono_page;
598 bool retv=mono_setpage(pageid,TRUE);
599 if (retv) _last_mono_page=old_page;
600 return retv;
603 bool mono_unflip(void)
605 bool retv;
606 if (_last_mono_page==-1) return FALSE;
607 if ((retv=mono_setpage(_last_mono_page,TRUE)) != 0)
608 _last_mono_page=-1; /* so it wont be able to double unflip */
609 return retv;
612 /* set the current text attributes. */
613 void mono_setattr (uchar attrib)
615 mono_attr = attrib;
618 /* set the (x,y) location of the cursor. - window relative */
619 bool mono_setxy (int x, int y)
621 if (!_mset(x,y)) return FALSE; /* set even if screen disabled */
622 if (!_mono_top()) return FALSE;
623 if (_mono_focused())
625 int c_offset = MONO_WID*mono_y + mono_x;
626 out_set(_cur_card,SR_CLH,(c_offset)>>8);
627 out_set(_cur_card,SR_CLL,(c_offset)&0xff);
629 return TRUE;
632 /* return the current x,y coordinates */
633 void mono_getxy(int *x, int *y)
635 _mget(x,y,TRUE);
638 /* clear the monochrome screen and reset cursor. */
639 void mono_clear (void)
641 int i;
642 if (!_mono_top()) return;
643 if ((split_win!=-1)&&(split_axis==MONO_AXIS_X))
644 for (i=0; i<MONO_HGT; i++)
645 smemset(split_base+i*MONO_ROW,mono_attr<<8,split_w);
646 else
647 smemset(split_base,mono_attr<<8,MONO_WID*split_h);
648 mono_setxy (0, 0);
651 /* scroll the monochrome screen by n lines, blanking bottom n lines. */
652 void mono_scroll (int n)
654 int i;
655 uchar *src, *dst, *bot;
657 if (!_mono_top()) return;
658 if (n >= split_h)
659 if ((split_flags==0)||((split_flags&MONO_FLG_WRAPCLEAR)==MONO_FLG_WRAPCLEAR))
660 { mono_clear (); return; }
662 if (split_flags&MONO_FLG_WRAP)
664 int x, y;
665 _mget(&x,&y,TRUE);
666 if (y<split_h-1)
668 if (split_flags&MONO_FLG_CLEAR)
669 smemset(split_base+y*MONO_ROW,mono_attr<<8,(split_h-y-1)*MONO_WID);
670 n-=(split_h-y-1);
672 } /* now at top of window */
673 if (n>0)
675 if (split_flags&MONO_FLG_CLEAR)
676 smemset(split_base,mono_attr<<8,n*MONO_WID);
677 y=n-1;
679 else y=split_h+n-1;
680 _mset(0,y);
682 else
684 src = split_base+n*MONO_ROW;
685 dst = split_base;
686 bot = split_base+(split_h-n)*MONO_ROW;
687 if ((split_win!=-1)&&(split_axis==MONO_AXIS_X))
689 for (i=0; i<(split_h-n); i++)
690 memmove(dst+i*MONO_ROW,src+i*MONO_ROW,2*split_w);
691 for (i=0; i<n; i++)
692 smemset(bot+i*MONO_ROW,mono_attr<<8,split_w);
694 else
696 memmove (dst, src, (split_h-n)*MONO_ROW);
697 smemset (bot, mono_attr<<8, n*MONO_WID);
702 bool _mono_log(void)
704 // return ((mono_spc_func!=NULL)||((mono_file!=-1)&&(!mono_screen||(mlog&split_win))));
705 return (mono_spc_func!=NULL) ||
706 ((mono_file!=-1)&&
707 (!mono_screen||((mlog==0)||(mlog&split_win))));
710 // doesnt correctly support split width stuff....
711 int _mscroll_msg(int *x, int *y)
713 if (split_flags&MONO_FLG_CLEAR)
714 smemset(split_base+(*y)*MONO_ROW,mono_attr<<8,split_w);
715 if ((split_flags&MONO_FLG_MSG)&&(split_msg!=NULL))
717 int old_y=*y, chars_in_msg=strlen(split_msg);
718 *y=((*y)+1)%split_h;
719 _mset(*x,*y);
720 if ((chars_in_msg>0)&&(split_msg[chars_in_msg-1]=='\n'))
721 { smemset(split_base+(*y)*MONO_ROW,mono_attr<<8,split_w); chars_in_msg--; }
722 _mprint(split_msg,chars_in_msg);
723 *y=old_y;
724 _mset(*x,*y);
726 return *y;
729 int _mscroll_us(int n, int *x, int *y)
731 if (*y < split_h-n)
732 (*y)+=n;
733 else
735 mono_scroll (n);
736 _mget(x,y,TRUE);
738 *x = 0;
739 _mscroll_msg(x,y);
740 return *y;
743 /* internal print a buffer a length n to the mono screen */
744 int _mprint(const char *s, int n)
746 int i,cur_x,cur_y;
747 uchar *p; /* pointer to current line. */
749 if (_mono_log())
750 write (mono_file, s, n); /* write even if no screen */
751 #ifdef _WIN32
752 if (mono_to_debugger)
753 OutputDebugString (s);
754 #endif
756 _mono_spc_check((char *)s,n);
758 if (mono_mode==MONO_OFF || !mono_screen) return n;/* no screen, so dont print */
760 _mget(&cur_x,&cur_y,TRUE);
761 for (i=0; i<n; i++)
763 p = _maddr(cur_x,cur_y);
765 switch (s[i])
767 case '\n':
768 _mscroll_us(1,&cur_x,&cur_y);
769 break;
770 case '\r':
771 cur_x = 0;
772 break;
773 case '\b':
774 if (cur_x > 0)
775 cur_x--;
776 else if (cur_y > 0)
777 cur_y--;
778 break;
779 case '\014':
780 mono_clear();
781 cur_x=cur_y=0;
782 break;
783 default:
784 p[0] = (uchar)s[i];
785 p[1] = mono_attr;
786 if (cur_x < split_w-1)
787 cur_x++;
788 else
789 _mscroll_us(1,&cur_x,&cur_y);
790 break;
793 mono_setxy (cur_x, cur_y);
794 return n;
797 /* printf to the monochrome screen. has the same arguments and return value
798 as printf (returns number of items printed). uses vsprintf to print into
799 a 1k buffer which is then transferred to the mono screen char by char. */
800 int mprintf(const char *fmt, ...)
802 char buf[1024];
803 int n;
804 va_list ap;
806 CoreThreadLock();
808 if (!_mono_top())
809 if (!_mono_log())
811 CoreThreadUnlock();
812 return -1;
815 va_start(ap, fmt);
816 n=lg_vsprintf(buf, fmt, ap);
817 va_end (ap);
819 /* punt if there was an error. */
820 if (n < 0)
822 CoreThreadUnlock();
823 return n;
826 /* write this string if we're logging. */
827 _mprint(buf,n);
829 CoreThreadUnlock();
830 return n;
833 /* print s with no formating, it's just text folks, just text, nothing to be seen here */
834 int mprint(const char *s)
836 int ret;
837 CoreThreadLock();
838 if (!_mono_top())
839 if (!_mono_log())
841 CoreThreadUnlock();
842 return -1;
844 ret = _mprint(s,strlen(s));
845 CoreThreadUnlock();
846 return ret;
849 /* dump screen to fn, erase if set */
850 bool mono_dump(char *fn, bool erase_it, bool readable)
852 int open_flags=O_WRONLY|O_CREAT|O_BINARY, mono_hnd;
853 int x,y,write_wid=MONO_WID;
854 uchar *cur_char;
855 char on_line[MONO_WID+2];
857 if (!_mono_top()) return FALSE;
858 if (erase_it) open_flags|=O_TRUNC; else open_flags|=O_APPEND;
859 if (fn==NULL) fn=MONO_DUMP;
860 if ((mono_hnd = open (fn, open_flags, S_IWRITE))==-1) return FALSE;
861 if (readable) { on_line[MONO_WID]=0x0D; on_line[MONO_WID+1]=0x0A; write_wid+=2; }
862 for (y=0; y<MONO_HGT; y++)
864 cur_char=(uchar *)page_addr+MONO_ROW*y;
865 for (x=0; x<MONO_WID; x++)
866 on_line[x]=*(cur_char+2*x);
867 write(mono_hnd,on_line,write_wid);
869 close(mono_hnd);
870 return TRUE;