424 lines
11 KiB
Plaintext
424 lines
11 KiB
Plaintext
|
_REMOTE CONNECTIVITY FOR PORTABLE TERMINALS: PART I_
|
||
|
by Dan Troy
|
||
|
|
||
|
|
||
|
[LISTING ONE]
|
||
|
|
||
|
void process_VT100_input(char *z)
|
||
|
{
|
||
|
char data;
|
||
|
TERMINALP t = (TERMINALP)z; /* default VT100 parameters */
|
||
|
|
||
|
if(!eof()) /* if character exists in */
|
||
|
{ /* serial buffer */
|
||
|
read(&data); /* then read it */
|
||
|
active = TRUE; /* set global activity flag */
|
||
|
write_screen(t, data); /* process VT100 character */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
[LISTING TWO]
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
char addlf; /* line feed/new line */
|
||
|
char keymode; /* cursor/application */
|
||
|
char insert; /* replace/insert */
|
||
|
char autowrap; /* off/on */
|
||
|
char keypad; /* numeric/alternate */
|
||
|
char origin; /* absolute/relative */
|
||
|
char kblock; /* keyboard unlock/lock */
|
||
|
}TERMINAL, *TERMINALP;
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING THREE]
|
||
|
|
||
|
init_emulation_mode:
|
||
|
|
||
|
clr ea ;shut off interrupts
|
||
|
mov dptr,#emul_processor_address ;get c function address
|
||
|
mov a,r3 ;get low byte of function
|
||
|
;from C call
|
||
|
movx @dptr,a ;save at storage address
|
||
|
inc dptr ;inc processor address ptr
|
||
|
mov a,r2 ;get high byte of function
|
||
|
movx @dptr,a ;save at storage address
|
||
|
setb ea ;turn back on interrupts
|
||
|
|
||
|
lcall get_and_decr_stack_pointer ;get data stack ptr
|
||
|
;parameter data struct
|
||
|
movx a,@dptr ;get low byte of setup
|
||
|
;parameter data struct
|
||
|
xch a,b ;save in b reg
|
||
|
lcall get_and_decr_stack_pointer ;adjust data stack ptr
|
||
|
movx a,@dptr ;get high byte of setup
|
||
|
;parameter data struct
|
||
|
push acc ;save on program stack
|
||
|
mov dptr,#data_struct ;get storage address
|
||
|
xch a,b
|
||
|
movx @dptr,a ;save low byte of setup
|
||
|
inc dptr
|
||
|
pop acc
|
||
|
movx @dptr,a ;save high byte of setup
|
||
|
|
||
|
ret
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING FOUR]
|
||
|
|
||
|
init_emulation_mode(process_VT100_input, (char *) t);
|
||
|
|
||
|
|
||
|
[LISTING FIVE]
|
||
|
|
||
|
typedef void(*PTF) (); /* a pointer to a function */
|
||
|
extern void init_emulation_mode(PTF, char *);
|
||
|
|
||
|
And the VT100 driver can be installed as follows:
|
||
|
|
||
|
/* initialize VT100 default parameters */
|
||
|
|
||
|
cursor.row = cursor.col = 1;
|
||
|
t->origin = t->addlf = t->keymode = RESET;
|
||
|
t->kblock = t->insert = t->autowrap = RESET;
|
||
|
t->keypad = NUMERIC;
|
||
|
|
||
|
clr_display(); /* clear LINKS display */
|
||
|
|
||
|
init_emulation_mode(process_VT100_input, (char *) t);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING SIX]
|
||
|
|
||
|
BEFORE
|
||
|
|
||
|
timer0:
|
||
|
.
|
||
|
.
|
||
|
.
|
||
|
reti
|
||
|
|
||
|
|
||
|
AFTER
|
||
|
|
||
|
timer0:
|
||
|
.
|
||
|
.
|
||
|
.
|
||
|
jnb in_emul_processor,process_emul ;if the emulation driver
|
||
|
reti ;is already running, then
|
||
|
;return from interrupt
|
||
|
process_emul: ;else call the driver
|
||
|
|
||
|
clr ea ;shut off interrupts while the
|
||
|
setb in_emul_processor ;recursion prevention semaphore
|
||
|
setb ea ;is set
|
||
|
|
||
|
push dph ;protect all registers that the C code driver
|
||
|
push dpl ;could possibly use (includes all of bank 3
|
||
|
push psw ;registers)
|
||
|
push acc
|
||
|
push b
|
||
|
push 18h
|
||
|
push 19h
|
||
|
push 1ah
|
||
|
push 1bh
|
||
|
push 1ch
|
||
|
push 1dh
|
||
|
push 1eh
|
||
|
push 1fh
|
||
|
|
||
|
mov dptr,#return_from_emul_processor ;put return from
|
||
|
push dpl ;emulation driver
|
||
|
push dph ;on stack
|
||
|
|
||
|
mov dptr,#emul_processor_address ;put emulation processor
|
||
|
movx a,@dptr ;driver address on stack
|
||
|
push acc
|
||
|
inc dptr
|
||
|
movx a,@dptr
|
||
|
push acc
|
||
|
|
||
|
mov dptr,#data_struct ;get the pointer to any
|
||
|
movx a,@dptr ;data to be passed to
|
||
|
mov r2,a ;the C language driver.
|
||
|
inc dptr ;pointer address is
|
||
|
movx a,@dptr ;stored in r2 and r3
|
||
|
mov r3,a
|
||
|
|
||
|
reti ;calls generic emulation driver
|
||
|
;(last address on program stack)
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING SEVEN]
|
||
|
|
||
|
return_from_emul_processor:
|
||
|
|
||
|
pop 1fh ; restore stack prior to call to VT100 driver
|
||
|
pop 1eh
|
||
|
pop 1dh
|
||
|
pop 1ch
|
||
|
pop 1bh
|
||
|
pop 1ah
|
||
|
pop 19h
|
||
|
pop 18h
|
||
|
pop b
|
||
|
pop acc
|
||
|
pop psw
|
||
|
pop dpl
|
||
|
pop dph
|
||
|
|
||
|
clr ea ;reset recursion prevention semaphore
|
||
|
clr in_emul_processor ;while interrupts are off
|
||
|
setb ea
|
||
|
.
|
||
|
.
|
||
|
ret ; gets address of next instruction to execute
|
||
|
; in the routine that had been interrupted by
|
||
|
; timer 0.
|
||
|
; address taken off the 8051 stack and the stack
|
||
|
; pointer is updated
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING EIGHT]
|
||
|
|
||
|
char *read_VT100_image(char row, char col, char *string,
|
||
|
char number_to_read)
|
||
|
{
|
||
|
short i;
|
||
|
char *ptr;
|
||
|
|
||
|
if(row <= VT100_MAX_ROWS && col <= VT100_MAX_COLS)
|
||
|
{
|
||
|
/* calculate number of characters to read on row */
|
||
|
if((number_to_read + col) > (VT100_MAX_COLS+1))
|
||
|
number_to_read = (VT100_MAX_COLS+1) - col;
|
||
|
|
||
|
/* get string start address from global screen array */
|
||
|
ptr = &screen[row - 1][col - 1];
|
||
|
|
||
|
/* transfer string to return string array */
|
||
|
for(i = 0; i < number_to_read; i++;)
|
||
|
string[i] = *ptr++;
|
||
|
str[i] = 0; /* terminate string */
|
||
|
}
|
||
|
return(string);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING NINE]
|
||
|
|
||
|
|
||
|
void get_cursor_position(TERMINALP t, char *row, char *col)
|
||
|
{
|
||
|
/* if cursor origin is relative, then calc row position
|
||
|
based on scrolling start position, else use global row
|
||
|
position */
|
||
|
if(t->origin == SET)*row = cursor.row - begin.scroll + 1;
|
||
|
else *row = cursor.row;
|
||
|
|
||
|
*col = cursor.col;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING TEN]
|
||
|
|
||
|
|
||
|
static char screen[24][80]; /* VT100 virtual screen image */
|
||
|
|
||
|
/* put a space character in each virtual image position */
|
||
|
|
||
|
static void clr_display()
|
||
|
{
|
||
|
short i,j;
|
||
|
|
||
|
for(j = 0;j < VT100_MAX_ROWS; j++)
|
||
|
for(i = 0;i < VT100_MAX_COLS; i++)
|
||
|
screen[j][i]=' ';
|
||
|
}
|
||
|
|
||
|
|
||
|
[LISTING ELEVEN]
|
||
|
|
||
|
static char screen[24][80]; /* VT100 virtual screen image */
|
||
|
char *current, *next, *last;
|
||
|
|
||
|
/* put a space character in each virtual image position */
|
||
|
|
||
|
static void clr_display()
|
||
|
{
|
||
|
current = &screen[0][0];
|
||
|
last = &screen[24 - 1][80 - 1];
|
||
|
|
||
|
do{
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
}while(current < last);
|
||
|
}
|
||
|
|
||
|
|
||
|
[LISTING TWELVE]
|
||
|
|
||
|
static char screen[24][80]; /* VT100 virtual screen image */
|
||
|
static short begin_scroll_row, end_scroll_row;
|
||
|
|
||
|
/* Scroll screen up one row. Last row is blank. */
|
||
|
|
||
|
static void scroll_up()
|
||
|
{
|
||
|
short i,j;
|
||
|
|
||
|
for(j = (begin_scroll_row-1; j<(end_scroll_row-1); i++)
|
||
|
for(i = 0;i < VT100_MAX_COLS; i++)
|
||
|
screen[j][i]=screen[j+1][i];
|
||
|
|
||
|
for(i = 0;i < VT100_MAX_COLS; screen[j][i] = ' ', i++);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING THIRTEEN]
|
||
|
|
||
|
static char screen[24][80]; /* VT100 virtual screen image */
|
||
|
static char *current, *next, *last;
|
||
|
static short begin_scroll_row, end_scroll_row;
|
||
|
|
||
|
/* Scroll screen up one row. Last row is blank. */
|
||
|
|
||
|
static void scroll_up()
|
||
|
{
|
||
|
current = &screen[begin_scroll_row - 1][0];
|
||
|
next = current + 80;
|
||
|
last = &screen[end_scroll_row - 1][0];
|
||
|
|
||
|
do{
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
*current++ = *next++;
|
||
|
}while(current < last);
|
||
|
|
||
|
last += 80;
|
||
|
|
||
|
do{
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
*current++ = ' ';
|
||
|
}while(current < last);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
[LISTING FOURTEEN]
|
||
|
|
||
|
#include "speedc.h"
|
||
|
#include "vt100.h"
|
||
|
#include "string.h"
|
||
|
|
||
|
void exception_handler(char code);
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
TERMINAL t; /* define VT100 setup parameters */
|
||
|
char string[21];
|
||
|
char display_string[23];
|
||
|
|
||
|
cursor.row = cursor.col = 1; /* globals defined in vt100.h */
|
||
|
t->origin = t->addlf = t->keymode = 0;
|
||
|
t->kblock = t->insert = t-> autowrap = 0;
|
||
|
t->keypad = NUMERIC;
|
||
|
|
||
|
init_emulation_mode(process_VT100_input, (char *)t); /* prototype in vt100.h */
|
||
|
|
||
|
/* initialize the first 3 lines on the LINKS terminal display by
|
||
|
using the special LINKS x function. This function allows the
|
||
|
user to define distinct display regions on the terminal. The
|
||
|
nomenclature is as follows:
|
||
|
D means define a display region which is touch sensitive.
|
||
|
1,2, or 3 means that the touch sensitive area defined will
|
||
|
generate transmit that particular ASCII character in the
|
||
|
key buffer when that touch sensitive area is pressed on
|
||
|
the LINKS screen. This is also referred to as its name.
|
||
|
A18; means the touch sensitive display area in row A (first row
|
||
|
on the LINKS), columns 1-8 (touch display areas have 8
|
||
|
distinct areas per row). The semicolon means the end of
|
||
|
the touch display definition, and what follows is the
|
||
|
message to be displayed in that display area.
|
||
|
B18; means row B (second row), columns 1-8.
|
||
|
C18; means row C (third row), columns 1-8.
|
||
|
*/
|
||
|
|
||
|
x("D1 A18; ");
|
||
|
x("D2 B18; ");
|
||
|
x("D3 C18; ");
|
||
|
|
||
|
open("98N1",1); /* open LINKS RS232 port with special LINKS
|
||
|
operating system function */
|
||
|
|
||
|
/* continuously update LINKS terminal display with the current VT100
|
||
|
virtual image found in rows 1-3, columns 1-20) using read_VT100_scr
|
||
|
whose prototype is in vt100.h.
|
||
|
*/
|
||
|
do{
|
||
|
read_VT100_scr(1, 1, string, 20); /* read row 1, cols 1-20 */
|
||
|
strcpy(display_string, "P1"); /* prefix string with special */
|
||
|
strcat(display_string, string); /* links P cmd (print to touch */
|
||
|
x(display_string); /* display area named '1') */
|
||
|
|
||
|
read_VT100_scr(2, 1, string, 20); /* read row 2, cols 1-20 */
|
||
|
strcpy(display_string, "P2"); /* prefix string with special */
|
||
|
strcat(display_string, string); /* links P cmd (print to touch */
|
||
|
x(display_string); /* display area named '2') */
|
||
|
|
||
|
read_VT100_scr(3, 1, string, 20); /* read row 3, cols 1-20 */
|
||
|
strcpy(display_string, "P3"); /* prefix string with special */
|
||
|
strcat(display_string, string); /* links P cmd (print to touch */
|
||
|
x(display_string); /* display area named '3') */
|
||
|
|
||
|
}while(-1);
|
||
|
}
|
||
|
|
||
|
/* The exception handler is needed for all LINKS applications to handle
|
||
|
special LINKS control functions.
|
||
|
*/
|
||
|
|
||
|
void exception_handler(char code)
|
||
|
{
|
||
|
if (code == 4)turn_off(); /* detects ON/OFF button pressed,
|
||
|
and turns LINKS off via LINKS turn_off */
|
||
|
}
|
||
|
|