`
`25
`26
`27
`28
`29
`30
`31
`32
`33
`34
`35
`36
`37
`38
`39
`40
`41
`42
`43
`44
`45
`46
`47
`48
`49
`50
`51
`52
`53
`54
`55
`56
`57
`58
`59
`60
`61
`62
`63
`64
`65
`66
`67
`68
`69
`70
`71
`72
`73
`74
`75
`
`static int I,
`0,
`waitchr
`vflag = False,
`capbp,,
`capbc,
`Ch,
`Want_7-Bit = True,
`ESC_Seq_State = 0;
`
`int
`
`_ex ,
`_cy,
`_atr
`_pag
`oldtop
`oldbot
`
`Ox07,
`0,
`
`0,
`Ox184f;
`
`FILE * in_file = NULL;
`FILE * cap_file = NULL;
`
`I* escape sequence state variable
`
`I* white on black
`
`I* start with keyboard input
`
`#include "cterm.h"
`
`I* external declarations, etc.
`
`int Wants_To-Abort ()
`{ return broke ();
`
`void
`
`I* checks for interrupt of script
`
`I* main routine
`
`main ( argc, argv ) int argc
`char* argv [);
`char * cp,
`* addext ();
`I* check for script filename
`if ( argc > 1 )
`in_file = fopen ( addext ( argv [ 1 ), ".SCR" ), "r" );
`I* check for capture filename
`if ( argc > 2 )
`cap_file = fopen ( addext ( argv [ 2 ), ".CAP" ), "w" );
`I* install· CH1 module
`set_int ();
`I* get video setup
`Set_Vid ();
`I* clear the screen
`cls ();
`cputs ( "Terminal Emulator" ); I* tell who's working
`cputs ( "\r\n< ESC for local commands >\r\n\n" );
`Want_7-Bit = True;
`ESC_Seq_State = 0;
`Init_Comm ();
`while ( 1 )
`( if (( Ch = kb_file ()) > 0
`{ if ( Is_Function_Key ( Ch
`{ if ( docmd () < 0 )
`break;
`
`I*
`
`set
`
`up drivers, etc.
`I* main loop
`I* check local
`
`) )
`
`I* command
`
`else
`Send-Byte ( Ch & Ox7F );
`
`I* else send it
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`*I
`*I
`*I
`
`*I·
`*I
`*I
`
`*I
`
`*I
`
`Figure 6-8. Continued.
`
`(more)
`
`Section II: Programming in the MS-DOS Environment
`
`231
`
`ZTE (USA) 1007, Page 241
`
`
`
`Part B: Programming for MS-DOS
`
`if (( Ch = Read_Modem ()) >= 0 )
`{ if ( Want_7-Bit )
`Ch &= Ox7F;
`switch
`ESC_Seq_State
`
`case 0
`switch ( Ch
`
`case ESC
`ESC_Seq_State
`break;
`
`1;
`
`I* check remote
`
`I* trim off high bit
`I* state machine
`
`I* no Esc sequence
`
`I* Esc char received
`
`*I
`
`*I
`*I
`
`*I
`
`76
`77
`78
`79
`80
`81
`82
`83
`84
`85
`86
`87
`88
`89
`90
`91
`92
`93
`94
`95
`96
`97
`98
`99
`100
`101
`102
`103
`104
`105
`106
`107
`108
`109
`110
`111
`112
`113
`114
`115
`116
`117
`118
`119
`120
`121
`122
`123
`124
`125
`126
`
`I* wait if required
`
`I* clear screen on FF
`
`default :
`if ( Ch == waitchr
`waitchr = 0;
`i f ( Ch == 12 )
`cls () ;
`else
`*I
`I* ignore rubouts
`! = 127 )
`if ( Ch
`I* handle all others *I
`{ putchx ( (char) Ch );
`put-cap ( (char) Ch ) ;
`
`*I
`
`*I
`
`break;
`
`: I* ESC -- process any escape sequences here
`case 1
`switch ( Ch )
`
`case 'A'
`
`:
`
`ESC_Seq_State
`break;
`
`0;
`
`I* VT52 up
`I* nothing but stubs here
`
`case 'B'
`
`I* VT52 down
`
`ESC_Seq_State
`break;
`
`0;
`
`case 'C'
`
`I* VT52 left
`
`ESC_Seq_State
`break;
`
`0;
`
`case 'D'
`
`I* VT52 right
`
`ESC_Seq_State
`break;
`
`0;
`
`case 'E'
`cls () ;
`
`I* VT52 Erase CRT
`I* actually do this one
`
`*I
`
`*I
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`*I
`
`Figure 6-8. Continued.
`
`(more)
`
`232
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 242
`
`
`
`Article 6: Interrupt-Driven Communications
`
`127
`128
`129
`130
`131
`132
`133
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157
`158
`159
`160
`161
`1 62
`163
`164
`165
`166
`1 67
`168
`169
`170
`171
`172
`173
`174
`175
`176
`177
`
`ESC_Seq_State
`break;
`
`0;
`
`case 'H'
`0, 0 ) ;
`locate
`ESC_Seq_State = 0;
`break;
`
`case 'j'
`deos ();
`ESC_Seq_State
`break;
`
`0;
`
`I* VT52 horne cursor
`
`I* VT52 Erase to EOS
`
`I* ANSI.SYS -VT100 sequence
`case ' ['
`ESC_Seq_State = 2;
`break;
`
`*I
`
`*I
`
`*I
`
`default :
`putchx (ESC);
`putchx ( (char) Ch ) ;
`ESC_Seq_State
`0;
`
`break;
`
`I* pass thru all others
`
`*I
`
`:
`case 2
`ESC_Seq_State
`
`0;
`
`I* ANSI 3.64 decoder
`I* not implemented
`
`I* check CH1A handlers
`if (broke ())
`{ cputs ( "\r\n***BREAK***\r\n" ) ;
`break;
`
`if { cap_file
`cap_flush ();
`Terrn_Comm () ;
`rst_int ();
`exit ( 0 );
`
`docrnd ()
`FILE* getfil ();
`int wp;
`wp = True;
`! in_file : : vflag )
`i f (
`cputs ( "\r\n\tCommand: " );
`else
`wp = False;
`Ch = toupper ( kbd_wait ());
`i f ( wp )
`putchx ( (char) Ch ) ;
`
`I* end of main loop
`I* save any capture
`
`I* restore when done
`I* restore break handlers
`I* be nice to MS-DOS
`
`I* local command shell
`
`I* ask for command
`
`I* get response
`
`*I
`*I
`
`*I
`
`*I
`*I
`
`*I
`*I
`*I
`
`*I
`
`*I
`
`*I
`
`Figure 6-8. Continued.
`
`(more)
`
`Section II: Programming in the MS-DOS Environment
`
`233
`
`ZTE (USA) 1007, Page 243
`
`
`
`Part B: Programming for MS-DOS
`
`switch
`
`( Ch
`
`I* and act on it
`
`*I
`
`'S' :
`case
`i f ( wp )
`cputs ( "low speed\r\n" ) ;
`Set-Baud ( 300 );
`break;
`
`.-·
`
`178
`179
`180
`181
`182
`183
`184
`185
`186
`187
`188
`189
`190
`191
`1 92
`193
`194
`195
`196
`197
`198
`199
`200
`201
`202
`203
`204
`205
`206
`207
`208
`209
`210
`211
`212
`213
`214
`215
`21 6
`217
`218
`219
`220
`221
`222
`223
`224
`225
`226
`227
`
`case 'D'
`i f ( wp )
`cputs ( "elay ( 1-9 sec) : " ) ;
`Ch = kbd_wait ();
`i f ( wp )
`putchx ( (char) Ch ) ;
`Delay ( 1 000 * ( Ch -
`1 0 1
`i f ( wp )
`putchx (
`break;
`
`1 \n 1
`
`)
`
`;
`
`) )
`
`;
`
`case 'E'
`i f ( wp )
`cputs ( "ven Parity\r\n" );
`Set_Farity ( 2 );
`break;
`
`case 'F'
`i f ( wp )
`cputs ( "ast speed\r\n" );
`Set_Baud ( 1200 );
`break;
`
`"\r\n\tVALID COMMANDS:\r\n" );
`"\tD
`delay 0-9 seconds.\r\n" );
`even parity.\r\n" );
`"\tE
`"\tF
`(fast) 1200-baud.\r\n" );
`"\tN
`no parity.\r\n" );
`"\tO
`odd parity.\r\n" );
`"\tQ
`quit, return to DOS.\r\n" );
`"\tR
`reset modem.\r\n" );
`"\tS
`(slow) 300-baud.\r\n" );
`use script file.\r\n" );
`"\tU
`"\tV
`verify file input.\r\n" );
`wait for char." );
`"\tW
`
`case 'H'
`i f ( wp )
`{ cputs
`cputs
`cputs
`cputs
`cputs
`cputs
`cputs
`cputs
`cputs
`cputs
`cputs
`cputs
`
`break;
`
`case 'N'
`i f ( wp
`
`Figure 6-8. Continued.
`
`(more)
`
`234
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 244
`
`
`
`Article 6: Interrupt-Driven Communications
`
`228
`229
`230
`231
`232
`233
`234
`235
`236
`237
`238
`239
`240
`241
`242
`243
`244
`245
`246
`247
`248
`249
`250
`251
`252
`253
`254
`255
`256
`257
`258
`259
`260
`261
`262
`263
`264
`265
`266
`267
`268
`269
`270
`2T1
`272
`273
`274
`275
`276
`277
`278
`
`cputs ( "o Parity\r\n" ~;
`Set_Parity
`1 ) ;
`break;
`
`case '0'
`if ( wp )
`cputs ( "dd Parity\r\n" ) ;
`Set_Parity ( 3 );
`break;
`
`case 'R'
`i f ( wp )
`cputs ( "ESET cornin Port\r\n" ) ;
`In i t_Corrun
`() ;
`break;
`
`case 'Q'
`i f ( wp )
`cputs ( "-QUIT Corrunand\r\n" );
`Ch = ( -
`1
`) ;
`break;
`
`case 'U'
`! vflag
`if ( in_file &&
`putchx (
`'U' ) ;
`cputs ( "se file: " );
`getfil ();
`cputs ( "File" );
`cputs ( in_file ? "Open\r\n"
`waitchr = 0;
`break;
`
`"Bad\r\n" ) ;
`
`case 'V'
`if ( wp )
`{ cputs
`cputs
`
`"erify flag toggled" );
`vflag ? "OFF\r\n"
`"ON\r\n" );
`
`vflag = vflag ? False : True;
`break;
`
`case 'W'
`i f { wp
`cputs { "ait for: <" ) ;
`waitchr = kbcLwait ();
`if ( waitchr ==
`'
`' )
`waitchr = O;
`i f ( wp )
`{ if ( waitchr
`putchx ( (char) waitchr );
`else
`cputs ( "no wait" );
`
`Figure 6-8. Continued.
`
`(more)
`
`Section /1· Programming in the MS-DOS Environment
`
`235
`
`ZTE (USA) 1007, Page 245
`
`
`
`Part B: Programming for MS-DOS
`
`cputs ( ">\r\n" ) ;
`
`break;
`
`default :
`if ( wp
`{ cputs ( "Don't know " ) ;
`putchx ( (char) Ch ) ;
`cputs ( "\r\nUse 'H' command for Help. \r\n" ) ;
`
`Ch =
`
`'?';
`
`"\r\n[any key]\r" );
`Read-Keyboard () == EOF
`
`I* if window open ....
`
`I* wait for response
`
`i f ( wp )
`{ cputs
`while
`
`return Ch
`
`()
`
`kbd__wai t
`int c
`while ( ( c = kb_file ())
`
`( -
`
`1 ) )
`
`I* wait for input
`
`return c & 255;
`
`I* input from kb or
`
`file
`
`kb_file ()
`int
`c
`in_file
`i f (
`c = Wants_To_Abort () ;
`i f ( waitchr &&
`! c
`)
`c = ( - 1
`) ;
`else
`( c = getc ( in_file )) == EOF
`::
`if ( c
`fclose ( in_file );
`cputs ( "\r\nScript File Closed\r\n" );
`in_file
`NULL;
`waitchr
`0;
`c = ( -
`) ;
`
`I* USING SCRIPT
`I* use first as flag
`
`I* then for char
`
`:: c == 26
`
`else
`if ( c ==
`'\n'
`c =
`1 ) ;
`( -
`if ( c == '\\' )
`c = esc ();
`!= ( - 1 ))
`if ( vflag && c
`{ putchx
`' {' ) ;
`putchx
`(char) c ) ;
`putchx
`'}' ) ;
`
`I* ignore LFs in file
`
`I* process Esc sequence
`
`I* verify file char
`
`279
`280
`281
`282
`283
`284
`285
`286
`287
`288
`289
`290
`291
`292
`293
`294
`295
`296
`297
`298
`299
`300
`301
`302
`303
`304
`305
`306
`307
`308
`309
`310
`311
`312
`313
`314
`315
`316
`317
`318
`319
`320
`321
`322
`323
`·324
`325
`326
`327
`328
`329
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`Figure 6-8. Continued.
`
`(more)
`
`236
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 246
`
`
`
`Article 6: Interrupt-Driven Communications
`
`330
`331
`332
`333
`334
`335
`336
`337
`338
`339
`340
`341
`342
`343
`344
`345
`346
`347
`348
`349
`350
`351
`352
`353
`354
`355
`356
`357
`358
`359
`360
`361
`362
`363
`364
`365
`366
`367
`368
`369
`370
`371
`372
`373
`374
`375
`376
`377
`378
`379
`380
`
`:
`
`else
`c = Read_Keyboard ();
`return ( c ) ;
`
`esc ()
`{ int c
`c = getc ( in_file ) ;
`c ) )
`switch
`toupper
`
`I* USING CONSOLE
`I* if not using file
`
`I* script translator
`
`I* control chars in file
`
`case 'E'
`:
`c = ESC;
`break;
`
`case 'N'
`C = ' I \n I i·
`break;
`
`case 'R'
`c = '\r';
`break;
`
`case 'T'
`C = I \t I i
`break;
`
`case '"' :
`c = getc ( in_file ) & 31;
`break;
`
`return ( c ) ;
`
`FILE * getfil ()
`{ char fnm [ 20 ];
`getnam ( fnm, 15 );
`if ( !
`( strchr ( fnm,
`strcat ( fnm, ".SCR" );
`return ( in_file = fopen ( fnm, "r" ));
`
`)) )
`
`I* get the name
`
`) char * b;
`
`void getnam ( b, s
`int s
`;
`while ( s -- > 0
`if ( ( * b = (char) kbcLwait ()) != '\r' )
`putchx ( * b ++ );
`else
`break ;
`
`I* take input to buffer
`
`putchx (
`
`'\n' ) ;
`
`*I
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`Figure 6-8. Continued.
`
`(more)
`
`Section 11· Programming in the MS-DOS Environment
`
`237
`
`ZTE (USA) 1007, Page 247
`
`
`
`Part B: Programming for MS-DOS
`
`381
`382
`383
`384
`385
`386
`387
`388
`389
`390
`391
`392
`393
`394
`395
`396
`397
`398
`399
`400
`401
`402
`403
`404
`405
`406
`407
`408
`409
`410
`411
`412
`413
`414
`415
`416
`417
`418
`419
`420
`421
`422
`423
`424
`425
`426
`427
`428
`429
`430
`431
`
`* b
`
`0;
`
`b,
`char * addext
`e ) char * b,
`* e;
`static char bfr [ 20 ];
`if ( strchr ( b,
`'.' ) )
`return (b);
`bfr, b ) ;
`strcpy
`strcat
`bfr, e ) ;
`bfr ) ;
`return
`
`I* add default EXTension
`
`*I
`
`;
`void put_cap ( c ) char c
`( if ( cap_file && c != 13
`fputc ( c, cap_file );
`
`I* strip out CRs
`I* use MS-DOS buffering
`
`void cap_flush ()
`{ if ( cap_file )
`{ fclose ( cap_file );
`cap_file = NULL;
`cputs ( "\r\nCapture file closed\r\n" );
`
`I* end Capture mode
`
`I*
`TIMER SUPPORT STUFF
`static long timr;
`
`*I
`(IBMPCIMSDOS)
`I* timeout register
`
`static union REGS rgv
`
`long getmr ()
`{ long now
`Ox2c00;
`rgv.x.ax
`intdos ( & rgv, & rgv );
`now= rgv.h.ch;
`now *= 60L;
`now +=
`rgv.h.cl;
`now *=
`60L;
`now +=
`rgv.h.dh;
`100L;
`now *=
`now +=
`rgv.h.dl;
`( 10L * now
`return
`
`) ;
`
`I* msec since midnite
`
`I* hours
`I* to minutes
`I* plus min
`I* to seconds
`I* plus sec
`I* to 11100
`I* plus 11100
`I* msec value
`
`void Delay ( n ) int n ;
`{ long wakeup ;
`wakeup = getmr () + ( long ) n;
`while ( getmr () < wakeup )
`
`I* sleep for n rnsec
`
`I* wakeup time
`
`I* now sleep
`
`*I
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`*I
`*I
`*I
`*I
`*I
`*I
`*I
`
`*I
`
`*I
`
`*I
`
`Figure 6-8. Continued.
`
`(more)
`
`238
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 248
`
`
`
`Article 6: Interrupt-Driven Communications
`
`432
`433
`434
`435
`436
`437
`438
`439
`440
`441
`442
`443
`444
`445
`446
`447
`448
`449
`450
`451
`452
`453
`454
`455
`456
`457
`4S8
`459
`460
`461
`462
`463
`464
`465
`466
`467
`468
`469
`470
`471
`472
`473
`474
`475
`476
`477
`478
`479
`480
`481
`482
`
`void Start_Timer ( n ) int n
`timr = g~tmr () + ( long
`
`n *
`
`I* set timeout for n sec
`1000L;
`
`I* if timeout return 1 else return 0
`Timer_Expired ()
`( return ( getmr () > timr );
`}
`
`Set_Vid ()
`{ _i_v ();
`return 0;
`
`I* initialize video
`
`row, col ) int row ,
`
`void locate
`col;
`_cy = row % 25;
`_ex = col % 80;
`_wrpos (row, col );
`
`void deal ()
`{ _deal ();
`
`void deos ()
`deal ();
`i f ( _cy < 24 )
`Ox0600;
`{ rgv.x.ax
`( _atr << 8 ) ;
`rgv.x.bx
`( _cy + 1 ) << 8;
`rgv.x.cx
`rgv.x.dx
`Ox184F;
`int86 ( Ox10, & rgv, & rgv );
`
`locate ( _cy, _ex);
`
`/* use ML from CH2.ASM
`
`/* use ML from CH2.ASM
`
`I* if not last, clear
`
`void cls ()
`{ _cls ();
`
`void cursor ( yn ) int yn ;
`rgv.x.cx = yn ? Ox0607
`: Ox2607;
`rgv.x.ax = Ox0100;
`int86 ( Ox10, & rgv, & rgv );
`
`I* use ML
`
`I* ON/OFF
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`void revvid ( yn ) int yn ;
`{ i f ( yn )
`_atr =_color ( 8, 7 );
`
`I* black on white
`
`*I
`
`Figure 6-8. Continued.
`
`(more)
`
`Section IL- Programming in the MS-DOS Environment
`
`239
`
`ZTE (USA) 1007, Page 249
`
`
`
`putchx ( c ) char c
`{ if ( c ==
`'\n'
`putch ( '\r' );
`putch (c);
`return c
`;
`
`ReacLKeyboard ()
`
`int c
`;
`i f ( kbhit ())
`return ( getch () ) ;
`return ( EOF );
`
`I*
`MODEM SUPPORT
`static char mparm,
`wrk [ 80 ];
`
`0;
`
`void Init_Comm ()
`static int ft
`i f ( ft ++ == 0
`i_m ();
`Set_Farity ( 1 );
`Set_Baud ( 1200 ) ;
`
`#define B1200 Ox80
`#define B300 Ox40
`
`I* put char to CRT
`
`I* get keyboard character
`returns -1 if none present
`
`I* no char at all
`
`*I
`
`I* initialize comm port stuff
`I* firstime flag
`
`I* 8,N, 1
`I* 1200 baud
`
`I* baudrate codes
`
`I* n is baud rate
`
`;
`
`Set_Baud ( n ) int n
`if ( n == 300 )
`mparm = ( mparm & Ox1F ) + B300;
`else
`if ( n == 1200 )
`( mparm & Ox1F ) + B1200;
`mparm =
`else
`return 0;
`sprintf ( wrk, "Baud rate
`cputs ( wrk ) ;
`set_mdm ( mparm );
`return n ;
`
`I* invalid speed
`%d\r\n", n ) ;
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`*I
`
`*I
`*I
`
`*I
`
`*I
`
`*I
`
`Part B: Programming for MS-DOS
`
`else
`_atr
`
`_color ( 15, 0 );
`
`I* white on black
`
`483
`484
`485
`486
`487
`488
`489
`490
`491
`492
`493
`494
`495
`496
`497
`498
`499
`500
`501
`502
`503
`504
`505
`506
`507
`508
`509
`510
`511
`512
`513
`514
`515
`516
`517
`518
`519
`520
`521
`522
`523
`524
`525
`526
`527
`528
`529
`530
`531
`532
`533
`
`#define PAREVN Ox18
`#define PARODD 0x10
`#define PAROFF OxOO
`
`I* MCR bits for commands
`
`*I
`
`Figure 6-8. Continued.
`
`(more)
`
`240
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 250
`
`
`
`Article 6: Interrupt-Driven Communications
`
`#define STOP2 Ox40
`#define WORDS Ox03
`#define WORD7 Ox02
`#define WORD6 Ox01
`
`534
`535
`536
`537
`53S
`539
`540
`541
`542
`543
`544
`545
`546
`547
`54S
`549
`550
`551
`552
`553
`554
`555
`556
`557
`55S
`559 Write_Modem ( c ) char c
`560
`c ) ;
`wrtmdm
`561
`return ( 1 ) ;
`562
`563
`564
`565
`566
`567
`56S
`569
`570
`571
`572
`
`PAREVN
`
`PARODD
`
`cputs ( wrk );
`set_mdm ( mparm );
`return n
`;
`
`Read-Modem ()
`return ( rdmdm ());
`
`void Term_Comm ()
`u_m ();
`
`I* end of cterm.c *I
`
`( WORDS
`
`PAROFF
`
`) ;
`
`Set_Parity ( n ) int n
`{ static int mmode;
`i f ( n ==
`mmode =
`else
`i f ( n -- 2
`( WORD7
`mmode =
`else
`if ( n -- 3
`mmode = ( WORD7
`else
`return 0;
`mparm = mparm & OxEO ) + mmode;
`sprintf ( wr~, "Parity is %s\r\n",
`
`) ;
`
`) ;
`
`I* n is parity code
`
`I* off
`
`I* on and even
`
`I* on and odd
`
`I* invalid code
`
`n ==
`"OFF"
`n == 2? "EVEN"
`
`:
`
`: "ODD" )));
`
`I* return 1 if ok, else 0
`
`I* never any error
`
`I* from int bfr
`
`I* uninstall comm port drivers
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`*I
`
`Figure 6-8. Continued.
`
`CTERM features file-capture capabilities, a simple yet effective script language, and a
`number of stub (that is, incompletely implemented) actions, such as emulation of the VT52
`and vnoo series terminals, indicating various directions in which it can be developed.
`The names of a script file and a capture file can be passed to CTERM in the command line.
`If no filename extensions are included, the default for the script file is .SCR and that for the
`capture file is .CAP. If extensions are given, they override the default values. The capture
`feature can be invoked only if a filename is supplied in the command line, but a script file
`can be called at any time via the Esc command sequence, and one script file can call for
`another with the same feature.
`
`Section II: Programming in the MS-DOS Environment
`
`241
`
`ZTE (USA) 1007, Page 251
`
`
`
`Part B: Programming for MS-DOS
`
`The functions included in CTERM.C are listed and summarized in Table 6-13.
`
`Table 6-13. CTERM.C Functions.
`
`Name
`
`Description
`
`docmd()
`
`kbd_wait()
`kb_file()
`
`esc()
`getfil()
`getnam()
`
`addext()
`
`put_ cap()
`cap_flush()
`
`Program documentation.
`Include files.
`Definitions.
`Global data areas.
`External prototype declaration.
`Wants_ To_ Abort() Checks for Ctrl-Break or Ctrl-C being pressed.
`main()
`Main program loop; includes modem engine and
`sequential state machine to decode remote
`commands.
`Gets, interprets, and performs local (console or
`script) command.
`Waits for input from console or script file.
`Gets keystroke from console or script; returns EOF
`if no character available.
`Translates script escape sequence.
`Gets name of script file and opens the file.
`Gets string from console or script into designated
`buffer.
`Checks buffer for extension; adds one if none
`given.
`Writes character to capture file if capture in effect.
`Closes capture file and terminates capture mode if
`capture in effect.
`Timer data locations.
`Returns time since midnight, in milliseconds.
`Sleeps n milliseconds.
`Sets timer for n seconds.
`Checks timer versus clock.
`Initializes video data.
`Positions cursor on display.
`Deletes to end of line.
`Deletes to end of screen.
`Clears screen.
`Turns cursor on or off.
`Toggles inverse/normal video display attributes.
`Writes char to display using putch() (Microsoft C
`library).
`
`lines
`
`1-5
`7-11
`12-20
`22-43
`45
`47-49
`52-165
`
`167-297
`
`299-304
`306-334
`
`336-362
`364-370
`372-382
`
`384-393
`
`395-398
`400-406
`
`408-411
`413-425
`427-432
`434-436
`438-440
`442-445
`447-452
`454-456
`458-468
`470-472
`474-478
`480-485
`487-492
`
`getmt()
`Delay()
`Start_ Timet()
`Timer_ Expired()
`Set_Vid()
`locate()
`deol()
`deos()
`cls()
`cur sot()
`revvid()
`putchx()
`
`(more)
`
`242
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 252
`
`
`
`Article 6: Interrupt-Driven Communications
`
`Table6-13. Continued.
`
`lines
`
`494-500
`502-504
`506-512
`514-515
`517-529
`531-537
`539-557
`559-562
`564-566
`568-570
`
`Name
`
`Description
`
`Read_Keyboard()
`
`Init_Comm()
`
`Set_ Baud()
`
`Set_ Parity()
`Write_ Modem()
`Read_Modem()
`Term_Comm()
`
`Gets keystroke from keyboard.
`Modem data areas.
`Installs ISR and so forth and initializes modem.
`Baud-rate definitions.
`Changes bps rate of UART.
`Parity, WL definitions.
`Establishes UART parity mode.
`Sends character to UART.
`Gets character from ISR's buffer.
`Uninstalls ISR and so forth and restores original
`vectors.
`
`·For communication with the console, CTERM uses the special Microsoft C library func(cid:173)
`tions defined by CONIO.H, augmented with the functions in the CH2.ASM handler. Much
`of the code may require editing if used with other compilers. CTERM also uses the func(cid:173)
`tion prototype file CTERM.H, listed in Figure 6-9, to optimize function calling within the
`program.
`
`4
`
`function prototypes for CTERM.C *I
`I* CTERM.H -
`int Wants_To_Abort(void);
`void rnain(int ,char* *);
`int docrnd(void);
`int kbd_wait(void);
`int kb_file(void);
`int esc (void) ;
`FILE *getfil(void);
`void getnarn (char *, int ) ; ·
`char *addext(char *,char*);
`void put_cap(char );
`void cap_flush(void);
`long getrnr(void);
`void Delay(int );
`void Start_Tirner(int );
`int Timer-Expired (void);
`int Set_Vid(void);
`void locate(int ,int );
`void deol(void);
`void deos(void);
`void cls (void) ;
`void cursor(int );
`void revvid(int );
`int putchx(char );
`
`Figure 6-9. CTERM.H.
`
`(more)
`
`Section II: Programming in the MS-DOS Environment
`
`243
`
`ZTE (USA) 1007, Page 253
`
`
`
`Part B: Programming for MS-DOS
`
`int Read_Keyboard(void);
`void Init_Comm(void);
`int Set_Baud(int ) ;
`int Set_Parity(int );
`int Write_Modem(char );
`int Read_Modem(void);
`void Term_Comm(void);
`
`I* CH1 .ASM functions - modem interfacing *I
`void L..m (void) ;
`void set_mdm(int);
`void wrtmdm(int);
`void Send_Byte(int);
`int
`rdmdm(void);
`void u_m (void) ;
`
`I* CH1A.ASM functions - exception handlers *I
`void set_int (void) ;
`void rst_int (void) ;
`int broke (void) ;
`
`I* CH2.ASM functions - video interfacing •I
`void _i_v(void);
`int _wrpos(int, int);
`void _deol(void);
`void _cls(void);
`int _color(int, int);
`
`Figure 6-9. Continued.
`
`Program execution begins at the entry to main(), line 52. CTERM first checks (lines 56
`through 59) whether any filenames were passed in the command line; if they were,
`CTERM opens the corresponding files. Next, the program installs the exception handler
`Cline 60), initializes the video handler (line 61), clears the display (line 62), and announces
`its presence (lines 63 and 64). The serial driver is installed and initialized to 1200 bps and
`no parity (lines 65 through 67), and the program enters its main modem-engine loop
`(lines 68 through 159).
`
`This loop is functionally the same as that used in ENGINE, but it has been extended to
`detect an Esc from the keyboard as signalling the start of a local command sequence (lines
`70 through 73) and to include a state-machine technique (lines 80 through 153) to recog(cid:173)
`nize incoming escape sequences, such as the VT52 or VT100 codes. To specify a local com(cid:173)
`mand from the keyboard, press the Escape (Esc) key, then the first letter of the local
`command desired. After the local command has been selected, press any key (such as
`Enter or the spacebar) to continue. To get a listing of all the commands available, press
`Esc-H.
`
`The kb_file() routine of CTERM (called in the main loop at line 69) can get its input from
`either a script file or the keyboard. If a script file is open (lines 308 through 330), it is used
`until EOF is reached or until the operator presses Ctrl-C to stop script-file input. Otherwise,
`
`244
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 254
`
`
`
`Article 6: Interrupt-Driven Communications
`
`input is taken from the keyboard (lines 331 and 332). If a script file is in use, its input is
`echoed to the display (lines 325 through 329) if the V command has been given.
`
`To permit the Esc character itself to be placed in script files, the backslash (\) character
`serves as a secondary escape signal. When a backslash is detected (lines 323 and 324) in
`the input stream, the next character input is translated according to the following rules:
`
`Character
`
`Interpretation
`
`E ore
`Norn
`Ror r
`Tort
`A
`
`Translates to Esc.
`Translates to Linefeed.
`Translates to Enter (CR).
`Translates to Tab.
`Causes the next character input to be converted into a control character.
`
`Any other character, including another \ , is not translated at all.
`
`When the Esc character is detected from either the console or a script file, the docmd()
`function (lines 167 through 297) is called to prompt for and decode the next input charac(cid:173)
`ter as a command and to perform appropriate actions. Valid command characters, and the
`actions they invoke, are as follows:
`
`Command
`Character
`
`Action
`
`D
`
`E
`F
`H
`N
`0
`Q
`R
`s
`u
`v
`w
`
`Delay 0-9 seconds, then proceed. Must be followed by a decimal
`digit that indicates how long to delay.
`Set EVEN parity.
`Set (fast) 1200 baud.
`Display list of valid commands.
`Set no parity.
`Set ODD parity.
`Quit; return to MS~DOS command prompt.
`Reset modem.
`Set (slow) 300 baud.
`Use script file (CTERM prompts for filename).
`Verify file input. Echoes each script-file byte.
`Wait for character; the next input character is the one that must be
`matched.
`
`Any other character input after an Esc and the resulting Command prompt generates the
`message Don't know X (where X stands for the actual input character) followed by the
`prompt Use 'H' command for Help.
`
`Section 11- Programming in the MS-DOS Environment
`
`245
`
`ZTE (USA) 1007, Page 255
`
`
`
`Part B: Programming for MS-DOS
`
`If input is taken from a script and the V flag is off, docmd() performs its task quietly, with
`no output to the screen. If input is received from the console, however, the command let(cid:173)
`ter, followed by a descriptive phrase, is echoed to the screen. Input, detection, and execu(cid:173)
`tion of the local commands are accomplished much as in CDVUTL, by way of a large
`switch() statement (lines 178 through 290).
`
`Although the listed commands are only a subset of the features available in CDVUTL for
`the device-driver program, they are more than adequate for creating useful scripts. The
`predecessor of CTERM (DT115.EXE), which included the CompuServe B-Protocol file(cid:173)
`transfer capability but had no additional commands, has been in use since early 1986 to
`handle automatic uploading and downloading of files from the CompuServe Information
`Service by means of script files. In conjunction with an auto-dialing modem, DT115.EXE
`handles the entire transaction, from login through logout, without human intervention.
`
`All the bits and pieces of CTERM are put together by assembling the three handlers
`with MASM, compiling CTERM with Microsoft C, and linking all four object modules into
`an executable file. Figure 6-10 shows the complete sequence and also the three ways of
`using the finished program.
`
`Compiling:
`
`C>MASM CH1; <Enter>
`C>MASM CH1A; <Enter>
`C>MASM CH2; <Enter>
`C>MSC CTERM; <Enter>
`
`Linking:
`
`C>LINK CTERM+CH1+CH1A+CH2; <Enter>
`
`Use:
`(no files)
`
`C>CTERM <Enter>
`
`or
`(script only)
`
`C>CTERM scriptfile <Enter>
`
`or
`
`C>CTERM scriptfile capturefile <Enter>
`
`Figure 6-10. Putting CTERM together and using it.
`
`246
`
`The MS-DOS Encyclopedia
`
`jim Kyle
`Chip Rabinowitz
`
`ZTE (USA) 1007, Page 256
`
`
`
`Article 7: File and Record Management
`
`Article7
`File and Record Management
`
`The core of most application programs is the reading, processing, and writing of data
`stored on magnetic disks. This data is organized into files, which are identified by name;
`the files, in turn, can be organized by grouping them into directories. Operating systems
`provide application programs with services that allow them to manipulate these files and
`directories without regard to the hardware characteristics of the disk device. Thus, applica(cid:173)
`tions can concern themselves solely with the form and content of the data, leaving the
`details of the data's location on the disk and of its retrieval to the operating system.
`
`The disk storage services provided by an operating system can be categorized into file
`functions and record functions. The file functions operate on entire files as named
`entities, whereas the record functions provide access to the data contained within files.
`(In some systems, an additional class of directory functions allows applications to deal
`with collections of files as well.) This article discusses the MS-DOS function calls that
`allow an application program to create, open, close, rename, and delete disk files; read
`data from and write data to disk files; and inspect or change the information (such as
`attributes and date and time stamps) associated with disk filenames in disk directories.
`See also PROGRAMMING IN THE MS-DOS ENVIRONMENT: STRUCTURE OF MS-DOS:
`MS-DOS Storage Devices; PROGRAMMING FOR Ms-oos: Disk Directories and Volume Labels.
`
`Historical Perspective
`
`Current versions of MS-DOS provide two overlapping sets of file and record management
`services to support application programs: the handle functions and the file control block
`(FCB) functions. Both sets are available through Interrupt 21H (Table 7-1). See SYSTEM
`CALLS: INTERRUPT 21H. The reasons for this surprising duplication are strictly historical.
`
`The earliest versions of MS-DOS used FCBs for all file and record access because CP/M,
`which was the dominant operating system on 8-bit microcomputers, used FCBs. Microsoft
`chose to maintain compatibility with CP/M to aid programmers in converting the many
`existing CP/M application programs to the 16-bit MS-DOS environment; consequently,
`MS-DOS versions l.x included a set of FCB functions that were a functional superset of
`those present in CP/M. As personal computers evolved, however, the FCB access method
`did not lend itself well to the demands of larger, faster disk drives.
`
`Accordingly, MS-DOS version 2.0 introduced the handle functions to provide a file and
`record access method similar to that found in UNIX/XENIX. These functions are easier to
`use and more flexible than their FCB counterparts and fully support a hierarchical (tree(cid:173)
`like) directory structure. The handle functions also allow character devices, such as the
`
`Section II: Programming in the MS-DOS Environment
`
`247
`
`ZTE (USA) 1007, Page 257
`
`
`
`Part B: Programming for MS-DOS
`
`console or printer, to be treated for some purposes as though they were files. MS-DOS ver(cid:173)
`sion 3.0 introduced additional handle functions, enhanced some of the existing handle
`functions for use in network environments, and provided improved error reporting for
`all functions.
`
`The handle functions, which offer far more capability and performance than the FCB
`functions, should be used for all new applications. Therefore, they are discussed first in
`this article.
`
`Table 7-1. Interrupt 21H Function Calls for File and Record Management.
`
`Operation
`
`Create file.
`Create new file.
`Create temporary file.
`Open file.
`Close file.
`Delete file.
`Rename file.
`Perform sequential read.
`Perform sequential write.
`Perform random record read.
`Perform random record write.
`Perform random block read.
`Perform random block write.
`Set disk transfer area address.
`Get disk transfer area address.
`Parse filename.
`Position read/write pointer.
`Set random record number.
`Get file size.
`Get/Set file attributes.
`Get/Set date and time stamp.
`Duplicate file handle.
`Redirect file handle.
`
`Handle
`Function
`
`FCB
`Function
`
`16H
`
`OFH
`lOH
`13H
`17H
`14H
`15H
`21H
`22H
`27H
`28H
`lAH
`2FH
`29H
`
`24H
`23H
`
`3CH
`5BH
`5AH
`3DH
`·3EH
`41H
`56H
`3FH
`40H
`3FH
`40H
`
`42H
`
`42H
`43H
`57H
`45H
`46H
`
`248
`
`The MS-DOS Encyclopedia
`
`ZTE (USA) 1007, Page 258
`
`
`
`Article 7: File and Record Management
`
`Using the Handle Functions
`
`The initial link between an application program and the data stored on disk is the name of
`a disk file in the form
`
`drive:path\filename.ext
`
`where drive designates the disk on which the file resides, path specifies the directory
`on that disk in which the file is located, and filename.ext identifies the file itself. If drive
`and/or path is omitted, MS-DOS assumes the default disk drive and current directory.
`Examples of acceptable pathnames include
`
`C: \PAYROLL\ TAXES.DAT
`LETTERS\MEMO.TXT
`BUDGET.DAT
`
`Pathnames can be hard-coded into a program as part of its data. More commonly, how(cid:173)
`ever, they are entered by the user at the keyboard, either as a command-line parameter or
`in response to a prompt from the program. If the pathname is provided as a command(cid:173)
`line parameter, the application program must extract it from the other information in the
`command line: Therefore, to allow a program to distinguish between pathnames and
`other parameters when the two are combined in a command line, the other parameters,
`such as switches, usually begin with a slash(/) or dash ( -) character.
`
`All handle functions that use a pathname require the name to be in the form of an ASCIIZ
`stri~g-that is, the name must be terminated by a null (zero) byte. If the pathname is
`hard-coded into a program, the null byte must be part of the ASCIIZ string. If the path(cid:173)
`name is obtained from keyboard input or from a command-line parameter, the null byte
`must be appended by the program. See Opening an Existing File below.
`
`To use a disk file, a program opens or creates the file by calling the appropriate MS-DOS
`function with the ASCIIZ pathname. MS-DOS checks the pathname for invalid characters
`and, if the open or create operation is successful, returns a 16-bit handle, or identification
`code, for the file. The program uses this handle for subsequent operations on the file, such
`as record reads and writes.
`
`The total number of handles for simultaneously open files is limited in two ways. First, the
`per-process limit is 20 file handles. The process's first five handles are always assigned to
`the standard devices, which default to the CON, AUX, and PRN character devices:·
`
`Handle
`
`Service
`
`Default
`
`0
`1
`2
`3
`4
`
`Standard input
`Standard output
`Standard error
`Standard auxiliary
`Standard list
`
`Keyboard (CON)
`Video display (CON)
`Video display (CON)
`First communications port (AUX)
`First parallel printer port (PRN)
`
`Section 11· Programming in the MS-DOS Environment
`
`249
`
`ZTE (USA) 1007, Page 259
`
`
`
`Part B: Programming for MS-DOS
`
`Ordinarily, then, a process has o