home *** CD-ROM | disk | FTP | other *** search
- {$C-,V-,K-}
- (****************************************************************************)
- (* *)
- (* Author: Paul Meiners *)
- (* P & M Software Company *)
- (* 9350 Country Creek #30 *)
- (* Houston, Texas 77036 *)
- (* *)
- (* Phone: (713) 772-2090 *)
- (* *)
- (* Date: March 3, 1985 *)
- (* *)
- (* Language: Turbo PASCAL version 3.00B *)
- (* *)
- (* Remarks: This program provides terminal emulation with capture to *)
- (* to disk, XMODEM file transfers, color and music. Uses *)
- (* interrupt driven serial I/O with circular queues. Uses a *)
- (* removable window system. VT-100 emulation is optional. *)
- (* *)
- (****************************************************************************)
-
- program
- TMODEM;
-
- type
- strtype = string[255];
- string40 = string[40];
- string30 = string[30];
- string20 = string[20];
- string10 = string[10];
- alt_char_array = array[ 96..127 ] of byte;
- tab_stop_array = array[ 1..80 ] of byte;
-
- const
- version = '4.0';
- sin_buf_size = 5120;
- sin_buf_fill_lim = 3072;
- sin_buf_drain_lim = 2048;
- sout_buf_size = 512;
- capture_buf_size = 1024;
- max_dial_entries = 16;
- SOH = ^A;
- SYN = ^V;
- CAN = ^X;
- NAK = ^U;
- ACK = ^F;
- EOT = ^D;
- SUB = ^Z;
- BADNAME = #$75;
- CR = ^M;
- LF = ^J;
- CRLF = ^M^J;
- ESC = #27;
- NUL = #00;
- DEL = #127;
- FF = ^L;
- BS = ^H;
- HT = ^I;
- VT = ^K;
- default_stopbits : integer = 1;
- default_databits : integer = 8;
- default_parity : integer = 0; { 0=None, 1=Even, 2=Odd }
- default_baud : integer = 1200;
- wait_increment : integer = 333; { 1/3 of a second. }
- datasegment : integer = 0;
- XON : integer = 17; { XON is a DC1 character. }
- XOFF : integer = 19; { XOFF is a DC3 character. }
- dial_pre_str : string40 = 'ATDT ';
- dial_post_str : string10 = '|';
- modem_init_str : string40 = 'AT S0=0|';
- speaker_off : string40 = 'AT M0|';
- speaker_on : string40 = 'AT M1|';
- forced_carrier : string10 = 'FALSE';
- emulation_mode : string10 = 'FALSE';
- auto_LF : string10 = 'FALSE';
- redial_time : integer = 60;
- carrier_timeout : integer = 35;
- com_port : integer = 1;
- comment_ch : char = ';';
- FGcolor : integer = 15;
- BGcolor : integer = 0;
- split_screen : string10 = 'FALSE';
- max_xmodem_buffers : integer = 64;
- alt_character : alt_char_array = ( 4,97,98,99,100,101,102,241,104,105,
- 217,191,218,192,197,196,196,196,196,196,195,180,193,
- 194,179,243,242,227,216,156,250,127 );
- tab_stop : tab_stop_array = ( 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
- 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
- 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
- 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
- 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 );
- type
- sin_buffer_type = array[1..sin_buf_size] of byte;
- sout_buffer_type = array[1..sout_buf_size] of byte;
- func_buffer_type = array[1..40] of string[75];
- capture_ptr_type = ^capture_record;
- capture_record = record
- capture_store_ptr : integer;
- capture_buffer : array[1..capture_buf_size] of char;
- capture_next : capture_ptr_type;
- end;
- xmodem_buf = array[1..128] of char;
- xmodem_table = array[1..255] of xmodem_buf;
- registerset = record
- AX,BX,CX,DX,BP,DI,SE,DS,ES,Flags : integer;
- end;
- dialrec = record
- bbs_name : string30;
- bbs_number : string30;
- bbs_baud : integer;
- bbs_parity : integer;
- bbs_databits : integer;
- bbs_stopbits : integer;
- end;
- dialarray = record
- no_of_dial_entries : integer;
- dir_entries :
- array[1..max_dial_entries] of dialrec;
- end;
- sort_ptr_type = ^dialsort;
- dialsort = record
- sort_rec : dialrec;
- sort_next : sort_ptr_type;
- end;
- screen_char = record
- disp_char : char;
- disp_attr : byte;
- end;
- screen_line = array[1..80] of screen_char;
- screen_type = array[1..24] of screen_line;
- saved_cursor = record
- x_coor : integer;
- y_coor : integer;
- bscan : integer;
- sscan : integer;
- ForeG : integer;
- BackG : integer;
- end;
- telink_header = record
- telink_buf_len : byte;
- telink_hdr_id : char;
- telink_blk_no : byte;
- telink_blk_cmpl : byte;
- telink_file_size : array[1..4] of byte;
- telink_create_time : array[1..4] of byte;
- telink_filename : array[1..16] of char;
- telink_version : byte;
- telink_prog_name : array[1..16] of char;
- end;
-
- var
- mono_scr : screen_type absolute $B000:$0000;
- color_scr : screen_type absolute $B800:$0000;
- crt_mode : byte absolute $0040:$0049;
- scroll_top : byte;
- scroll_bot : byte;
- scroll_region : boolean;
- scroll_last : byte;
- sin_buf_fill_cnt : integer;
- sin_xoff : boolean;
- sin_buffer_ptr : ^sin_buffer_type;
- sin_store_ptr : integer;
- sin_read_ptr : integer;
- sout_buffer_ptr : ^sout_buffer_type;
- sout_store_ptr : integer;
- sout_read_ptr : integer;
- sout_int_off : boolean;
- turn_IRQ_on : byte;
- turn_IRQ_off : byte;
- IRQ_vector_ofs : integer;
- IRQ_vector_seg : integer;
- hold_vector_ofs : integer;
- hold_vector_seg : integer;
- com_addr : array[ 1..2 ] of integer absolute $0000:$0400;
- base_com_addr : integer;
- int_enable_reg : integer;
- int_ident_reg : integer;
- int_ident : byte;
- line_control_reg : integer;
- modem_control_reg : integer;
- line_status_reg : integer;
- line_status : byte;
- modem_status_reg : integer;
- sync_time : integer;
- xmodem_table_ptr : ^xmodem_table;
- old_max : integer;
- old_screen : string10;
- xmodem_buf_cnt : integer;
- xmodem_ptr : integer;
- xmodem_rd : integer;
- xblocksize : integer;
- xfilesize : integer;
- batch_mode : boolean;
- recv_file_size : real;
- recv_create_time : array[1..4] of byte;
- recv_date_time : array[1..2] of integer absolute recv_create_time;
- crc_register : integer;
- crc_input : integer;
- crc_mode : boolean;
- continue_transfer : boolean;
- capture_flag : boolean;
- capture_warning : boolean;
- capture_first : capture_ptr_type;
- capture_curr : capture_ptr_type;
- printer_on : boolean;
- printer_control_off : boolean;
- sort_curr : sort_ptr_type;
- sort_first : sort_ptr_type;
- sort_prev : sort_ptr_type;
- exit_program : boolean;
- default_chg : boolean;
- func_key : ^func_buffer_type;
- keyfile : text;
- block_count : integer;
- error_count : integer;
- filename : string40;
- recv_file : file;
- xmit_file : file;
- size_file : file of byte;
- textfile : text;
- textimage : strtype;
- dial_drive : integer;
- dial_PATH : string40;
- cnf_PATH : string40;
- dialfile : file of dialarray;
- dial_dir : dialarray;
- dialarray_number : integer;
- dial_str : string40;
- redial_number : string40;
- redial_name : string30;
- baud : integer;
- stopbits : integer;
- databits : integer;
- par : integer;
- kbd_char : char;
- a_key : string[2];
- regs : registerset;
- half_duplex : boolean;
- ascii_mode : boolean;
- escape_mode : boolean;
- escape_number : byte;
- escape_register : array[1..50] of byte;
- escape_str : strtype;
- escape_type : char;
- escape_sub_type : char;
- line_drawing_chars : boolean;
- ok : boolean;
- parity_ch : string10;
- baud_ch : string10;
- stop_ch : string10;
- data_ch : string10;
- FG,BG : integer;
- shade_no : integer;
- FG_shade : array[ 0..7 ] of integer;
- blink_state : integer;
- intensity_state : integer;
- scale : array[ 0..20 ] of real;
- notes : array[ 1..84 ] of integer;
- factor : array[ 0..6 ] of real;
- tempo : real;
- note_length : integer;
- octave : integer;
- dots : integer;
- dnote : array[ 0..6 ] of real;
- music_mode : real;
- rest_mode : real;
- silent_mode : boolean;
- monitor_mode : boolean;
- time_fix : string10;
- curr_time : string10;
- start_time : string10;
- dial_time : string10;
- a_second : integer;
- yes_no : string[4];
- mx,my : byte;
- insert_mode : boolean;
- auto_wrap : boolean;
- cursor_hold : saved_cursor;
- curr_bscan : integer;
- curr_sscan : integer;
- keypad_mode : boolean;
- rx,ry : byte;
- lx,ly : byte;
-
- {$I BASIC.INC}
- {$I RWINDOW.INC}
- (****************************************************************************)
- (* COMMAND DISTRIBUTOR *)
- (****************************************************************************)
- procedure
- exec_command(ch : char); FORWARD;
-
- (****************************************************************************)
- (* WAIT FOR A KEY *)
- (****************************************************************************)
- procedure
- wait_for_key;
- begin
- write(' Press ANY key to continue...');
- repeat
- repeat
- a_key := inkey;
- until a_key <> '';
- if length(a_key) = 2 then begin
- exec_command( a_key[2] );
- a_key := '';
- end;
- until length(a_key) = 1;
- end;
-
- (****************************************************************************)
- (* REWRITE CONFIG FILE *)
- (****************************************************************************)
- procedure
- rewrite_config_file;
- begin
- rewrite(textfile);
- writeln(textfile,'CM=',com_port);
- writeln(textfile,'ST=',default_stopbits);
- writeln(textfile,'DA=',default_databits);
- writeln(textfile,'PA=',default_parity);
- writeln(textfile,'BA=',default_baud);
- writeln(textfile,'WA=',wait_increment);
- writeln(textfile,'PR=',dial_pre_str);
- writeln(textfile,'PO=',dial_post_str);
- writeln(textfile,'MI=',modem_init_str);
- writeln(textfile,'SY=',speaker_on);
- writeln(textfile,'SN=',speaker_off);
- writeln(textfile,'RT=',redial_time);
- writeln(textfile,'FC=',forced_carrier);
- writeln(textfile,'CT=',carrier_timeout);
- writeln(textfile,'DP=',dial_PATH);
- writeln(textfile,'XO=',XON);
- writeln(textfile,'XF=',XOFF);
- writeln(textfile,'VT=',emulation_mode);
- writeln(textfile,'LF=',auto_LF);
- writeln(textfile,'FG=',FGcolor);
- writeln(textfile,'BG=',BGcolor);
- writeln(textfile,'CC=',comment_ch);
- writeln(textfile,'SS=',split_screen);
- writeln(textfile,'MX=',max_xmodem_buffers);
- end;
-
- (****************************************************************************)
- (* SETUP SPLIT SCREEN OPERATION *)
- (****************************************************************************)
- procedure
- setup_split;
- var
- i : integer;
- begin
- clrscr;
- rx := 1;
- ry := 1;
- gotoxy(1,1);
- for i:=1 to 80 do write('-');
- gotoxy(37,1);
- write(' Remote ');
- lx := 1;
- ly := 1;
- gotoxy(1,18);
- for i:=1 to 80 do write('-');
- gotoxy(37,18);
- write(' Local ');
- gotoxy(1,2);
- end;
-
- {$I MUSIC.INC}
- {$I DIRECT.INC}
- {$I TM1.INC}
- {$I TM2.INC}
- {$I TM3.INC}
- (****************************************************************************)
- (* KEYBOARD HANDLER *)
- (****************************************************************************)
- procedure
- local_swrite;
- begin
- if a_key[1]=CR then begin
- scrwrite(a_key[1]);
- a_key := LF;
- end;
- scrwrite(a_key[1]);
- end;
-
- procedure
- keyboard;
- begin
- if length(a_key) = 2 then begin
- exec_command(a_key[2]);
- if default_chg then change_defaults;
- end
- else begin
- store_sout_buffer(a_key[1]);
- if split_screen[1]='T' then begin
- window(1,19,80,24);
- gotoxy(lx,ly);
- local_swrite;
- lx := wherex;
- ly := wherey;
- window(1,1,80,24);
- exit;
- end;
- if half_duplex then
- local_swrite;
- end;
- end;
-
- (****************************************************************************)
- (* INITIALIZE FUNCTION KEYS *)
- (****************************************************************************)
- procedure
- initialize_function_keys;
- var
- i : byte;
- begin
- for i:=1 to 40 do func_key^[i]:='';
- assign(keyfile,'TMODEM.KEY');
- {$I-}
- reset(keyfile);
- {$I+}
- ok:=(ioresult = 0);
- if not ok then begin
- rewrite(keyfile);
- for i:=1 to 40 do
- writeln(keyfile,func_key^[i]);
- end
- else begin
- i :=0;
- while ( not eof(keyfile) ) and ( i < 40 ) do begin
- i := succ( i );
- readln(keyfile,func_key^[i]);
- end;
- end;
- close(keyfile);
- end;
-
- (****************************************************************************)
- (* READ CONFIG FILE *)
- (****************************************************************************)
- procedure
- read_config_file;
- var
- teststr : string[2];
- dataval : integer;
- begin
- assign(textfile,'TMODEM.CNF');
- {$I-}
- reset(textfile);
- {$I+}
- ok:=(ioresult = 0);
- if not ok then
- rewrite_config_file
- else begin
- while not eof(textfile) do begin
- readln(textfile,textimage);
- teststr := copy(textimage+' ',1,2);
- upstring(teststr);
- dataval := bval(copy(textimage+' ',4,9));
- delete(textimage,1,3);
- if teststr = 'ST' then default_stopbits := dataval;
- if teststr = 'DA' then default_databits := dataval;
- if teststr = 'PA' then default_parity := dataval;
- if teststr = 'BA' then default_baud := dataval;
- if teststr = 'WA' then wait_increment := dataval;
- if teststr = 'PR' then dial_pre_str := textimage;
- if teststr = 'MI' then modem_init_str := textimage;
- if teststr = 'PO' then dial_post_str := textimage;
- if teststr = 'SN' then speaker_off := textimage;
- if teststr = 'SY' then speaker_on := textimage;
- if teststr = 'RT' then redial_time := dataval;
- if teststr = 'FC' then forced_carrier := textimage;
- if teststr = 'CT' then carrier_timeout := dataval;
- if teststr = 'DP' then dial_PATH := textimage;
- if teststr = 'VT' then emulation_mode := textimage;
- if teststr = 'LF' then auto_LF := textimage;
- if teststr = 'CM' then com_port := dataval;
- if teststr = 'FG' then FGcolor := dataval;
- if teststr = 'BG' then BGcolor := dataval;
- if teststr = 'CC' then comment_ch := textimage[1];
- if teststr = 'SS' then split_screen := textimage;
- if teststr = 'MX' then max_xmodem_buffers := dataval;
- end;
- end;
- close(textfile);
- a_second := round( 3.003004 * wait_increment );
- end;
-
- (****************************************************************************)
- (* MAIN LINE CODE *)
- (****************************************************************************)
- begin
- dial_drive := ord(default_drive) - pred( ord('A') );
- getdir(dial_drive,dial_PATH);
- if dial_PATH[length(dial_PATH)] <> '\' then
- dial_PATH := dial_PATH + '\';
- cnf_PATH := dial_PATH;
- read_config_file;
- FG := FGcolor;
- BG := BGcolor;
- blink_state := 0;
- intensity_state := 0;
- set_intensity;
- lowvideo;
- textcolor( FG );
- textbackground( BG );
- window(1,1,80,25);
- clrscr;
- initwin;
- capture_flag := false;
- printer_on := false;
- printer_control_off := true;
- ascii_mode := false;
- escape_mode := false;
- monitor_mode := false;
- line_drawing_chars := false;
- keypad_mode := false;
- auto_wrap := false;
- insert_mode := false;
- default_chg := false;
- scroll_top := 1;
- scroll_bot := 24;
- scroll_last := 24;
- scroll_region := false;
- with cursor_hold do begin
- x_coor := 1;
- y_coor := 1;
- bscan := 6;
- sscan := 7;
- ForeG := FG;
- BackG := BG;
- end;
- curr_bscan := 6;
- curr_sscan := 7;
- time_fix := time;
- dial_time := time_fix;
-
- new( sin_buffer_ptr );
- new( sout_buffer_ptr );
- new( func_key );
- if not ( max_xmodem_buffers in [ 4..255 ] ) then
- max_xmodem_buffers := 64;
- getmem( xmodem_table_ptr, max_xmodem_buffers * 128 );
- datasegment := DSeg;
-
- baud := default_baud;
- stopbits := default_stopbits;
- databits := default_databits;
- par := default_parity;
- init_com_port;
-
- exit_program := false;
- half_duplex := false;
-
- dial_str := modem_init_str;
- dialer;
- redial_number := '';
- redial_name := '';
- initialize_function_keys;
-
- mkwin(2,2,79,22,'TMODEM, ver '+version);
- writeln;
- writeln(' If you use this program and like it, a contribution ($20 suggested) will');
- writeln(' be appreciated.');
- writeln;
- writeln;
- writeln(' P & M Software Co.');
- writeln(' 9350 Country Creek #30');
- writeln(' Houston, Texas 77036');
- writeln;
- writeln;
- writeln(' You are encouraged to copy and share this program with others, on the');
- writeln(' condition that the program not be sold for profit, except by the author,');
- writeln(' and that this notice is not altered, bypassed, or removed.');
- writeln;
- gotoxy(50,wherey);
- writeln('Good Luck,');
- gotoxy(50,wherey);
- writeln('Paul Meiners.');
- writeln;
- escape_win;
- gotoxy(19,23);
- write('Copyright (c) 1985 by: P & M Software Co.');
- reset_win;
-
- write(' Do You Want Music? ');
- repeat until keypressed;
- read(kbd,kbd_char);
- write(kbd_char);
- initialize_music;
- if ( emulation_mode = 'T' ) or ( upcase( kbd_char ) <> 'Y' ) then
- silent_mode := true
- else
- silent_mode := false;
- rmwin;
- flush_sin_buff;
- display_prompts;
-
- delay( wait_increment );
- if split_screen[1]='T' then
- setup_split;
- repeat
- if sin_read_ptr <> sin_store_ptr then begin
- kbd_char := read_sin_buffer;
- if split_screen[1]='T' then begin
- window(1,2,80,17);
- gotoxy(rx,ry);
- scrwrite(kbd_char);
- rx := wherex;
- ry := wherey;
- window(1,1,80,24);
- end
- else
- scrwrite(kbd_char);
- end;
- a_key := inkey;
- if a_key <> '' then keyboard;
- until exit_program;
-
- port[int_enable_reg] := 0; { Turn off modem and reset }
- port[modem_control_reg] := 0; { vectors. }
- port[$21] := port[$21] or turn_IRQ_off;
- memw[$0000:IRQ_vector_ofs] := hold_vector_ofs;
- memw[$0000:IRQ_vector_seg] := hold_vector_seg;
- freemem( xmodem_table_ptr, max_xmodem_buffers * 128 );
- dispose( func_key );
- dispose( sout_buffer_ptr );
- dispose( sin_buffer_ptr );
-
- if capture_flag then toggle_capture_mode;
- window(1,1,80,25);
- clrscr;
- change_drive( cnf_PATH[1] );
- end.