delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/07/24/05:52:50

From: e-mail DOT address AT end DOT of DOT text (Mike Collins)
Newsgroups: comp.os.msdos.djgpp
Subject: One PC shadows another (Part 1)
Date: 22 Jul 1997 10:25:14 GMT
Organization: Storage Technology Limited
Lines: 138
Message-ID: <5r21qb$3bq@news.network.com>
NNTP-Posting-Host: 129.80.172.76
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

/*
Folks,

I am writing a database program in C, that will be used in a critical 
situation in real time. For disaster recovery, I wrote the code below, which
causes two PCs to run the same software in parallel, so that both PCs remain
identical at all times. I have incorporated it into my software and tested
it, and it appears to work fine. If anybody has the same requirement, they
may use it, hack it about, do whatever they want with it. There are no
guarantees with it, though, and I will not spend much time supporting it.

The effect is that a PC is configured as MASTER and another is configured as
SLAVE. All keyboard characters on the Master go into the keyboard buffer as
usual, where your fantastic program goes looking for its input. If it uses
getch(), the character is input to the program, but when it uses kb_getch(),
besides going to the program, the character is also sent to the serial port.
Note that in these routines, only serial port COM-1 is used. If you don't like
that, change the references to 0x3fa-0x3fe to something you like better.

Your fantastic program is also running on the Slave system, and just as on
any system, it goes looking in the keyboard buffer for its input. On the
Slave system, however, any character arriving at serial COM-1 port causes an
interrupt, and the interrupt routine puts the character into the keyboard
buffer, where your program finds it, just as if you had typed it there.

The routines in this source code come with a demonstration program which
will be compiled as long as TEST is defined. The demonstration program in
main() echoes any characters typed on the Master onto the screen of the
Slave, but this is not a simple echo. It is the result of the same program
running on both Master and Slave, and getting the same keyboard input. The
program detects characters and function keys. It does not detect other two-
character keys such as Arrow keys, although they are, in fact, sent to the
slave system.

Five routines are defined and described in kb.h (below). Read the
descriptions there. The database program for which I wrote these shadowing
routines, uses active help files, for which I use the kb_ungetch() and
kb_ungets(). For example, at a given point in the program, I look for input.
If the key pressed is A, B, C, D, F1 or F2, then the program performs a
corresponding action. If the key was F1, the action is to display a help menu.
The menu describes the action for each key other than F1, eg:

A   - Action 1
B   - Action 2
C   - Action 3
D   - Action 4
F2  - Action 5

If Escape is pressed, the menu goes away, and a goto (yes, that's right,
a GOTO!!) takes us back to the beginning of the keyboard input section,
and you can press the key of your choice. Instead of making the menu
go away, however, you can move the cursor down to the line of your choice
(let's say the description for the F2 key) and press Return to select it.
In that case, the help() routine which has just received a return from the
menu() routine, does a

kb_ungets("\0\x3c");

The "\0" tells kb_ungets that this is a function key (you could kb_ungets an
arrow key or delete key the same way). The "\x3c" is the second character
generated by the F2 key. Now when the goto is executed, the keyboard input
routine finds two characters in the keyboard buffer - a zero, saying that
the next character is the scancode of the key pressed, and a \x3c, exactly
the same as if it had been looking for keyboard input and we had pressed the
F2 key, so off it goes and does the F2 action.

Prerequisites are :
1) Your program must be in 32-bit protected mode C, compilable with DJGPP.
2) All keyboard input must be done via getch(). If you use scanf(), for
   example, you will have some work to do before you can use these routines.

How to use these routines :

1) #include kb.h // in your program.c file
2) In the initiallisation phase of your program, insert the line
SetupInt();
3) Throughout your program, change all your getch() and ungetch() statements
   to kb_getch() and kb_ungetch(). This can be done with a couple of #defines
4) Put kb.c into your project.
5) Compile & Link.
6) Copy your program.exe file to the slave system.
7) Connect a serial cable (pins 2, 3 and 7) between the two machines' COM-1.
8) Run the program on both machines.
9) Configure the Master by pressing (Alt-Ctl-M).
10) Configure the Slave by pressing (Alt-Ctl-S).
11) Type on the Master only. Anything typed on the Slave will go only to the
    Slave, so the two programs may get out of step.
12) A machine may be configured to Standalone by pressing Alt-Ctl-1.
    kb_getch() will then work the same as getch() would have.



*/
//=================FILE : KB.H====================//

#define MASTER 0x32        /* ScanCode for 'M' key */
#define SLAVE 0x1f         /* ScanCode for 'S' key */
#define STANDALONE 0x02    /* ScanCode for '1' key */
// set MASTER mode by pressing Alt-Ctl-M keys
// set SLAVE mode by pressing Alt-Ctl-S keys
// set STANDALONE by pressing Alt-Ctl-1 keys
// these settings assume that the scan codes equate with English keyboard.


int kb_hit(void); // tests to see if a key has been hit. More specifically,
                  // tests whether 'next' and 'last' keyboard-buffer pointers
                  // are equal

void kb_ungetch(char ch); // puts a char back into the keyboard buffer. This
                          // character appears to your program the same as
                          // one that you have entered from the keyboard.

char kb_getch(void); // gets a character (or function key) from the keyboard
                     // and sends it to your program the same as getch(), but
                     // if in MASTER mode, also sends it to serial port A, or
                     // in SLAVE mode, gets the character from the serial line
                     // and puts it into the keyboard buffer. The program
                     // running on the SLAVE system sees it as keybd input.

void disp_kb_bfr(int period); // displays the keyboard buffer without
                              // modifying anything.
                              // Shows Head & Tail as '>' & '<'.

void  kb_ungets(char *str);   // Puts characters into kb-bfr. Use like this :
     // 1) ungets("\0\x3c") - put the FUNC-1 character into the keybd buffer
     //   the leading zero specifies that this is a
     //   function/arrow/etc. character. The second char (0x3c) is the scancode.
     // 2) ungets("Hello World") - must be less than 16 characters
     // these characters are then ready to be read by your program exactly
     // the same as if they had been keyed in.


-- 
Don't just hit "reply" - my E-mail address is bogus
to avoid automatic browsers from sending junk mail.
Please use collim'at'anubis'dot'network'dot'com
Actually, even this doesn't stop all of them ...

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019