~ubuntu-branches/ubuntu/wily/gargoyle-free/wily-proposed

« back to all changes in this revision

Viewing changes to tads/tads2/msdos/osdbg.c

  • Committer: Bazaar Package Importer
  • Author(s): Sylvain Beucler
  • Date: 2009-09-11 20:09:43 UTC
  • Revision ID: james.westby@ubuntu.com-20090911200943-idgzoyupq6650zpn
Tags: upstream-2009-08-25
ImportĀ upstreamĀ versionĀ 2009-08-25

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifdef RCSID
 
2
static char RCSid[] =
 
3
"$Header: d:/cvsroot/tads/TADS2/msdos/OSDBG.C,v 1.2 1999/05/17 02:52:18 MJRoberts Exp $";
 
4
#endif
 
5
 
 
6
/* 
 
7
 *   Copyright (c) 1990, 2002 Michael J. Roberts.  All Rights Reserved.
 
8
 *   
 
9
 *   Please see the accompanying license file, LICENSE.TXT, for information
 
10
 *   on using and copying this software.  
 
11
 */
 
12
/*
 
13
Name
 
14
  osdbg  - os routines for debugger
 
15
Function
 
16
  Implements os routines for windowing DOS debugger.
 
17
Notes
 
18
  None
 
19
Modified
 
20
  04/21/92 MJRoberts     - creation (from tads 1.2 osgen.c)
 
21
*/
 
22
 
 
23
#ifdef __WIN32__
 
24
#include <windows.h>
 
25
#include <wincon.h>
 
26
#endif
 
27
 
 
28
#ifdef DJGPP
 
29
#include <dpmi.h>
 
30
#endif
 
31
 
 
32
#include <stdarg.h>
 
33
#include "os.h"
 
34
#include "osgen.h"
 
35
#include "std.h"
 
36
#include "osdbg.h"
 
37
 
 
38
#ifdef __WIN32__
 
39
 
 
40
/*
 
41
 *   For Win32, use the console API to access the screen.  Keep track of
 
42
 *   two console handles - the standard one, and the new one we create for
 
43
 *   the debugger screen.  [0] is the standard handle, which we use for
 
44
 *   the game screen, and [1] is the debugger screen.  
 
45
 */
 
46
HANDLE G_screen_bufhdl[2];
 
47
 
 
48
/* global with current output handle - see ossdos32.c */
 
49
extern HANDLE G_out_bufhdl;
 
50
 
 
51
#endif /* __WIN32__ */
 
52
 
 
53
#ifdef MSOS2
 
54
# define INCL_VIO
 
55
# include <os2.h>
 
56
#endif /* MSOS2 */
 
57
 
 
58
/* adjust assembler keywords */
 
59
# if _MSC_VER >= 700
 
60
# define interrupt __interrupt
 
61
# define asm       __asm
 
62
# else
 
63
# ifndef DJGPP
 
64
#  define interrupt _interrupt
 
65
#  define asm       _asm
 
66
# endif /* !DJGPP */
 
67
# endif /* _MSC_VER >= 700 */
 
68
 
 
69
 
 
70
/* clear a window */
 
71
void osdbgclr(oswdef *win)
 
72
{
 
73
    ossclr(win->oswy1, win->oswx1, win->oswy2, win->oswx2, win->oswcolor);
 
74
}
 
75
 
 
76
#ifdef MSOS2
 
77
typedef struct pagedef
 
78
{
 
79
    USHORT  row;
 
80
    USHORT  col;
 
81
    size_t  size;
 
82
    BYTE    cells[2];
 
83
} pagedef;
 
84
 
 
85
pagedef *pages[2];
 
86
 
 
87
int osdbgini(int rows, int cols)
 
88
{
 
89
    size_t size = 2 * rows * cols;
 
90
 
 
91
    pages[0] = (pagedef *)malloc(size + sizeof(pagedef) - 2);
 
92
    pages[1] = (pagedef *)malloc(size + sizeof(pagedef) - 2);
 
93
    pages[0]->row = pages[1]->row = 0;
 
94
    pages[0]->col = pages[1]->col = 0;
 
95
    pages[0]->size = pages[1]->size = size;
 
96
    memset(pages[0]->cells, 0, size);
 
97
    memset(pages[1]->cells, 0, size);
 
98
    return(0);
 
99
}
 
100
#else /* MSOS2 */
 
101
#ifdef __WIN32__
 
102
 
 
103
int osdbgini(int rows, int cols)
 
104
{
 
105
    /* 
 
106
     *   initialize our array of output screen buffer handles -- the first
 
107
     *   entry is the default entry, which we use for the game screen; the
 
108
     *   second entry is a new handle we create, which we use for the
 
109
     *   debug screen 
 
110
     */
 
111
    G_screen_bufhdl[0] = G_out_bufhdl;
 
112
    G_screen_bufhdl[1] = CreateConsoleScreenBuffer(GENERIC_WRITE, 0,
 
113
        0, CONSOLE_TEXTMODE_BUFFER, 0);
 
114
 
 
115
    /* success */
 
116
    return 0;
 
117
}
 
118
 
 
119
#else /* __WIN32__ */
 
120
 
 
121
int osdbgini(int rows, int cols)
 
122
{
 
123
    return(0);
 
124
}
 
125
 
 
126
#endif /* __WIN32__ */
 
127
#endif /* MSOS2 */
 
128
 
 
129
#ifndef DJGPP
 
130
 
 
131
int ossvpg(char pg)
 
132
{
 
133
    static int  prvpg;
 
134
#ifdef MSOS2
 
135
           USHORT siz;
 
136
#else /* MSOS2 */
 
137
    extern long scrbase;
 
138
#endif /* MSOS2 */
 
139
           int  ret;
 
140
    
 
141
    if (pg == prvpg) return(prvpg);
 
142
#ifdef MSOS2
 
143
    siz = (USHORT)pages[prvpg]->size;
 
144
    VioReadCellStr(pages[prvpg]->cells, &siz, (USHORT)0, (USHORT)0, (HVIO)0);
 
145
    VioGetCurPos(&pages[prvpg]->row, &pages[prvpg]->col, (HVIO)0);
 
146
 
 
147
    VioWrtCellStr(pages[pg]->cells, (USHORT)pages[pg]->size,
 
148
                  (USHORT)0, (USHORT)0, (HVIO)0);
 
149
    VioSetCurPos(pages[pg]->row, pages[pg]->col, (HVIO)0);
 
150
#endif /* MSOS2 */
 
151
    ret = prvpg;
 
152
    prvpg = pg;
 
153
    
 
154
#ifdef __WIN32__
 
155
    /* set ossdos32.c's output handle to the selected page's handle */
 
156
    G_out_bufhdl = G_screen_bufhdl[pg];
 
157
 
 
158
    /* show the selected page */
 
159
    SetConsoleActiveScreenBuffer(G_out_bufhdl);
 
160
#else /* __WIN32__ */
 
161
#ifndef MSOS2
 
162
    asm {
 
163
        push    bp
 
164
        mov     ah, 5
 
165
        mov     al, pg
 
166
        int     0x10
 
167
 
 
168
        mov     ax, (25 * 80 * 2) + 96
 
169
        cmp     pg, 0
 
170
        jne     ossvpg_1
 
171
        neg     ax
 
172
    }
 
173
ossvpg_1:
 
174
    asm {
 
175
        add     word ptr [scrbase], ax
 
176
        pop     bp
 
177
    }
 
178
#endif /* !MSOS2 */
 
179
#endif /* __WIN32__ */
 
180
    return(ret);
 
181
}
 
182
 
 
183
#endif /* !DJGPP */
 
184
 
 
185
/* scroll a window up a line */
 
186
static void osdbgsc(oswdef *win)
 
187
{
 
188
    ossscr(win->oswy1, win->oswx1, win->oswy2, win->oswx2, win->oswcolor);
 
189
}
 
190
 
 
191
/* print a string in a debugger window */
 
192
void osdbgpt(oswdef *win, char *fmt, ...)
 
193
{
 
194
    char     buf[256];
 
195
    va_list  argptr;
 
196
    char    *p;
 
197
 
 
198
    va_start(argptr, fmt);
 
199
    vsprintf(buf, fmt, argptr);
 
200
    va_end(argptr);
 
201
 
 
202
    for (p=buf ; *p ; )
 
203
    {
 
204
        char *p1;
 
205
 
 
206
        if ((win->oswflg & OSWFMORE) && win->oswx == win->oswx1 &&
 
207
            win->oswmore+1 >= win->oswy2 - win->oswy1)
 
208
        {
 
209
            char c;
 
210
            int eof;
 
211
            
 
212
            ossdsp(win->oswy, win->oswx, win->oswcolor, "[More]");
 
213
            ossdbgloc((char)win->oswy, (char)(win->oswx+6));
 
214
            eof = FALSE;
 
215
            do
 
216
            {
 
217
                switch(c = os_getc())
 
218
                {
 
219
                case '\n':
 
220
                case '\r':
 
221
                    win->oswmore--;
 
222
                    break;
 
223
 
 
224
                case ' ':
 
225
                    win->oswmore = 0;
 
226
                    break;
 
227
 
 
228
                case 0:
 
229
                    if (os_getc() == CMD_EOF)
 
230
                    {
 
231
                        win->oswmore = 0;
 
232
                        eof = TRUE;
 
233
                    }
 
234
                    break;
 
235
                }
 
236
            } while (c != ' ' && c != '\n' && c != '\r' && !eof);
 
237
                
 
238
            ossdsp(win->oswy, win->oswx, win->oswcolor, "      ");
 
239
        }
 
240
 
 
241
        for (p1 = p ; *p1 && *p1 != '\n' && *p1 != '\r' && *p1 != '\t'; p1++);
 
242
        if (*p1 == '\n' || *p1 == '\r' || *p1 == '\t')
 
243
        {
 
244
            int c = *p1;
 
245
            
 
246
            *p1 = '\0';
 
247
 
 
248
            if ((size_t)win->oswx + strlen(p) > (size_t)win->oswx2 &&
 
249
                (win->oswflg & OSWFCLIP))
 
250
                p[win->oswx2 - win->oswx + 1] = '\0';
 
251
            ossdsp(win->oswy, win->oswx, win->oswcolor, p);
 
252
 
 
253
            if (c == '\n')
 
254
            {
 
255
                ++(win->oswy);
 
256
                win->oswx = win->oswx1;
 
257
                if (win->oswy > win->oswy2)
 
258
                {
 
259
                    win->oswy = win->oswy2;
 
260
                    osdbgsc(win);
 
261
                }
 
262
                win->oswmore++;
 
263
            }
 
264
            else if (c == '\t')
 
265
            {
 
266
                win->oswx += strlen(p);
 
267
                do
 
268
                {
 
269
                    ossdsp(win->oswy, win->oswx, win->oswcolor, " ");
 
270
                    ++(win->oswx);
 
271
                    if (win->oswx > win->oswx2 && (win->oswflg & OSWFCLIP))
 
272
                        break;
 
273
                } while ((win->oswx - 2) & 7);
 
274
            }
 
275
            p = p1 + 1;
 
276
            if (win->oswx > win->oswx2) return;
 
277
        }
 
278
        else
 
279
        {
 
280
            if ((size_t)win->oswx + strlen(p) > (size_t)win->oswx2
 
281
                && (win->oswflg & OSWFCLIP))
 
282
                p[win->oswx2 - win->oswx + 1] = '\0';
 
283
            ossdsp(win->oswy, win->oswx, win->oswcolor, p);
 
284
            win->oswx += strlen(p);
 
285
            p = p1;
 
286
        }
 
287
    }
 
288
}
 
289
 
 
290
/* open a window - set up location */
 
291
void osdbgwop(oswdef *win, int x1, int y1, int x2, int y2, int color)
 
292
{
 
293
    win->oswx1 = win->oswx = x1;
 
294
    win->oswx2 = x2;
 
295
    win->oswy1 = win->oswy = y1;
 
296
    win->oswy2 = y2;
 
297
    win->oswcolor = color;
 
298
    win->oswflg = 0;
 
299
}
 
300
 
 
301
/* locate the cursor */
 
302
void ossdbgloc(char y, char x)
 
303
{
 
304
#if defined(MSOS2) || defined(__WIN32__)
 
305
    ossloc(y, x);
 
306
#else /* !MSOS2 */
 
307
# ifdef DJGPP
 
308
    __dpmi_regs regs;
 
309
 
 
310
    regs.h.dh = y;
 
311
    regs.h.dl = x;
 
312
    regs.h.ah = 2;
 
313
    regs.h.bh = 1;
 
314
    __dpmi_int(0x10, &regs);
 
315
# else /* DJGPP */
 
316
    asm {
 
317
         push bp;
 
318
         mov  dh, y;
 
319
         mov  dl, x; 
 
320
         mov  ah, 2;
 
321
         mov  bh, 1;
 
322
         int  0x10;
 
323
         pop  bp;
 
324
    }
 
325
# endif /* DJGPP */
 
326
#endif /* MSOS2 */
 
327
}
 
328
 
 
329
/* get some text */
 
330
int osdbggts(oswdef *win, char *buf, int (*cmdfn)(void *, char), void *cmdctx)
 
331
{
 
332
    char *p = buf;
 
333
    char *eol = buf;
 
334
    char *eob = buf + 127;
 
335
    int   x = win->oswx;
 
336
    int   y = win->oswy;
 
337
    int   cmd = 0;
 
338
 
 
339
    win->oswmore = 0;
 
340
    for (buf[0] = '\0' ; ; )
 
341
    {
 
342
        char c;
 
343
 
 
344
        ossdbgloc((char)y, (char)x);
 
345
        switch(c = os_getc())
 
346
        {
 
347
        case 8:
 
348
            if (p > buf)
 
349
            {
 
350
                char *q;
 
351
                char  tmpbuf[2];
 
352
                int   thisx, thisy;
 
353
                
 
354
                for ( q=(--p) ; q<eol ; q++ ) *q = *( q+1 );
 
355
                eol--;
 
356
                if ( --x < 0 )
 
357
                {
 
358
                    x = win->oswx2;
 
359
                    y--;
 
360
                }
 
361
                *eol = ' ';
 
362
                thisx = x;
 
363
                thisy = y;
 
364
                for ( q=p, tmpbuf[1]='\0' ; q<=eol ; q++ )
 
365
                {
 
366
                    tmpbuf[0] = *q;
 
367
                    ossdsp( thisy, thisx, win->oswcolor, tmpbuf );
 
368
                    if ( ++thisx > win->oswx2 )
 
369
                    {
 
370
                        thisx = 0;
 
371
                        thisy++;
 
372
                    }
 
373
                }
 
374
                *eol = '\0';
 
375
            }
 
376
            break;
 
377
 
 
378
        case 13:
 
379
            /*
 
380
             *   Scroll the screen to account for the carriage return,
 
381
             *   position the cursor at the end of the new line, and
 
382
             *   null-terminate the line.  
 
383
             */
 
384
            *eol = '\0';
 
385
            while( p != eol )
 
386
            {
 
387
                p++;
 
388
                if ( ++x > win->oswx2 )
 
389
                {
 
390
                    y++;
 
391
                    x = 0;
 
392
                }
 
393
            }
 
394
            
 
395
            if ( y == win->oswy2 ) osdbgsc(win);
 
396
            else ++y;
 
397
            x = 0;
 
398
            ossdbgloc((char)y, (char)x);
 
399
            
 
400
            /*
 
401
             *   Finally, copy the buffer to the screen save buffer (if
 
402
             *   applicable), and return the contents of the buffer.  Note
 
403
             *   that we add an extra carriage return if we were already on
 
404
             *   the last line, since we scrolled the screen in this case;
 
405
             *   otherwise, ossaddsbe will add all the blank lines that are
 
406
             *   necessary.  
 
407
             */
 
408
            win->oswx = x;
 
409
            win->oswy = y;
 
410
            return(0);
 
411
            
 
412
        case 0:
 
413
            switch(c = os_getc())
 
414
            {
 
415
            case CMD_EOF:
 
416
                return 0;
 
417
                
 
418
            case CMD_LEFT:
 
419
                if ( p>buf )
 
420
                {
 
421
                    p--;
 
422
                    x--;
 
423
                    if ( x < 0 )
 
424
                    {
 
425
                        x = win->oswx2;
 
426
                        y--;
 
427
                    }
 
428
                }
 
429
                break;
 
430
 
 
431
            case CMD_RIGHT:
 
432
                if ( p<eol )
 
433
                {
 
434
                    p++;
 
435
                    x++;
 
436
                    if ( x > win->oswx2 )
 
437
                    {
 
438
                        x = 0;
 
439
                        y++;
 
440
                    }
 
441
                }
 
442
                break;
 
443
            case CMD_DEL:
 
444
                if ( p<eol )
 
445
                {
 
446
                    char *q;
 
447
                    char  tmpbuf[2];
 
448
                    int   thisx=x, thisy=y;
 
449
                    
 
450
                    for ( q=p ; q<eol ; q++ ) *q = *(q+1);
 
451
                    eol--;
 
452
                    *eol = ' ';
 
453
                    for ( q=p, tmpbuf[1]='\0' ; q<=eol ; q++ )
 
454
                    {
 
455
                        tmpbuf[0] = *q;
 
456
                        ossdsp( thisy, thisx, win->oswcolor, tmpbuf );
 
457
                        if ( ++thisx > win->oswx2 )
 
458
                        {
 
459
                            thisx = 0;
 
460
                            thisy++;
 
461
                        }
 
462
                    }
 
463
                    *eol = '\0';
 
464
                }
 
465
                break;
 
466
            case CMD_KILL:
 
467
            case CMD_HOME:
 
468
            do_kill:
 
469
                while( p>buf )
 
470
                {
 
471
                    p--;
 
472
                    if ( --x < 0 )
 
473
                    {
 
474
                        x = win->oswx2;
 
475
                        y--;
 
476
                    }
 
477
                }
 
478
                if ( c == CMD_HOME ) break;
 
479
                /*
 
480
                 *   We're at the start of the line now; fall through for
 
481
                 *   KILL, UP, and DOWN to the code which deletes to the
 
482
                 *   end of the line.  
 
483
                 */
 
484
            case CMD_DEOL:
 
485
                if ( p<eol )
 
486
                {
 
487
                    char *q;
 
488
                    int   thisx=x, thisy=y;
 
489
                    
 
490
                    for ( q=p ; q<eol ; q++ )
 
491
                    {
 
492
                        ossdsp( thisy, thisx, win->oswcolor, " " );
 
493
                        if ( ++thisx > win->oswx2 )
 
494
                        {
 
495
                            thisx = 0;
 
496
                            thisy++;
 
497
                        }
 
498
                    }
 
499
                    eol = p;
 
500
                    *p = '\0';
 
501
                }
 
502
                if (cmd) return(cmd);
 
503
                break;
 
504
            case CMD_END:
 
505
                while ( p<eol )
 
506
                {
 
507
                    p++;
 
508
                    if ( ++x > win->oswx2 )
 
509
                    {
 
510
                        x = 0;
 
511
                        y++;
 
512
                    }
 
513
                }
 
514
                break;
 
515
                
 
516
            default:
 
517
                if (cmd = (*cmdfn)(cmdctx, c))
 
518
                {
 
519
                    c = CMD_KILL;
 
520
                    goto do_kill;
 
521
                }
 
522
                break;
 
523
            }
 
524
            break;
 
525
        default:
 
526
            if ( c >= ' ' && c < 127 && eol<eob )
 
527
            {
 
528
                if ( p != eol )
 
529
                {
 
530
                    char *q;
 
531
                    int   thisy=y, thisx=x;
 
532
                    char  tmpbuf[2];
 
533
                    
 
534
                    for ( q=(++eol) ; q>p ; q-- ) *q=*(q-1);
 
535
                    *p = c;
 
536
                    for ( q=p++, tmpbuf[1] = '\0' ; q<eol ; q++ )
 
537
                    {
 
538
                        tmpbuf[0] = *q;
 
539
                        ossdsp( thisy, thisx, win->oswcolor, tmpbuf );
 
540
                        thisx++;
 
541
                        if ( thisx > win->oswx2 )
 
542
                        {
 
543
                            thisx = 0;
 
544
                            if ( thisy == win->oswy2 )
 
545
                            {
 
546
                                y--;
 
547
                                osdbgsc(win);
 
548
                            }
 
549
                            else thisy++;
 
550
                        }
 
551
                    }
 
552
                    if ( ++x > win->oswx2 )
 
553
                    {
 
554
                        y++;
 
555
                        x = 0;
 
556
                    }
 
557
                }
 
558
                else
 
559
                {
 
560
                    *p++ = c;
 
561
                    *p = '\0';
 
562
                    eol++;
 
563
                    ossdsp( y, x, win->oswcolor, p-1 );
 
564
                    if ( ++x > win->oswx2 )
 
565
                    {
 
566
                        x = 0;
 
567
                        if ( y == win->oswy2 )
 
568
                            osdbgsc(win);
 
569
                        else y++;
 
570
                    }
 
571
                }
 
572
            }
 
573
            break;
 
574
        }
 
575
    }
 
576
}