Language selection

Search

Patent 2060891 Summary

Third-party information liability

Some of the information on this Web page has been provided by external sources. The Government of Canada is not responsible for the accuracy, reliability or currency of the information supplied by external sources. Users wishing to rely upon this information should consult directly with the source of the information. Content provided by external sources is not subject to official languages, privacy and accessibility requirements.

Claims and Abstract availability

Any discrepancies in the text and image of the Claims and Abstract are due to differing posting times. Text of the Claims and Abstract are posted:

  • At the time the application is open to public inspection;
  • At the time of issue of the patent (grant).
(12) Patent Application: (11) CA 2060891
(54) English Title: COMPUTER OPERATIONS RECORDER AND TRAINING SYSTEM
(54) French Title: SYSTEME D'ENREGISTREMENT D'OPERATIONS INFORMATIQUES
Status: Dead
Bibliographic Data
(51) International Patent Classification (IPC):
  • G06F 11/34 (2006.01)
  • G09B 9/00 (2006.01)
  • G09B 19/00 (2006.01)
(72) Inventors :
  • WILLIAMS, PAUL E. (United States of America)
  • MCCARTHY, KEVIN G. (United States of America)
  • CERCHIO, GERARD J. (United States of America)
  • ALVES, ROBERT A. (United States of America)
(73) Owners :
  • WILLIAMS, PAUL E. (Not Available)
  • MCCARTHY, KEVIN G. (Not Available)
  • CERCHIO, GERARD J. (Not Available)
  • ALVES, ROBERT A. (Not Available)
  • TDS HEALTHCARE SYSTEMS CORPORATION (United States of America)
(71) Applicants :
(74) Agent: GOWLING LAFLEUR HENDERSON LLP
(74) Associate agent:
(45) Issued:
(86) PCT Filing Date: 1990-07-03
(87) Open to Public Inspection: 1991-01-04
Availability of licence: N/A
(25) Language of filing: English

Patent Cooperation Treaty (PCT): Yes
(86) PCT Filing Number: PCT/US1990/003878
(87) International Publication Number: WO1991/000575
(85) National Entry: 1991-12-18

(30) Application Priority Data:
Application No. Country/Territory Date
374,933 United States of America 1989-07-03

Abstracts

English Abstract

2060891 9100575 PCTABS00003
A method for detecting and recording signals from an input device
operatively connected to a digital computer and output from a
target program accessible by the computer, the method comprising
the steps of: a) loading recorder means into ROM of the computer;
b) accessing a format table file with the recorder to get data
representing predefined recording characteristics of the target
program and configure the recorder to the target program; c)
monitoring and interceding in the control of the operations of the
computer with the recorder; d) accessing the target program with the
digital computer; e) recording to a datafile signals from the input
device, the signals representing input to the target program,
and a sequence of screens produced by the target program.


Claims

Note: Claims are shown in the official language in which they were submitted.


WO 91/00575 PCT/US90/03878

- 288 -

1. A method for detecting and recording
signals from an input device operatively connected to a
digital computer and output from a target program
accessible by the computer, the method comprising the
steps of:
a) loading recorder means into the computer's
memory;
b) accessing a format table file with the
recorder to get data representing predefined recording
characteristics of the target program and configure the
recorder to the target program;
c) monitoring and interceding in the control
of the operations of the computer with the recorder
d) accessing the target program with the
digital computer;
e) recording to a datafile signals from the
input device, the signals representing input to the target
program, and a sequence of screens produced by the target
program.

2. The method of claim 1, wherein the step of
recording is carried out by a recorder not integral with a
means for playing back the datafile.

WO 91/00575 PCT/US90/03878


- 289 -
3. The method of claim 1, wherein the step of
recording is carried out by a recording emulator.

4. The method of claim 2, wherein the step of
recording is carried out by a recording emulator.

5. The method of claim 1, wherein the step of
recording is carried out by an emulator linked to a
recorder by an application programming interface.

6. The method of claim 1, wherein the step of
recording is carried out with a generic recorder.

7. The method of claim 1, wherein the step of
recording is carried out with a generic recorder having a
terminate-stay-resident portion.

8. The method of claim 1, wherein the step of
recording is carried out optionally by at least two of the
group consisting of (a recording emulator, a generic
recorder, an emulator linked to a recorder by an
application programming interface).

9. The method of claim 1, wherein the step of
recording is carried out optionally by any of the group
consisting of (a recording emulator, a generic recorder,

WO 91/00575 PCT/US90/03878


- 290 -
an emulator linked to a recorder by an application
programming interface).

10. The method of claim 4 further comprising
the step of:
a) recording in the datafile time from a
clock chip in the digital computer.

11. The method as in one of claims 5-7,
wherein the step of accessing the format table file is
carried out with a configurable format table file.

12. The method as in one of claims 5-7,
wherein the step of accessing the format table file is
carried out with a configurable format table file
configurable as to sample rate, record hold off, function
hold off, start record, stop record, record screen, type
in position, no keyboard in ROM, and auto exit code.


12. The method of claim 6, wherein the step of
recording is carried out with hooks or calls into
operating system interrupts.

13. The method of claim 12, wherein the step
of recording is carried out by outputting the datafile
subsequent to formatting and compressing the data.

WO 91/00575 PCT/US90/03878

- 291 -

14. The method of claim 12, wherein the step
of recording includes a configure state having the
following steps: a) initializing internal
data structures from the function table file in FTF 172;
b) setting key interpretation tables; and
c) arming a start and stop record key sequence.

15. The method of claim 12, wherein the step
of recording includes a target program state in which the
target program runs in a regular DOS environment, except
during the keyboard interrupts and the hardware clock
interrupts.

16. The method of claim 12, wherein the step
of recording includes a target program state that, during
a keyboard interrupt, switches from the target program
state to the keyboard state so that the following actions
that may optionally be performed include:
transferring control to the generic recorder's
keyboard interrupt routine so that the following actions
may optionally be performed: (1) nothing, the recorder is
not activated; (2) recognize the activation key sequence;
(3) store away the character generated from the keyboard;
and (4) post an I/O cycle for the clock interrupt.


WO 91/00575 PCT/US90/03878
- 292 -
17. The method of claim 12, wherein the step
of recording includes a target program state that, during
a clock interrupt, switches from the target program state
to the clock state so that the actions that may optionally
be performed include: (1) nothing, the recorder is not
active; (2) compare the screen to its previous state;
(3) store the present screen; and (4) perform a disk I/O.

18. The method of claim 12, wherein the step
of accessing with a generic recorder a format table file
includes:
a) reading data from a specified format table
file from a disk accessible by a terminate-stay resident
portion of the generic recorder, the format table file
including a machine-specific, key definition table; and
b) compiling the data in the format table file
and inserting the data into memory of a resident portion
of the generic recorder.

19. The method of claim 12, wherein the step
of recording includes:
using the keyboard interrupts and the clock
hardware interrupts to trigger a comparison of a present
and a previous screens to determine if the generic
recorder need take any action.

WO 91/00575 PCT/US90/03878
- 293 -


20. The method of claim 12, wherein the step
of recording includes;
accessing, via the generic recorder, a master table
for interpreting keystrokes from a host computer's BIOS;
interpreting keystrokes by the BIOS maintained
within a separate ring buffer within the generic recorder;

accessing machine recognition code to identify a
host machine type and a host keyboard type for direct key
number decoding for turn on and turn off key sequences.



21. The method of claim 12, wherein the step
of recording is carried out with;
a generic recorder having the following: (1) a
monitored interrupt; (2) a screen multiplex interrupt;
(3) a clock interrupt; and (4) a keyboard interrupt.



22. The method of claim 10, wherein the step
of monitoring and interceding in the control of the
operations of the computer includes:
replacing, via the recorder generic recorder
terminate-stay-resident portion, at least some of normal
interrupts so that whenever the computer's operating
system calls the normal interrupts, the resident portion
will have an opportunity to examine the normal interrupts

WO 91/00575 PCT/US90/03878

- 294 -
before the normal interrupts reach the computer's
operating system.



23. The method of claim 12, wherein the step
of monitoring and interceding in the control of the
operations of the computer includes:
taking control of the keyboard and clock
interrupts.



24. The method of claim 4, wherein the step of
recording includes:
receiving the signals in the recording emulator
but not acting upon the signals without the recorder first
having evaluated the signals.



25. The method of claim 4, wherein the step of
recording includes:

controlling the recording emulator with hooks
or traps.

26. The method of claim 4, wherein the step of
recording is carried out with the emulating being
subservient to recording.

WO 91/00575 PCT/US90/03878

- 295 -
27. The method of claim 5, wherein the step of
recording is carried out with a 3270 emulator.

28. The method of claim 5, wherein the step of
recording is carried out with CICS protocol.

29. The method of claim 21, wherein the
recorder takes over at least some of the interrupts.

30. The method as in one of claims 1-29,
wherein the step of recording is carried out while the
computer is linked to a host.

31. The method as in one of claims 1-30,
further comprising the steps of :
with a CBT system accessible by said computer,
reading said datafile and displaying the sequence of
screens and the signals on a monitor operatively connected
to the digital computer.

32. The method of claim 31, wherein the steps
of reading and displaying further comprise the step of:
routing the screens and the signals through
playback means.

WO 91/00575 PCT/US90/03878
- 296 -
33. The method of claim 32, wherein the step
of routing includes:
routing the screens and the signals through at
least one of the playback means selected from the group
consisting of (automatic playback means, manual playback
means, instructional playback means, and proficiency
playback means).

34. The method as in one of claims 31-33,
further comprising the step of:
routing the screens and the signals through
modify means.



35. The method of claim 34, wherein the step
of routing the screens and the signals through modify
means comprises:
routing the screens and the signals through
basic page means.

36. The method of claim 34-35, wherein the
step of routing the screens and the signals through modify
means comprises:
routing the screens and the signals through
typing error means.

WO 91/00575 PCT/US90/03878
- 297 -
37. The method of claim 34-36, wherein the
step of routing the screens and the signals through modify
means comprises:
routing the screens and the signals through
selection error means.

38. The method of-claim 34-37, wherein the
step of routing the screens and the signals through modify
means comprises:
routing the screens and the signals through
color/ASCII means.

39. The method of claim 34-38, wherein the
step of routing the screens and the signals through modify
means comprises:
routing the screens and the signals
through screen utility means.

40. The method of claim 36, wherein the step
of routing further comprises;
routing the screens and the signals through
student diskette means.


41. The method of claim 33, wherein the
routing the screens and the signals through student
diskette means comprises:

WO 91/00575 PCT/US90/03878

- 298 -
routing the screens and signals through student
registration means, course directory means, and directory
update means.
42. An apparatus for detecting and recording
signals from an input device operatively connected to a
digital computer and output from a target program
accessible by the computer, the apparatus comprising the
steps of:
a) a recorder in the computer's memory;
b) a format table file accessable by the
recorder to get data representing predefined recording
characteristics of the target program and to configure the
recorder to the target program; and
c) wherein the recorder monitors and
intercedes in the control of the operations of the
computer while the computer accesses the target program to
form a datafile of signals from the input device, the
signals representing input to the target program, and a
sequence of screens produced by the target program.


43. The apparatus of claim 42, wherein the
recorder is not integral with a means for playing back the
datafile.

44. The apparatus of claim 42, wherein the
recorder is a recording emulator.

WO 91/00575 PCT/US90/03878
- 299 -

45. The apparatus of claim 43, wherein the
recorder is a recording emulator.


Description

Note: Descriptions are shown in the official language in which they were submitted.


~O91/0057!i 1 2a~)89Lpcrius9o/o3878
rO~FUT~R ~P~A~IONS RECORDER AND TRAINING SYSTEM
I. BACKGROUND OF THE INVENTION
A. Technical Flel~

The present invention relates to a computer
system wherein one computer program, or a cluster of
computer programs, is used to make a recording of another
computer program in operation. More particularly, the
present invention forms a computer-readable file of
records of inputs to, and outputs from, the other computer
program. The file may then be edited and manipulated to
produce a computer-assisted educational exercise,
including a simulation of the second computer program in
operation.

B. Background Art
It is advantageous to teach computer skills by
having a student experience "real-life" situations.
However, it is often preferable to provide the student
with certain computer skills before allowing them to
access a computer program, particularly where incorrect
student input may lead to untenable results or where the
access time is expensive. Because it is also expensive to
provide such computer skills to a large number of
students,~students have been provided with computer-
assisted instruction, and student testing, along with a
simulation of a "live" computer program. The closer the
simulated experience is to the real use of the computer,
the easier it is for the students to transfer their
learning to actual computer operations.
In order to make the simulation of the computer
program targeted for learning ("target program"), one
approach has been to have computer programmers write a
computer program to simulate the target program. Instruc-
tional information and student testing capabilities may be
added to the simulation. However, writing one computer
program to realistically simulate another computer program
is often difficult and time consuming, and is also likely
to be very expensive.




. . .


` '. ' . . :. .

WO91/~05~ 2 - PCT/US90/03878


U.S. patents 4,637,797 and 4,701,130
(collectively, "the WHITNEY patents") disclose a software
training system including a computer, a cassette tape
player system, and software for running the computer.
This software includes the target program which the
student is learning to use and courseware which defines a
multiplicity of events which correspond to different
-portions of a predefined training lesson.
The tape player system is attached by an
interface to one of the computer's input/output ports.
The interface allows the computer to turn the tape player
on and off, and also transmits keystroke data from the
left track of a stereo cassette tape player, to the
computer. Oral instructions or other sounds recorded on
the right track of the stereo cassette are played over a
speaker. The training system works by alternately turning
on the tape to give the student oral instructions and to
get keystroke data from the tape, and then turning off the
tape player while the student enters keystrokes.
The keystrokes entered by the student are
compared with a filter specified by the currently active
event in the courseware. If a correct entry is made, the
tape player is turned back on and the lesson continues.
Certain predefined keystrokes from the tape player cause a
new event from the courseware to be selected and for the
tape player to be turned off. Furthermore, if the student
fails to make the correct keystrokes within a preselected
time period, the training system enters the correct answer
for him and proceeds with the next portion of the training
session.
The WHITNEY patents appear to use a co-resident
program that records the user inputs, which are later fed
back to the target program during the execution of the
tutorial to obtain screen outputs. While this approach
may be acceptable for limiting incorrect student input, it
requires accessing the target program each time that a
student is to be trained. Thus, the WHITNEY patents do
not address the problem of expensive access time.


,



; ~- :
:: . .,,: . . .

WO91/00575 2 ~ ~ 0 8 9 ~ PCT/U590/03878


U.S. Patent No. 4,662,013 ("CERCHIO," one of the
inventors herein) discloses an interactive training/expert
computer system that includes a computer subsystem for
executing computer programs. A keyboard is used for
entering data into the system, and a CRT displays the
results of executing a computer program in the computer
subsystem. A preselected computer program is resident in
the computer subsystem. A tutor module interrupts the
flow of.data from the keyboard, interpreting, and
manipulating the input data, selectively generating
messages in response to the input data, and selectively
allowing a subset of the input data to be processed by the
preselected computer program. The interpreting,
manipulating, generating, and allowing functions are
dynamically determined in accordance with predefined
criteria dependent on the contextual circumstances in the
running of the preselected computer program.
Although the CERCHIO invention involves an
interactive software training system in which a co-
resident "courseware module" serves as a tutorial co-
program, the patent is not directed at how to make the
courseware module, particularly a course module that
functions without accessing the target program for each
education exercise.

II. DISCLOSURE OF THE INVENITON
SUMMARY OF ~HE INVENTION
It is an object of the present -invention to
provide a system and a method to produce a recording of
the use of a computer program.
It is another object of the present invention to
provide a system and a method for producing a recording of
the use of a computer program operating on a local or a
remote host computer.
It is another object of the present invention to
provide a system and a method for using the recording to
simulate the use of the computer program in computer-based
training.


.. . , ~ . ~

'- ` ': ' ~., ' '' -~;-, , :,' ' ~,
" :'.: ` ., : .' ' ,: . . ., : " ' '

- ' ;' ' . '`'.,"' .' ~ ,.,.'~ ':', " ,' ',

W091!00575 ^ ;::~' PCTtUS90/03878
2 ~ ~ a ~

It is another object of the present invention to
provide a system and a method for using the recording to
simulate the use of the computer program.
It is yet another object of the present
invention to provide a system and a method for editing and
modifying the recording to produce a computer-based
training system.
It is a further object of the present invention
to provide a system and a method for using the recording
to test student learning with regard to use of the
computer program.
Other objects and advantages of the present
invention will become apparent from the following summary,
drawings, and detailed description of the invention and
its embodiments.
The present invention is designed to capture
and/or create information and format it into a computer-
based training exercise. In an automatic recorder of
digital computer operations driven by a first program and
user input, the recorder includes: a first digital
computer; a memory device connected to the computer; and
means for automatically recording in the memory the
operations and the input of the first program. The
recorder may further include: a second digital computer
connected to the first digital computer for hosting the
first program and receiving the input via the first
computer. Other features of the present invention are
detailed below.
Due to the complexity of the invention and the
corresponding amount of information needed to describe it,
the following outline is provided:

I. BACKGROUND OF THE INVENTION
A. Field of Invention
8. Description of the Related Art
II. SUMMARY OF THE INVENTION
III. BRIEF DESCRIPTION OF THE DRAWINGS
IV. DETAILED DESCRIPTION OF THE INVENTION AND A FIRST




: ~

W091/00575 PCT/US90io3878
- 2 ~

PREFERRED EMBODIMENT
A. General Features
1. CBT Exercise System Overview
a) Playback
b) Students
c) Help
d) Modify
e) Single Screen Utility
f) Miscellaneous Functions
B. Recording Emulator 8a
1. Emulator Flow Charts
C. CBT Generic Recorder 8b
1. Sampling Control
2. Recording Algorithms
3. Data Management
4. File Management
5. Configuration
6. Generic Recorder Figures
7. CBT State Program Structure
D. Menu Structure
E. QSCRs
F. Playback
1. Playback with Control Loop
2. Playback Flow Charts
a) Automatic Playback (Page 1 F2)
b) Manual Playback (Page 1 - Fl)
c) Instructional Playback
d) Proficiency Playback
3. Print Exercise
4. Modify
a) Options Menu
b) Modifying Screens
c) Selection Error
d) Typing Mode
e) Color/ASCII
f) LPW
G. Screen Utility (Page 1 - F7)
H. Student

WO91/00575 ,` PCT/US90/03878
2~68~ 9~ 6 -

1. Student Start-Up Flowchart
2. Course Directory
3. Critique
4. Help
I. Search Utility
J. File Functions
1. Copy Exercise to Drive x (Page la - Fl-
F4)
2. Delete Exercise (Page la - F6)
3. Rename Exercise (Page la - F5)
4. Append (Page la - F7)
5. Replace Pathway (Page la - F8)
K. File Structures
1. FTF File
2. Exercise File
3. Exercise Directory
4. Defaults (Page 1 - F10)
5. Other Files
L. Management Interface
M. Global Variables Header File (CBT V)
N. Generic Recorder Code
V. SECOND PREFERRED EMBODIMENT
Non-Linear Impacts
Exercise File Layout
New Features
Playback
Print
Modify
Option Menu Mode
Screen Information
Cursor Information
Screen Utility
3270 Recorder
VI. CLAIMS

III. BRIEF DESCRIPTION OF THE DRAWINGS




. :, . .;: :

W091~00575 --, PCT/US90/03878
- 7 - ~
2~8`~ ~ .
FIG~ 1 is a block diagram of the present
invention.
FIG~ 2 is a block diagram of the present
invention that provides further detail of elements of FIGo
1.
FIG~ 3 is a block diagram that provides further
,detail of recording emulator 8a of FIG~ 1~
FIG~ 4 is a block diagram that provides further
detail of the record screen step 86 of FIG~ 3~
FIG~ 5 is a block diagram that provides further
detail to the process key step 92 of FIG~ 3~
FIG~ 6 is a block diagram of the open file step
96 of FIG~ 3~
FIG~ 7 is a state diagram of the generic
recorder 8b of FIG~ 1~
FIG~ 8 is a block diagram of the recorder data
flow and memory organization of the generic recorder 8b of
FIG~ 1~
FIG~ 9 is a block diagram of the resident
portion of generic recorder 8b of FIG~ 1 and interruptsO
FIG~ 10 is a block diagram of the monitored
interrupt 222 of FIG~ 9~
FIG~ 11 is a block diagram of the multiplex
interrupt 224 of FIG~ 9~
FIG~ 12 is a block diagram of the clock
interrupt 226 of FIG~ 9~
FIG~ 13 is a block diagram of the process
keyboard 258 of FIG~ 12.
FIG~ 14 is a block diagram of the record key 280 of FIG~
13.
FIG~ 15 is a block diagram of the C clock code
260 of FIG~ 12.
FIG~ 16 is a block diagram of the process flags
302 of FIG~ 15.
IG~ 17 is a block diagram of the screen differs
312 of FIG~ 15~
FIG~ 18 is a block diagram of the tmp=cmp screen
376 of FIG~ 17.



.- :: :: - : .... :: . . -


.. .. : . ~. ~
- -. , - . ,., ~ :, :

W091/OOS75 . PCT/US90/03878! .
$~ ~ :
iFIG. l9 is a block diagram of tmp in ignore
region 382 of FIG. 17.
FIG. 20 is a block diagram of the record screen
334 of FIG. 15.
FIG. 21 is a block diagram of the keyboard
interrupt 228 of FIG. 9.
FIG. 22 is a block diagram of the playback 22 of
FIG. 2.
FIG. 23 is a block diagram of the process
playback record step 522 of FIG. 22.
FIG. 24 is a block diagram of the automatic
playback step 24 of FIG. 23.
FIG. 25 is a block diagram of the manual
playback step 26 of FIG. 23.
FIG. 26 is a block diagram of the instructional
playback step 28 of FIG. 23.
FIG. 27 is a block diagram of the proficiency
playback step 30 of FIG. 23.
FIG. 28 is a block diagram of the print step 42
of FIG. 23.
FIG. 29 is a block diagram of the overall
structure of modify 44 of FIG. 23.
FIG. 30 is a block diagram of the options menu
mode 52 of FIG. 29.
FIG. 31 is a block diagram of the selection
error mode 48 of FIG. 29.
- FIG. 32 is a block diagram of the typing error
mode 50 of FIG. 29.
FIG. 33 is a block diagram of the color/ASCII
mode 54 of FIG. 29.
FIG. 34 is a block diagram of the LPW modify
mode 58 of FIG. 29.
IG. 35 is a block diagram of the single screen
utility 56 of FIG. 2.
FIG. 36 is a block diagram of the process option
1000 of single screen utility 56 of FIG. 2.
FIG. 37 is a block diagram of the student
diskette 32 of FIG. 2.



., ~ .: . .: :
. - - . ..: -, :



:: . .: . .-

WO91/00575 PCT/US90/03878
-9- 2~a~

FIG. 38 is a block diagram of the course
directory step 36 of the student directory shown in FIG.
37.
FIG. 39 is a block diagram of the search
function 68 of FIG. 2.
FIG. 40 is a block diagram of the copy function
60 of FIG. 2.
FIG. 41 is a block diagram of the delete
function 62 of FIG. 2.
FIG. 42 is a block diagram of the rename
function 64 of FIG. 2.
FIG. 43 is a block diagram of the append file
function 66 of FIG. 2.
FIG. 1' is a block diagram of of the present
15 invention.
FIG. 2' is a block diagram of Data Files 10a'.
FIG. 22' is a block diagram of Playback 22'o
FIG. 28' is a block diagram of Print 45.
FIG. 29' is a block diagram of modify 44.
FIG. 30A is a block diagram of Option Menu Mode
52.
FIG. 35' is a block diagram of Screen Utility
56.
FIG. 44 is a block diagram of Screen
Information.
FIG. 45 is a block diagram of Cursor
Information.
FIG. 46 is a block diagram of Initialize
Recorder 2000.
30FIG.-47 is a block diagram of Initialize
Recorder 2000.
FIG. 48 is a block diagram of Install KB -
Interrupt 2002.
FIG. 49 is a block diagram of Monitor Keyboard
Interrupt 2004.
FIG. 50 is a block diagram of Process Screen
2006.




:, ~: .: ~ , , ` :
-

, . : .. . ., ~ ~
.

WO91!0057S PCT/US90/03878


FIG. 51 is a block diagram of Reset Interrupts2008.
FIG. 52 is a block diagram of Process Duplicate
Single Filenames 2010.
FIG. 53 is a block diagram of Parse Key TableO
FIG. 54 is a block diagram of Read Key Table.
FIG. 55 is a block diagram of Keyboard
Interrupt.
FIG. 56 is a block diagram of Process Key.
FIG. 57 is a block diagram of Screen Arrived.
FIG. 58 is a block diagram of Process
Displayable Key.
FIG. 59 is a block diagram of Process Function
- Key.
FIG. 60 is a block diagram of Autoexit Screen
Record.
FIG. 61 is a block diagram of Write to FileO
FIG. 62 is a block diagram of Process Temporary
Write.
FIG. 63 is a block diagram of Process final
Write.

IV. BEST MODE FOR CARRYING OUT THE INVENTION -
DETAILED DESCRIPTION OF THE INVENTION AND A FIRST
PREFERRED EMBODIMENT
The present invention involves one or more
computer programs in a digital system adapted to record
the input to and output from a target computer program.
There are 19 C source code modules, though herein, the one
or more computer programs may be referenced in the
singular as "program, "code," or "logic." One of the
modules is a large assembly language module called
cbt.asm, and other, smaller assembly modules include
vidlib.asm, vidlib2.asm, int24.asm, model.asm,
pdepvdad.asm, pdephdad.asm, and pr40sub.asm. There is a
header file, cbt.h, and a variables file, cbt.v, also
included in the modules. The recording, authoring, and
exercise playback functions, when compiled and linked,

WO~l/00575 PCT/US90/0387


become the program titled CBTP.EXE. The program is
written using Microsoft C version 5.1 and linked with the
medium memory module using only the standard Microsoft
library.
The programs may be run on a personal computer,
such as a PC or a PS2 (available from International
Business Machines Corporation ("IBM")), or another
compatible computer. The personal computer should have
640K memory, a keyboard, a monitor or CRT -- preferably
adapted for color display, and, if desired, a pointer
device such as a mouse or a light pen. Herein, the term
"input device" is used to encompass such input devices, as
a keyboard, mouse, light pen, etc. that produce electrical
signals representing, for example, keystrokes as input to
the target program 4. The personal computer may be used
alone to operate both the program of this present
invention and the computer program targeted for recordingO
Alternatively, the personal computer operated by the
present invention can be linked (by modem or cable and
appropriate emulator software) to a host computer, such as
an IBM 4300 series mainframe computer having the second
program operating thereon. - i~-
As an overview of the present invention, a
person experienced with the target program logs onto the
personal computer. The person then uses one of two
alternative approaches to record the target program. The
first approach is via the use of a recording emulator
which, by inserting calls to other routines of the present
invention described hereinafter, a terminal emulator may
be modified to allow it to record its use in a format that
is useful for simulation/record-processing software called
the "CBT." By using such an adapted emulator to access a
mainframe host application, the experienced user may
record the use thereof. The resulting recording may then
be replayed as a simulation or modified as described below
to turn the recording into a tutorial exercise. While
connected to a host via the recording emulator, the user
may at any time start or stop recording with the present




. . ;:, ~:

WO91/0~575 ~ 12 - PCT/US90/03878


invention. Although a recording emulator is an effective
way to produce simulations and recordings which can be
modified into student tutorials, because the recording
emulator essentially records its own use, it is limited to
recording those host transactions that this emulator
supports. Because it may be desired to record target
applications other than the emulation of a host terminal
session, this invention also includes a second approach to
recording the target program called the "generic
recorder." Since the generic recorder operates outside of
its target application, the target need not be modified to
be recorded.
The generic recorder is a terminate-stay-
residént ("TSR") program because, after it is loaded into
the computer, it will stay resident and act unobtrusively
in the background until it is called upon. This recorder
uses a Format Table File ("FTF") that describes the
recording characteristics of the program to be recorded.
The FTF file also handles any specialized keyboard
requirements of the target program. Once the generic
recorder is loaded, the user loads the proper FTF file
before starting to record. It is possible to have just
one FTF file that is always loaded automatically with the
recorder, or to create batch files that load the proper
FTF file when beginning the target application program.
Another FTF file may be loaded to record still another
program without having to reload the generic recorder.
Once the generic recorder and the appropriate
FTF file are loaded, the user calls up the target program
and can commence recording at any time or times. The
computer system does not record until a "start record hot
key" has been pressed. The user may optionally record
just a single screen or start a process of automatically
recording screens. If recording several screens, the
system will record until the user hits the "end record hot
key" to complete the recording and put the generic
recorder into its unobtrusive background state again.




.

. ~ , . - ~ .

. . . ~

WO91/00575 PCT/US90/03878
,.
; - 13 -
2~0~ .l ;;
The user can continue with other transactions
involving the target program, as described. Each time
that the start record hot key is hit, the user is asked to
enter a file name. Sequentially, by entering different
file names, the user can continue to make several
recordings without signing-off the target program.
The end result of the use of one of the above-
mentioned means for recording is at least one recording in
a-file of a computer that can then become available to the
CBT system for processing into a simulation and/or
tutorial for subsequent presentation to a student.
Note that the CBT is a computer program that is
an application program in itself. Thus, the CBT can use a
recording (i.e., a data file) made with either the
recording emulator or the generic recorder.
The user may then call up the recording and edit
it to produce a simulation in several formats. one format
adds educational information to guide a student through
the simulation. Another format involves essentially no
instruction, but tests the correctness of the student
interaction with the simulation.

A. General Features
FIG. 1 shows the general features of the present
invention. A personal computer 2 is running target
computer program 4 that is the subject of a future
training exercise. Program 4 may, for example, be an
application program, like the customized software that
operates a hospital, a word processing program, MS DOS, or
an emulator. Indeed, program 4 may be essentially any
program that is well-behaved in the DOS environment, i.e.,
any DOS program that does not improperly interfere with
the interrupt processing of the computer 2.
Optionally, computer 2 can be connected to a
host computer 6 by virtue of the contents of computer 2.
Computer 2 contains means for recording 8a and 8b, data
files 10, and CBT 12. Means for recording 8 includes
recording emulator 8a and a generic recorder 8b. Host 6




: . . . :., ~::. , -,

wo 91!00575; PCT/US90/03878
14 - ~

and computer 2 may be connected by means of the recording
emulator 8a. The line between the host 6 and target
program 4 is hyphenated to indicate that the data file 10
may optionally be produced by the recording emulator 8a
connected to host 6 and engaged in operations involving a
target program 4 that resides at host 6. Means for
recording 8 link to CBT 12 via at least one data file 10.
Computer 2 also contains at least one FTF file 14b, which
- links the CBT 12 to the configuration program 18 for
processing data received from the FTF 14b file.
Data file 10 may be comprised of a file of
records of computer screens produced during the operation
of program 4 and records of information input by the userO
Although this data could be stored in separate files, or
lS some other configuration, a file of records is preferred
for efficiently keeping track of the sequence of the
operations of program 4 with relatively more
straightforward logic than other alternatives.
Alternative configurations of the means for
recording 8 are also viable. For example, the recording
emulator 8a and CBT 12 could be integral as one program or
a linked cluster of programs, as is suggested by a dotted
line there between. In this alternative configuration,
the controlling functions may be located in a terminal
emulator that normally provides the link between the PC
computer and mainframe environments. For CBT purposes,
"hooks" may be placed in the emulator 8a to allow control
to be passed to the CBT 12 system~ In effect, emulator 8a
would be the main program with a control loop that allows
branching to CBT 12 code when characters are typed,
pointer device selections are made, or CBT-set interrupt
conditions are met. For the most part, a control loop
code handles all of the pointer device and keyboard input
activities in either this alternative configuration or in
the configuration detailed herein. With the hooks, C~T 12
would get "first shot" at the input keys. Only when the
PC computer 6 is actually connected to the mainframe would
the emulator 8a/CBT 12 have its own keystrokes and control

W091/00575 2 ~ ~ O ~ 9 1 S90/~3878
15 -

the operation. Such an emulator 8a/CBT 12 combination is
available from TDS Healthcare Systems Corporation in
Atlanta, Georgia -- U.S.A.
Although there are advantages and disadvantages
to this alternative, assuming that source code for an
emulator is publically available, it is not emphasized
herein so that others will not be limited to one emulator.
Further, it should be noted that an emulator similar to
recording emulator 8a, like most emulators, has a built in
FTF file 14a and initialization routine 16. While this is
efficient, it does not have the flexibility of the
configurable FTF file 14b of the generic recorder 8bo
., .
1. CBT Exercise System Overview
There are three different kinds of users
contemplated for the present invention: developers,
authors, and students. As used herein, "developer" refers
to a computer programmer who, for example, may be using
the system to create FTF files or to otherwise have access
to files or code segments that are not generally
accessible to other users. Developers have access to all
aspects of the present invention. The term "author"
refers to the user that, for example, records the target
program 4 and creates educational exercises. A "student"
refers to a user seeking to learn the target program 4,
and has access to CBT 12 essentially limited thereto.
Access to different parts of the system is
controlled by a file called CTR.PEW. The batch files that
run CBTP will transfer the proper CTRx file into CTR. PEW.
These files have the following designations: developers
have DEV; students have STU; and authors have a blank.
Developers can do anything, while authors and students are
restricted to exercise files and files with a TDS
extension. Authors can make a recording and do everything
necessary to create and customize exercises. Authors also
have the ability to delete files from the system, copy
files, etc.




, . .
: :: : : . .: . ,
,: , : ~ ,..... .
.: . . . :.
, , : '': ' : ~:: , :' .. :: , ',. :

WO91/00575 ~ ~ ~ PCT/U590/03878
16 ~

Students can only run exercises. They get a
student start-up screen, a registration screen, and then a
course directory from which they can select the exercises.
Alternatively, the present invention could be configured
to allow students to hotkey to the mainframe and practice
on it, after which they would be returned to the course
directory.
For the majority of the application, the actual,
real data appears on the screen. When modifing an
exercise, all of the screens will appear, including any
error messages, even if one selects to jump ahead to a
specific page or END to hurry along. The program writes
the screen from the existing file, then reads the screen
and stores that in the new file. Control files are mostly
"screens" that have been compressed and stored. The
screens are decompressed and read into the control
variables.
One major example of screen reading is the
concept of a QSCR ("Q-Screen"). Any screen that has those
four letters in the first four screen positions (row 0,
columns 0-3) is treated differently. The QSCR is followed
by a space and is then followed by a single letter which
describes various options for that screen. For example, a
QSCR N is visible only to the author and never in a
subsequently discussed playback mode, while a QSCR X
identifies an exercise statement. These options are
detailed later in this document.
Figure 2 outlines the main features of CBT 12.
a) Playback
Authors have access, via author menu 20, to
playback 22 which has four modes: automatic playback 24,
manual playback 26, instructional playback 28, and
proficiency playback 30. Automatic playback 24 reproduces
the recording of program 4 by automatically sequencing
through the recorded screens with predetermined timing,
which is adaptably changeable. The second mode of
playback 22 is the manual mode 26, which allows the user
to review the recording by stepping through it one screen


. . - . . , - - ,

WO91/00~75 PCTiUS9o/03878
~ - 17 - 2~89 ~

at a time. Manual mode 26 allows spending as much time as
needed at any particular point. This, for example, allows
students to completely grasp a lesson presented on a
--- screen of an exercise before moving to another screen.
When ready, the user gives the proper input keystroke and
the recording sequences to the next "frame" of data file
10. Instructional playback 28 provides a step-by-step
sequence of the QSCR instructional screens, along with the
compute~ sc~ee~s that simulate the program 4. It requires
a correct answer to advance and provides hints and error
messages. The final mode of playback 22 is proficiency
playback 30, which provides minimum educational guidance,
but tests students on the correctness of their handling of
the exercise with prompts and responses predetermined by
the author(s).
Student access to the CBT 12 is much more
limited than that of authors, but aspects of playback 22
may be made available to them. Students are provided with
a diskette 32 which they may use separately from the rest
of CBT 12. Students also get a special start-up screen,
and, when a student has finished his/her studies, the CBT
12 will return the computer 2 to the start-up screen to
wait for the next student to log on to do exercises.
- Authors are allowed full access so that they can
review their work and see their exercises in all forms.
Any exercise may then be saved as one which only allows
the student access to those of the four modes as may be
appropriate for the exercise at issue.

b) Students
The first step for the student is registration
34, which requires the student to input information that
can later be used to identify the student, including a
password. The set of data on each student, stored in
course directory 36, also allows an author to track the
progress of each student. Each student need only register
once but will have to reenter the registration step 34 to




:~
: :::: - .::: : . : . .. : :

WO9~ 18 - PCT/US90/0387


enter the password, in order to gain access to the course
directory 36 and the exercises therein.
The course directory 36 is a-directory that
includes a list of the different exercises available to
students. A course is a set of exercises. In the course
directory, students may alternatively choose to enter
critique 38, normally the last task accomplished after
completing the exercises. Critique 38 allows students to
provide feedback about their comp~ter-assisted instruction
and possibly other teaching as well. Critique 38 presents
a list of questions to, and receives responses from, the
student. The answers may be accessed by authors for use
in evaluating the course. A management system interface
40 keeps track of information on the individual students
and the different tutorials available to the individual
users.
Alternatively, in the course directory, students
may choose an exercise in a course. At this point, a
playback 22 mode selection must be made by the student
from the alternatives available to the student. The
student selects one of the four previously discussed modes
24, 26, 28, or 30 available in playback 22. Once the mode
has been selected, the exercise in a data file 10 is
accessed. After completing the exercise, the next step is
to update the directory 42. If the student has undertaken
a test in proficiency playback 30, part of update
directory 42 involves calculating and storing student test
score information. An exercise is flagged as completed
when the highest mode available to the student for the
particular exercise at issue has been completed. The
modes go from automatic 24 to manual 26 to instructional
28 to proficiency 30.

c) Help
Help system 44 can either be state driven or
based on name or number parameters. Herein, the help
system is state-driven. Thus, when the user hits the
"help" key, it calls a function that first determines




: . . . . .

WO9!/00575 `- PCT/US90/03878
- 19 2~

where the user was in CBT 12 (e.q., in student
registration 34, etc.) and then displays one or more
appropriate screens giving the user the helpful informa- -~
tion. If there is more than one help screen, the user can
5 go forward and backward through the help screens. When -
the user escapes from the help system 44, he or she is
returned to where the user was when the help key was hit.
Because this help system 44 is available throughout CBT
12, it is not illustrate-d in FIG. 2 as being connected by
a line to the CBT 12.

d) Modify
Playback 22 is linked to print 45, to facilitate
producing hard copy of the data file 10. This is in
addition to a subsequently discussed print page option.
Playback 22 also is linked to modify 46 which faciliates
changing the data file 10 to produce an exercise. Modify
44 is made up of a number of functions that allow the
author to make certain kinds of changes. The author can
make or change: a basic page 47 (e.g., a screen recorded
to data file 10); a selection error 48 (i.e., a selection
of a function key to change the basic page or screen, and
an associated message to be displayed in response to a
student input of the wrong function key); or a typing
error 50 (i.e., text to-change the typing expected on the
basic page or screen and a message for typing the wrong
text). Corresponding functions 42, 46, and 50,
respectively, enable these activities. Within these
functions, the author may toggle to options menu 52 to
choose from a number of different operations, including:
insert, delete, save, replace, list, print page, and go
forward. These operations allow manipulating the recorded
data. Note that not all of these options are always
available depending on what the user was doing before
coming to the options menu 52, as is more fully discussed
below.
Color/ASCII 54 is also accessable from functions
47, 48, and 50, and is essentially the screen-painting

WO91/00575 - PCT/US90/03878
20 -

part of the CBT 12 system. Color/ASCII 54 allows the
author to change the color at any character position on
the screen (if it is a color screen) and type any graphic
character. Note that these text-graphic characters are
S not all found on a keyboard. They could be entered from
the keyboard through the use of the "alt" key being
depressed while a number is entered. These options are
more easily accessed via a chart displayed in color/ASCII
54. Color/ASCII 54 (and options me~u 52) may also be
entered from a single screen utility 56, as is more fully
discussed below.
LPW 57 involves an "action key." An action key
causes the screen to change and the exercise to advance to
the next page. For example, when recording, the user may
have hit an enter key to advance in the target program 4.
Thus, the recording would show the screen change and that
an enter key was the key that prompted it. Likewise,
selecting an item at a row and column with a pointer
device might trigger the screen change, and the device hit
status, and row and column data are saved in the datafile
10 record. The "LPW" or light pen window is simply a way
to bring up the action key information on the screen to
allow the user to change it.
In sum, the functions of modify 46 allow the
author to take the recording of a sample run of target
program 4, recorded via data file 10, and transform this
record into an exercise. Modify 46 allows the user to add
in instructional comments and helpful hints on screens to
allow the subsequent student(s) to learn the functioning
of the target program 4. Modify 46 also allows the author
to change the function key(s) or text that produces a new
screen in the record, as well as to create error messages.
Further, modify 46 allows the author to rearrange and ~;
change the appearance of the screen to make an exercise
more palatable and understandable to the student.




,: . -; - ..

, -

WO91/00575 PCT/US90/03878
f'~`' .. . .
~; - 21 ~ 2~

e) Single Screen Utility
The single screen utility 56 is used to create
help screens and other special screens. Unlike modify 46,
the single screen utility 56 is not exercise driven,
though it can be used to make or change screens which can
later be incorporated into an exercise. In general, the
single screen utility 56 allows creating screens from
scratch or changing screens~sto-red as part of data file
10. As previously mentioned, the utility 56 also allows
access to color/ASCII 54 and options menu 52, and some
options therein. Utility 56 is useful for updating
control files, creating screen templates, creating single
screens, and performing certain editing functions.

f) Miscellaneous Functions
15 CBT 12 also has file functions 58 for
manipulating the data files 10. Copy 60 makes a copy of
any existing file 10 in whatever disk drive directory the
user specifies. Delete 62 deletes any existing file 10.
Rename 64 renames any existing file 10, and append 66
takes two files 10, and joins them together to form one
larger file. These functions process the data files as
files and do not access the records individually.
Search 68 is logically separate from the file
functions 58. Search 68 allows the user to search through
one or more files 10 for the occurrence of an input
string.
Defaults 70 allows the author to specify certain
default conditions for the operation of the CBT 12 system,
such as the printer identification, the automatic playback
24 wait time, and the disk drive where an exercise will be
found.




.., . ... . ~ .. :

;: : ~. ', . .. . . , ~ ; ; ; .

: .. : : ~: ,,: ,, . ~... .: '

WO91/OOS7~ ~ ~ PCTtUS90/03878
7~ - 22 -

B. Recording Emulator 8a
FIG. 3 is a more detailed flow chart of the
recording emulator 8a. The recording emulator 8a is a
standard terminal emulator. Recording emulator 8a is
adapted with hooks in it to allow access to the remainder
of CBT 12 if a flag is set for CBT 12 in the FTF
configuration file.
Recording emulator 8a uses control loop
returns. In the control loop that switches back and forth
from the CBT 12 program(s) and the recording emulator 8a
main loop, there is a need to be able to direct what
happens. CBT 12 has "states" which tell what to do when
events occur, such as when a key is hit and a function
called CBT_Character_Trap is called. Further, there is a
need to "interrupt" recording emulator 8a, to get it to
send control back to CBT 12 under other conditions. There
are two variables that provide this service, p_Reset and
p_Play_Int. Both are tested in the CBT_Low_Interrupt
function in CBTl.C, which is called everytime recording
emulator 8a reaches the end of the main loop and before it
restarts the loop. This provides a way to get control
back to the CBT 12.
The p Reset variable has six possible values.
One of the six is reserved. The value three means that
the user is a student and is used in the programs to
display the proper screens (students get a different
start-up screen, for example). The value five is set when
a subsequently discussed critique page being sought was
not found and returns back to the critique start. The
value two is essentially a "press any key" type and will
then return to the start-up screen values. If p_Reset is
11, it is in a timer situation signifying a waiting
condition. When the wait condition is met (e.q., when the
user finishes an exercise playback 22), the value of this
variable will become one.
Besides the tests in CBT_Low_Interupt, there is
a special reset handling routine of CBT_Character_Trap




:. . . . . ~.: ~ .,. . . ,. ; :
: ~ : , . -.

WO9l/00575 PCTtUS90/03878
~ 23 ~ 2~9~91

that handles the actual processing for the p_Reset values
of two, three, and five.
P_Play_Int, found mostly in CBT_Low_Interrupt,
is really a playback state holder having normal values
between 0 and 30 during the playback 22 routine. The
value four, essentially is the normal value for "go off to
playback 22 again," and this is also the value when the
user selects an exercise mode just before it brings in the
exercise. During playback 22, the values of two' three,
and five are found for timing waits or return locations
after a visit to recording emulator 8a for an action.
There is one other artificial situation when p Play_Int is
set to 88 during a process involving the subsequently
discussed registration page, which is handling its own
keystrokes, but then has to leave to get help 44 if
called. This flag is then used to handle location when
the registration page is called again after help 44 and
prevents the CBT 12 system from reloading or parsing
registration data.
P_Play_Int has a subset, p_Play_Int_Code which
is set in the playback 22 functions to more specifically
.
route the user to where he or she was. This is usually
effective when p_Play_Int has come in with a normal value
;~ of four. In addition, P_Int is used to take the value of
P_Play Int on entry into playback and holds that value for
processing while in playback, zeroing out p_Play_Int so
that it must be reset again while outside of playback to
refine the-effects of the action taken.

1. Emulator Flow Charts
In FIG. 3 the recording emulator 8a begins with
initialization step 72 which loads the FTF file 14b. If r
CBT 12 is to be supported, the user will set a flag to
indicate that CBT 12 is intended (hence active). Thus,
branch 74 tests whether the CBT 12 is active with respect
to recording emulator 8a. If the CBT 12 is not active,
the recording emulator 8a moves to exit point 76 to run as
a normal emulator without CBT 12. Emulators, by design,




: , - .. . : . .. ,.
. : ::: . - -: -. . ~-
. . . .::: .. .... . .
::, ,: . .. : : .

WO91/00575 ~ PCT/US90/03878
24 -

are intended to connect to a host and this is part of
their initialization 16 process. However, if the CBT 12
is active, the recording emulator 8a progresses to CBT 12
processing where a normal escape from the emulator 8a must
always be examined first in CBT 12 to see if CBT 12 is
finished. CBT 12 determines when the recording emulator
8a will be able to quit. Thus, from block 78 on, the
system is in the control loop where it is constantly
evaluating the state, as is more fully discussed below.
Generally, however, the control loop is concerned with
- whether it is recording or not, whether any keys or
pointer hits have been found, or whether any hot keys or
escape keys have been pressed. Thus, processing begins
through this loop starting at the evaluation at branch 78
which would not be true on first entry but which is always
the first test thereafter. A yes at branch 78 leads to
quit 80. Otherwise, the recording emulator 8a proceeds to
branch 82 where it sees if a new screen message has
arrived. If it has, the recording emulator 8a proceeds to
branch 84 to test if a record flag is set. If it is set,
the screen is recorded in step 86. If not, the screen is
ignored.- The emulator 8a loops back to escape flag 78
from record screen 86. The recording emulator 8a proceeds
from branch 84 or branch 82 to a point where the recording
emulator 8a tests whether a key was hit, at branch 88. If
it was, the recording emulator 8a proceeds to process key
step 92, and thereafter back to branch 78. At branch 90,
if no key was hit, the recording emulator 8a proceeds to
branch 94. If the user presses the hot key, a test at
branch 94 will send the recording emulator 8a to open a
data file 10 at step 96 and will start recording before
looping back to escape flag set 78. However, if the
answer coming out of branches 88 or 94 is no (i.e., if
there is no new screen and no key was hit), the recording
emulator 8a proceeds to branch 98 to determine whether
there is a pointer hit (i.e., was the mouse or light pen
clicked). If there is a pointer hit, the recording
emulator 8a proceeds to branch 100 where, if the record



. , ,, , . , :. .

.
;.~, , , . :

W091/00575 PCT/US90/03878
; - 25 ~ 2~ 91

flag is on, the recording emulator 8a proceeds to test
whether the hit and/or pointer location are valid at step
102. Thereafter, the recording emulator 8a loops back to
the escape flag setting query at 78. If the answer coming
out of branches 98 or 102 is no, then the recording
emulator 8a proceeds to a CBT option 104, which allows
exit from the recording emulator 8a. This option is to
allow the CBT 12 to get control of program 4 if needed,
for example, to keep the recording emulator 8b from
interrupting any CBT 12 processes, such as storing a file
or reading in multiple records.
FIG. 4 details the record screen step 86. Step
86 begins with an inquiry at branch 106 to determine
whether a typing buffer is open. If the typing buffer has
previously been opened, before recording the next screen,
it must be closed and written to a typing record in file
10, because the information in the buffer must belong to
the previous screen. Otherwise, the recording emulator 8a
proceeds to build a typing header in step 108. Because
every screen record has a header record associated
therewith, the recording emulator 8a proceeds to write the
typing record to the file at step 110. Next, the
recording emulator 8a proceeds to step 112 which closes
the typing buffer and joins the no fork from the typing
buffer open query of 106 at branch 114. Branch 114 tests
whether there is a function key in the typing buffer. If
there is, the recording emulator 8a proceeds to build
function key header bytes at step 116. If a function key
was hit to trigger the screen record, the header will be
constructed to store the identity of the key. Otherwise,
the recording emulator 8a builds unsolicited header bytes
at step 118, i.e., because where no key triggered the
screen that came, the header must say so. The recording
emulator 8a proceeds from either step 116 or step 118 to
step 120 to finish the header record. A function key or
an unsolicited flag is only part of the header. Thus, the
rest of the header is filled. Thereafter, the recording



. .. .

: ~ . .
.. , .. :. . -
.. .. ..
- .. - :. . : ;. . .:
,',, ' ' ,',' '~ ~ :
" ' ' . ' i , ` '
' . , ' ' ~,~: . .

WO91/00575 ~ PCT/US90/038~8
~6 .. . - 26 - ~

emulator 8a writes the file to memory at step 122 and
exits at 124 back to the diagram set forth in FIG. 3.
The process key step 92 of FIG. 3 that evaluates
the keyboard character input is detailed in FIG. 5.
Process key step 92 begins by checking whether an escape
key was selected at branch 126. If the escape key was
depressed, the recording emulator 8a proceeds to step 128
to set an escape flag. Thus, upon exiting at 130 to
FIG. 3, the escape flag set test 78 will trigger quitting
the recording emulator 8a. At branch 126, if the key
depressed was not the escape key, then the recording
emulator 8a proceeds to branch 132 to check whether the
key depressed was an end of record key. If it was, the
recording emulator 8a proceeds to end recording step 134,
which writes a "last record" flag and closes the file.
Next, the recording emulator 8a proceeds to step 136,
which sets record flag off (i.e., the hot key used to
record is set to "off" so that the system will not record
more data). The recording emulator 8a then proceeds to
return 130. If the key being evaluated in branch 132 is
not the end record key, the recording emulator 8a proceeds
to branch 138 to check whether it is a function key. At
this branch, if it is a function key, the recording
emulator 8a determines whether the typing buffer is open
at branch 140. If the typing buffer is open, then a
typing header is constructed at step 142. The header is
written to the data file 10 at step 144 and the typing
buffer is closed at step 146 before return 130. If the
typing buffer is not open at 140, the function key is
stored in a buffer at step 144 before return 130. In FIG.
4, the function key in the buffer will be recognized at
branch 114 and processed as previously discussed. In FIG.
5, at branch 138, if the key is not a function key, the
recording emulator 8a proceeds to branch 150 and accepts
the input key if it is a letter or number. In either
case, the recording emulator 8a proceeds to branch 152 to
check if the typing buffer is open. If the buffer is not
open, step 154 opens the buffer. Once the typing buffer


.. ...:, ..

.
, ~

WO91/00575 ~PCTtUS90/03878
~ - 27 ~ 2~39i
is open, step 154 places the letter or number key in the
buffer at block 156 which then leads to return 130.
The alternative from type character branch 150
leads to step 158, an unknown key test 158. The recording
emulator 8a ignores the key found and returns at block
- 130.
To further understand the typing buffer,
consider that it is a temporary storage area. If the user
types "DOG", the computer is directed by the CBT 12 to
first put a "D" in the buffer and then leavs to await the
next user input. Next time that the user types, i.e., the
-"O", the computer is directed to return to the buffer and
amend the contents of the buffer to hold "DO". When the
user types "G", the same process happens, until the user
hits the enter key. The enter key triggers writing out
- -the contents of the buffer as a typing record to the data
file 10. Further, the enter key is the function key put
in the header. The typing buffer is then closed to await
the next typing.
FIG. 6 details the step open file 96 of FIG 3.
To open a file, the recording emulator 8a asks the user to
input-or find-a file name at step 160. The recording
emulator 8a then checks whether the file name already
exists at branch 162. If it exists, then the recording
emulator 8a asks whether the user wishes to overwrite the
existing file at branch 164. If the user does not want to
overwrite the file, then the recording emulator 8a asks
the user for a new file name at branch 164 and loops back
to step 160. If overwrite is desired at branch 164 or if
the file did not exist at branch 162, the recording
emulator 8a proceeds to open the file at step 166, and
sets the record flag on at step 168 and proceeds to return
170. An escape (not shown) allows exiting if the user
decides not to input a file name.

C. CBT Generic Recorder 8b
Before getting into the details of the generic
recorder figures, the concepts of sampling and recording




: - :. :: . . ::: ::

.. .: : :. ,., ;: . . : ;. : .
:.: . . : . . . . -
-~ : .-: :: ,::,. : . .: .
.. ..

WO91/00575 ~ 28 - PCTiUS9o/03878


algorithms and an overview of the how the recorder works
should be understood.
The generic recorder 8b in FIG. 1, is
conceptually divided into two separately executable sub-
parts. The first sub-part (i.e., program) is for doing
the actual recording of state changes. This sub-part
becomes resident at the time of execution and maintains a
watch on the computer states by intercepting several of
the hardware and software interrupts. The hardware
devices monitored are the system clock, keyboard, and
pointer device.
With regard to software interrupts, an interrupt
service routine ("ISR") has addresses or vectors that are
numbered and correspond to fundamental routines that
operate the computer. The software interrupts monitored
are: 1) ISR 5 Print Screen; 2) ISR 10 Video BIOS; 3) ISR
13 DASD BIOS; 4) ISR 23 Control break from the BIOS; 5)
ISR 28 DOS idle interrupt; 6) ISR 21 DOS command request;
7) ISR 2F DOS multiplex interrupt; and 8) ISR 24 DOS
critical error. All of these interrupts are monitored
continuously except the last one, ISR 24. This interrupt
is only intercepted during the recorder's-disk read/write
operations. At all other times this interrupt is set to
the recorded task's critical interrupt handler.
The second sub-part of the general recorder 8b
is the configuration manager 18. This sub-part is for
interpreting the FTF file 14 and producing data structures
within the resident recorder's memory space that control
the operations of the generic recorder 8b. Such things as
sampling algorithm selections for a sample rate, hold off
times, start and stop sequences, and function key
sequences may all be defined within the FTF file 14 to
later be translated by this sub-part for the generic
recorder 8b, as is subsequently discussed. This dual sub-
part configuration allows the recorder to be reconfiguredbetween programs for long, complex recording sessions. It
also allows for custom tailoring of the generic recorder
8b even to the specific data being recorded.




'.: , ~: : . ,
.

WO91/00575- -PCT!US-90/03878'
: - 29 -

1. Sampling Control
The generic recorder 8b is developed for
flexibility and configurability. These attributes allow
recording the operations of a large number of targét
programs 4. The design is optimized to allow the
recording of a minimum of target program 4 transition
states. These states are useless in education demon-
stration and would simply take up space in the memory of
the computer. These transition states would also require
additional time on the part of the author of an
educational exercise to edit out the superfluous
information. The number of transition states are limited
by control of: l)-a variable sample rate; 2) function key
recognition; 3) function key hold off periods; 4) function
key minimum and maximum settle times; 5) screen change
hold off times; and 6) ignore regions.
Variable sample rate allows the recorder to
adapt to each target program 4 by examining screen changes
at a rate optimal to the performance of the target
program 4. Applications programs with little screen
change and much computational time need only be sampled
once or twice a second. Other application programs with
dynamic, unsolicited screen changes need to be sampled
more frequently so that the author may be able to single
out these state changes and thoroughly discuss them in CBT
exercises. The sample rate in this recorder program may
be set to as many as 17-samples per second. This is the
sample rate of an MS DOS clock in the personal computer 2.
Given that there may be a faster source of interrupts on
the host machine 2, the sampling interrupt routine may be
coupled to the clock of host 6 to attain an even higher
sampling rate. Another aspect of the sampling rate is
that it may be modified by the recording algorithm.

2. Recording Algorithms
The generic recorder 8b uses several forms of
recording to perform its task. These algorithms modify


:. ;... :.: ::

. , :~: -., .............. -: : . . . ;-

,. :- . . :. . -
:. . : -. .: .: , .

~ ~r~ PCT/US90/03878
., f;
.
the sample rate of the recorder, minimizing the
superfluous recorded data and the impact of the recorder
on the target application. This is done through the
function key recognition and other hold off mechanisms
during the recording session. The basic repetitive
sampling of the screen occurs at a fixed rate until a
screen change occurs or until a function key character is
pressed on the keyboard. These events allow the sample
rate to vary, thereby giving the target program 4 more
access time to the central processing unit ("CPU") of
computer 2 to perform its operation. These events also
avoid needless intermediate recorded screens.
When the user inputs instructions in computer 2
that will cause a relatively large amount of processing by
target program 4, the input is first recognized by generic
recorder 8b before the target program 4 receives the
input. The generic recorder 8b transmits the instructions
to program 4 and then goes into a background mode for a
sufficient amount of time to allow the target program 4 to
finish processing the input.
Two techniques are used to effect this sample
rate change: 1) "minimum/maximum times to change;" and
~ ~ ... .
2) "fixed hold-off time to change." When the generic
recorder 8b recognizes a command sequence to be sent to
the target program 4, the minimum/maximum times to change
flexibly specifies a minimum number of clock ticks to
wait. This minimum number of ticks is specified in the
FTF file 14. After that elapsed time, the generic
recorder 8b starts sampling the screen again. The generic
recorder 8b also waits for the screen to "settle" before
it performs the recording of the screen resulting from the
particular command. This maximum wait, or "settle time,"
is again specified in the configuration file of data. The
settling of the screen is determined by sampling the
screen in the same state twice in a row. Identical
screens indicate that the target program 4 has finished
processing the input and is now in an idle mode. The
screen is then recorded to a data file 10.



,., ` . ., ;


.

WO91/00575- ;~ PCT/US90/03878
L'` -~
li - 31 -
2 ~ Q ~
The second form of adaptive recording used in
generic recorder 8b, is both function key hold off and
unsolicited screen change record hold off. Function key
hold off is similar to the above minimum/maximum sequence
except that no maximum amount of time is specified. The
-generic recorder 8b, after a fixed amount of time, will
sample the screen and record it to the data file 10. The
unsolicited screen hold off is for a different situation.
There are some application programs that process data in
real-time and display that data upon the screen at regular
or irregular intervals. These applications produce output
without user input. There are two time periods involved
in this type of screen state change. First, there is the
periodicity of the information generation itself. This
time must be taken into account when selecting the all-
over sample rate to be used for the target program 4. The
second period of time is the time that it takes for the
target program 4 to update the screen. This update may be
taken into account by specifying a hold off rate in the
FTF file 14. This is a specified period of time that the
generic recorder 8b will wait, once a sample finds that
the!screen has changed without user input. The generic
recorder 8b will turn off all sampling for a set period of
time, allowing the target program 4 the maximum CPU time
to complete its calculations and display. The generic
recorder 8b then will record the resulting screen to the
data file 10.
The final recording algorithm is for screen
ignores. Frequently, an application program will have a
status area of the screen that is of little or no
educational value. This portion of the screen may be
updated with every keystroke, such as a cursor position
read out. The data may be updated synchronously with the
keyboard such as a display of a ticking clock. The
recorder would normally register these changes and then
record screens per change that occurred. This would
generate an untoward number of data screen records that
may have to be edited out of the data file. The generic




t ' ' ' : , ",, ,~
'' ' '-" '-: :, "' ' ' ': .' ' ' .:. ~':' :
: ` . ~ : ::`: :' ':: ' ' ','. : .,: .
' ' : ,' " : ' ~ ', ':, ~ ~ ' ;
: 'i: ' . :: ' ,: ::

W091/00575 -- ' PCT/US90/03878
32 -

recorder 8b is adapted to prevent this by allowing the FTF
file 14 to specify a region of the screen that is to be
ignored during screen comparing. Any changes within this
rectangular region are not considered as a screen change
and therefore do not trigger a screen record.
The generic recorder 8b allows for separate
regions to be defined for both 40 to 80 column video
modes. The generic recorder 8b further allows for a
trigger phrase on the screen when the ignore region
algorithm should be invoked. This trigger phrase is an
ASCII string displayed on the screen whenever the user
wishes the generic recorder 8b to ignore the region of the
screen. The phrase may be at any location on the screen.
The FTF file 14 specifies the row and column of the phrase
along with the ASCII characters to seek. When a
difference is found in a screen and an ignore region is
specified for that video mode, the trigger phrase is first
checked and then the ignore region is called if indeed the
string does exist on the screen within the specified
position. The row and column may be set to zero by
specifying an empty string ("") to indicate that no
trigger must be sought before employing the ignore
algorithm. In this case, the screen compare routine calls
the ignore region compare routine whenever a difference is
found in the specified video column mode.

3. Data Management
The screen and type-in data for the generic
recorder 8b are placed in a ring buffer which is fixed in
size at the time that the generic recorder 8b program is
compiled. The begin ring pointer and end ring pointer
respectively define the beginning and end of this buffer.
The write ring pointer defines the point which data goes
into the ring. This data is placed into the ring buffer
character-by-character, generated by the type-in record
and screen record algorithms. The "begin ring write" and
"end ring write" pointers define the area of the ring last
written to the file. The begin ring write pointer is


.: ' . . :
. ~ ., :
- .

. . ~ . .
.,

WO91/00575 PCT/US90/03878
~ _ 33 _ 2~ 91 `-

constantly monitored whenever data is added to the ring
buffer. An overrun condition exists whenever the write
ring pointer equals the begin ring write pointer. The end
ring write pointer defines the currently completed data
structure within the ring buffer. This pointer is only
moved when data structure has the final record trailer
attached to it and is, therefore, ready to be written to
the data file 10.
Screen records are completed at the time of
recording. The record-screen routine places the header in
the ring buffer, compresses the screen data into the
buffer and then appends the standard trailer at the end of
the record. The video mode state is then examined to
discern whether or not the screen is in 80 column mode.
If it is not in the 80 column mode, the screen record is
finished, the end ring write pointer is set to reflect
that it is finished, and the routine then returns to the
caller. If it is in the 80 column mode, the above
procedure is repeated for the second half of the 80 column
screen data. The header of this screen record is adjusted
accordingly and the end ring write pointer is updated
beforè routine return.
The keyboard data type-in record is built up
over an extended period of time with the program 4
requiring processing time in-between all recorded
keystrokes. A type-in buffer is therefore built through
multiple entries into the keyboard section of the code.
This requires that some state in-formation be held about
the status of the current type-in buffer. The type-in
30- flag tells if a type-in buffer is in progress. The size 1
and size 2 pointer point to the size of the type-in buffer
in the data ring buffer. These bytes are updated every
time a key is recorded into the buffer. The type-in
record therefore "grows" as time passes to hold all of the
typed characters in the user's input stream. The end ring
write pointer is not updated every time a character is
recorded into the ring buffer because, for the CBT 12 to
recognize the type-in record, a trailer must be appended




. : . ' ' ' :~. . : '. ;:

WO91/00575 - PCT/US90/03878

~3~
to the end of the data. This trailer is appended whenever
a screen record is triggered if indeed, there is a type in
buffer in progress. ~"
The ring buffer write routine is triggered by a
fixed number of writes into the ring buffer. The recorder
compares the number of writes to the ring buffer to a
constant that is defined when the program is compiled. If
the number of writes to the ring exceeds this constant,
then the write flag is set and the ring buffer is written
to disk at the first DOS legal time. This algorithm may
be expanded to allow for a write, whenever the buffer
reaches a certain percentage fill point that may be
specified by the ASCII FTF file.
4. File Management
The generic recorder 8b produces formatted
instruction files called "paths". The generic recorder 8b
requests the name of the file that the recordings are to
be placed into at record initialization. This file is
then examined to first see if it exists. If it does not
exist in the current directory, then the generic recorder
8b creates the file and the recording session appears in
the file as target program 4 operations progress. If the
file already exists the generic recorder 8b must either
append to the existing file, overwrite it, or ask the user
for a new file name. This is done upon the first opening
of the file. This is indicated by a "chk-exists" flag.
The user replies to any of the above options. In the case
of appending, the generic recorder 8b must erase the end
of file record from the file to which the current
recording sessions data is to be appended. This is easily
done for this is a fixed length record. The session is
then added to the file, ring buffer segment by ring buffer
segment, one at a time. The overwrite option merely has
the generic recorder 8b create a file on top of the
existing file. In the case of a rename, the recorder
turns off and then awaits the user to press the start
record sequence to input the new file name.




., , .. :. ....... - ~ , ,;;
:: .
: ,: . - ..... :

: . : . ~. .

WO91/OOS7~ - PCT/US90/03878
1~ - 35 - 2 ~

5. Configuration
The configuration program 18 is written in C and
receives information from the generic recorder 8b through
the DOS multiplex interrupt. This routine first inquires
for the residency of the generic recorder 8b and then
requests the generic recorder 8b for the address of the
configuration data structure that the generic recorder 8b
uses for its operations. An INIT function then reads the
FTF file 14, defaulting to a FTF file extension, as is
more fully discussed below.
6. Generic Recorder Figures
The accompanying state diagram of FIG. 7 shows
the possible states of execution for the generic recorder
8b. Being a state diagram, FIG. 7 does not describe
lS process and data flow. Rather, it shows the various
states in which one might find the computer 6 after the
generic recorder 8b is started. Transitions between
states are indicated by the arrows on FIG. 7. The disk
symbol CFG FTF File 172 is not a state, but it is placed
on FIG. 7 to show that configure 174 requires
configuration data stored in a disk FTF file 14. These
states may be generalized to configure, target program
execution, recorder interrupts and recorder cleanup. Very
~ little of the code is straightforward, linear execution of
code in the normal DOS environment. The interrupt states
lend a level of complexity to the system that demands
exacting care.
Based on data from the CFG FTF file 172,
configure state 174 performs the following tasks:
(1) initialize internal data structures from the function
table file in FTF 172; (2) set the key interpretation
tables; and (3) arm the start and stop record key
sequence.
The target program state 178 is entered after
configuration 174. The target program state 178 runs as
in the regular DOS environment 176, except during the
keyboard interrupts 180 and the hardware clock interrupts
182.


, ;: - .: , , `- !



" ' ' ',: ~:~, , , '~' . ,

WO9l~00575 PCT/US90io387
36 ~
: - .

~6~ During a keyboard interrupt 180, control is
first sent to the recorder's keyboard interrupt routine.
The actions that may be performed are: (1) nothing, the
recorder is not activated; (2) recognize the activation
key sequence; (3) store away the character generated from
the keyboard; and (4) post an I/0 cycle for the clock
interrupt at 182.
During a clock interrupt, the generic recorder
8b moves from the targ~ prog~m l78 to the clock state
186. From this point, the actions that may be performed
are: (1) nothing, the recorder is not active; (2) compare
the screen to its previous state at 188; (3) store the
present screen; and (4) perform a disk I/O at 192. Wait
disk I/O legal l9o is a state in which the recorder may
not perform disk access because some other non-
interruptible process is incomplete within the personal
computer 6. An example would be that the computer 6 was
serving a disk I/O request from the target 4 application
when the clock interrupt occured. The generic recorder 8b
must delay until it is legal to perform the disk I/0
request.
~ FIG. 8 shows the data-flow and memory
organization between the configure state 174 (while an
INIT program 194 is running) and the resident recorder
196. The INIT program 194 reads a specified FTF
configuration file 14 from a disk of computer 2. Using an
internal, machine-specific, key definition table 198, INIT
194 engages compile routines 200 to compile configuration
data and key configuration table data and to insert them
into the memory of resident recorder 196 at CFG data 202
and key KFG table 204, respectively.
The resident recorder portion 196 performs the
recording task chiefly through the keyboard interrupts at
206 and clock hardware interrupts at 208. During
recording, both trigger a screen compare routine 210,
which compares the present and previous screens to
determine if the recorder needs to take any action, as is
discussed below. The CFG data 202 tells the interrupts


. :: . . . .

:... . . . ,: . , ,, ~ :
:. :

W O 91/00575 PC~r/US90/03878 , .
~ 37 ~ 2~

when it is necessary to record the screen to the data file
10. The compress format box 212 represents the previously
discussed ring data buffer. The ring data buffer is
written to the disk at disc I/O 214, and guided by the
stored data path information at 216. The start-up prompt
218 is a screen with the file name request field that
appears at record start-up.
Most of the memory used by the resident portion
196 of the gen~ric~recorder 8b is contained within the
recorder's ring buffer. Several pointers are maintained
within this structure. The first pointer is the beginning
of the next write to dis~. This is the data at risk. The
system begins the write to the disk file 10 at this mark.
The next is, of course, the next write into buffer
pointer. This pointer is the last valid information in
the buffer and the end of the write to disk area. The
next pointer points at the last type character buffer in
the ring.
The key CFG table 202 is the master table for
interpreting keystrokes from host 6's BIOS. Due to the
vast differences between machine keyboards, the BIOS
-keyboard interrupt routine is called by the generic
recorder 8b keyboard interrupt routine. The resulting
keystrokes interpreted by the BIOS are maintained within a
separate ring buffer within the generic recorder 8b. The
scan codes are the same across both PC's and PS2's of IBM.
The start-up sequences, however, must be decoded for each
variety of machine. Machine recognition code is provided
with a variable that contains the machine type and
therefore the keyboard type for direct key number decoding
for the turn on and turn off key sequences.
FIG. 9 shows the generic recorder 8b divided
into the four major parts: (1) monitored interrupt 222;
(2) screen multiplex interrupt 224; (3) clock interrupt
226; and (4) keyboard interrupt 228. The generic recorder
8b terminate-stay-resident portion 196 replaces several
normal interrupts so that whenever the operating system
calls these interrupts, the resident portion 196 will have



' : :

W091/00575 PCT/US90/038
38 -

an opportunity to examine them before they reach the
operating system.
FIG. 9 describes the fundamental TSR recorder
196 operations, whether in its inobtrusive background
state or in its active recording state. The generic
recorder 8b reacts whenever one of the interrupts listed
in FIG. 9 is called by the operating system. The resident
portion 196 replaces the operating system interrupt with a
call to a routine of its own from which it will chain back
to the normal operating system interrupt. For simplicity,
several interrupts are grouped together in FIG. 9 as
monitored interrupts 222, since these are examined by
resident portion 196 only to see if they are active. This
is because the generic recorder 8b must wait while the
operating system is busy with a task involving the
recorder 8b's ability to do disk I/O.
FIG. 10 shows the logic of a general monitored
interrupt 222. This control structure is placed into the
print screen, video BIOS, and DASD BIOS to maintain the
status of the screen. FIG. 10 describes a section of code
that is inserted into the aforementioned DOS interrupt
vectors. The control transfer may be made to this segment
of code through either a hardware generated interrupt 180
or a software interrupt 186 in the target program 178
Each of these routines has a status variable in the
resident recorder 196. The status is set at stop 230 to
mark that the interrupt is in the process of being
serviced. The service routine, which was the original
address within the vector table, is then called at stop
232 as if it was a subroutine. The original interrupt
service routine does the DOS, hardware, or target
application 4's requested work and then returns to the
monitored interrupt 310 routine. -The monitored interrupt
310 routine then marks the state of the particular
interrupt as non-active at block 234 and returns at iret
236 to DOS or the target program 4, whichever was the
calling agent. These interrupts, DASD, print screen, and
video 8IOS are monitored because they are not reentrant


; .. . ..
- , ' ' -

, ' ' ~ .,:,.,; ; .~ ' . .
',',: . :" , ,

W091/00575 -~ PCT/US90/03878
~ ~ 39 ~ 2~ 9~

and the recorder uses some of these functions. Thus, the
recorder cannot execute some of its routines when these
interrupts are active. Therefore, the generic recorder 8b
must know when these interrupts are active and does so by
checking the status variables that these monitors set at
step 230 and reset 234.
FIG. 9 also shows multiplex interrupt 224 which
is described in more detail in FIG. 11. This interrupt
will first check at branch 238 to see if the code issued
is in the command code for the generic recorder 8b. If it
is not, the normal multiplex interrupt routine is called
at chain interrupt 240. If the code is the generic
recorder 8b's code, the parameter sent to the interrupt
will be interpreted. Existence test 242 sees if this code
is already present and, if so, calls iret 244 to exit with
a flag saying that the system is already loaded. The
parameter being examined at branch 242 could-instead be a
return buffer command, which is tested at branch 246. If
it is, inquiry is made at branch 246 as to the location of
the buffer that will be used by the C code portion of the
generic recorder 8b to fill in control values. However,
if the parameter is not a return buffer command, there is
simply an iret 250.
The third interrupt connection in FIG. 9 is
clock interrupt 226, which is further detailed in FIG. 12.
The hardware clock interrupt routine is inserted into the
hardware clock interrupt stream. All comparison work and
screen recording is done within the C code. Most of the
major processing is done during this clock interrupt 226.
The two major subsections of the clock interrupt 226 are
process keyboard information 258, which is detailed in
FIG. 13 and which is further detailed in FIG. 14
(regarding handling the record key details) and the C
clock code 260, which is detailed in FIG. 15 and other,
subsequent figures. FIG. 16 describes a process flags
function 302 subset of the C clock code 260, and FIG. 20
describes the record screen 334 function. FIG. 17 details
a screen differs 312 operation, which has two subsets:

WO9lt00575 PCT/US90/03878
0 -

376 tmp = cmp screen of FIG. 18, and 382 tmp in ignore
region which is detailed in FIG. 19.
FIG. 12 shows the flow of an assembly routine
clock interrupt 226 that traps the system clock
interrupts. Upon receiving the clock interrupt signal
from a 8253 timer chip in thè computer 6, which occurs
18.2 times a second, a counter is set at step 252. The
counter referred to is an integer, single word, that is
incremented every time this hardware clock interrupt
occurs. This counter is used to track timing within the
recorder 196;
The interrupt 226 routine then moves to branch
254 and checks if the clock interrupt is already being
processed. The clock interrupt 226 is called periodically
whenever the 8253 timer chip generates an interrupt. This
means that the hardware frequently will cause the
interrupt to occur while the recorder is still executing
code from the last clock interrupt. Branch 254 prevents
the routine from re-entering while it is still being
executed from the previous request by exiting back to the
interrupt point at iret 262. If branch 254 returns a
negative value, the routine moves to branch 256 and checks
if the generic recorder 8b is turned on. If it is, the
routine moves to step 258 process keyboard and then calls
25 the C clock processing routine 260. If branch 256 returns
a no, the interrupt routine is exited at iret 262.
The final interrupt listed in FIG. 9 is the
keyboard interrupt 228, a detailed discussion of which is
postponed until FIG. 21.
FIG. 13 shows process keyboard 258, which is
called within the clock interrupt 226 to allow the generic
recorder 8b to process any keyboard interrupt queued data.
This routine examines the configuration table in CFG data
202 so that generic recorder 8b knows how to handle any
special key. Special handling includes ignoring and
triggering recorded screens. Process keyboard 258 then
branchs at 264, which checks to see if a key is buffered.
If it is not, process keyboard 258 returns at 266. If it



' ;, `', : ~ - ` :~,

WO91/00575 PCT/US90io3878
f - 41 - 2~

is buffered, branch 268 checks to see if the key is
specified in the configuration table of CFG data 2020 If
it is, then branch 270 tests whether it can ignore the
key. If the key cannot be ignored, branch 272 tests if it
is a function key. If it is a function key or if it can
ignore the key, step 274 sets record wait to
minimum/maximum or holdoff. If the key is not specified
in the configuration table in CFG data 202 at branch 268
or if it is not a function key in branch 272, then branch
276 checks to see if the key is a type-in character key.
If it is not a type-in character key, branch 278 tests if
it is an ASCII character. If it is or if it is a type-in
character key, step 280 records the key and loops back to
branch 264. Otherwise, out of branch 278, the character
is ignored while also looping back to branch 264.
FIG. 14 further describes record key 280, as
shown in FIG. 13. This routine places a type-in in a
buffer in the main ring buffer. The keys are recorded
with a compatible format within the CBT 12. More
particularly, record key 280, at branch 282, tests for an
auto exit condition, where the cursor has jumped to a
~- place not next to the last character typed. If yes, step
284 puts a tab function key in to close the previous type-
in and opens a new type-in. If no, branch 286 tests
whether to record a type-in buffer. If not recording a
type-in buffer then, step 288 sets up a type-in header.
Otherwise, branch 286, or the output of stop 288, leads to
branch 290 which checks for a type-in position flag. If
the flag is on, step 292 gets the position from the
compare screen routines subsequently discussed.
Otherwise, in step 294, the cursor position is obtained
from the hardware. In either case, step 296 records the
key and location, updates buffer size, then exits at
return 298.
The clock interrupt 226 of FIG. 12 is shown with
more detail in FIG. 15. The clock interrupt 226 is
divided into an assembly code jacket which sets up the C
code environment and stack described above as FIG. 12 and




:~

WO91/00575 PCT/US90/03878
42 -

the C code in FIG. 15. The C code manages the compare
routines and recorder control flags. The flag management
is detailed in FIG. 16 and the screen comparison routines
-are detailed in FIGS. 17 and 18.
The C code clock interrupt routine 260 in FIGo
15 is called when the generic recorder 8b is active and a
clock interrupt has occurred as described above. The
clock routine 260 begins at branch 300 to test for an~
flags. See FIG. 16 below. If there is a flag, the
10 recorder 8b proceeds to step 302 to process the flag(s)O
Otherwise, or if no flag or flags at 300, the recorder
tests for, waiting for record, at branch 304. Waiting for
record is a flag that indicates to the recorder 8b that a
condition exists that requires the recording of the screen
15 into the ring buffer. However, to prevent partly changed
screens from being recorded, this integer counter is
decremented for the FTF File 14 specified time 304, either
in min/max fashion 328 or holdoff fashion 316. When the
elapse time occurs, then the recording to the ring buffer
20 is performed by the record screen routine 334. See FIG.
20. If not waiting for a record at 304, the recorder 8b
proceeds to bump the sample rate count at step 306. The
sample rate counter is used to count the number of clock
interrupts that must occur between examinations of the
25 screen to detect changes. The sample rate interval in
clock ticks is specified in the sample rate variable in
the FTF configuration file 14. This prevents the recorder
from using too much of the personal computer 6's processor
time while waiting for the target application program 4 to
30 perform some action. Thereafter, the recorder 8b checks
whether a time to check the screen has been specified at
branch 308, and if not, returns at exit 310 to the calling t
assembler routine at FIG. 12. If a time to check the
screen has been specified at branch 308, the recorder 8b
35 calls the screen different test 312b, which is described
in detail in FIG. 17. Generally, though, the screen
different test 312b compares the current video refresh
memory with a copy of the last recorded video refresh



.. : .. :,... . .;,

WO91/00575 PCT/US90/03878
43 ~ 2 ~ 0 ~

memory, and inquires about a different. If no difference
is returned, the recorder 8b returns at exit 314 to the
assembly routine at FIG. 12, and otherwise proceeds to
branch 316 before a return at exit 320. The set wait to
holdoff step 318 is defined in the FTF configuration file
as the elapsed time for the recorder 8b to wait once a
screen change has been detected via screen different 312
(FIG. 17).
With further regard to branch 304, if waiting
for a record is positive, the recorder 8b proceeds to step
322 to decrement the wait count. The C clock interrupt
routine uses one wait count variable for delaying all
screen records. This is done for simplicity. Once the
system is in a state where it is delaying for the screen
to be recorded (to inhibit intermediate screen
recordings), this integer variable is decremented at step
322 to zero and then the screen record is executed. The
recorder 8b proceeds to branch 324 where, if the
decrementing has not produced a zero, the recorder 8b
returns at exit 326. Otherwise, at branch 328, the
recorder 8b checks if the minimum/maximum routine is
- active. If active, the recorder 8b checks if it has
waited for max at branch 330. In the case of min/max, the
elapsed time is set to max after min is waited. When the
screen is the same, which is determined by screen
different 312, and during the max period for two
consecutive samples, the screen is recorded. Screen
different 312 appears twice in FIG. 15 to illustrate that
it is the same routine, called at different places, with
different logic output controlled by its input. If the
screen is different at point 312a, the recorder exits 332
without recording the screen. If a no is returned from
312, 328, or 316, or a yes at 330 (which means the screen
has continued to change until the maximum time has
elapsed), the recorder 8b records a screen at step 334 and
sets the counts to zeros at step 336 before exiting at
338.




. .' ', "`''' ' ,""" .'' '.' '''''' ' ' ''' ' ''' . '

WO 91/00575 ~,~ PCr/US90/03878
44 -

Generally, a screen comparison is performed at
312 if the sample rate has elapsed. At that time, the
screen will be recorded at 334. If the ring buffer needs
to be~ written to the disk, then this routine sets the ring
5 write flag to true. The assembly code then performs the
checks necessary for disk I/O. If the checks affirm that
it is possible to write to the disk without interfering
with DOS, then the write ring routine is invoked. Other-
wise, the buffer will not be written till a subsequent
10 clock tick or keyboard press.
FIG. 16 details the process flags step 302 of
FIG. 15, i.e., flag processing during the clock interrupt
260. FIG. 16 depicts the actions taken when control flags
are set. If any flag is on, then the C clock interrupt
15 260 process flags 302 code is executed. This code is part
of the C clock interrupt 260 code. Thus, all returns made
in FIG. 16 are to the calling assembly code.
The major flags that are considered are the user
request end record, write data buffer ring, buffer
20 overrun, user file name request, and user file exists
flags. The last two flags are used to get file name
information from the user. The overrun flag is set
whenever information may be destroyed in the ring buffer
before it is written out to the disk file 10. The overrun
25 condition is when the recorder tries to place more
information into the ring buffer than there is free room
to hold it. This happens when the recorder does not get
the opportunity to write to disk but is still getting a
chance to process screen and keyboard data into the ring
30 buffer.
Writing to disk is the only way that the ring
buffer is emptied. The ring buffer is filled by recording
screens at step 334 and keystrokes (FIG. 20). The
recorder cannot write to the disk when the DOS operating
35 system is already being called by the target application
program 4. This is a DOS reentrance problem. DOS is a
single tasking operating system and does only one
operation at a time. Therefore, if there is a long series




, ,,:, : .' , ., ' ~ , :
. ~ ; .... . . ; - .. -

WO91/00575 PCT/US90io3878
~; _ 45 - 2~ 9~

of DOS calls that cause many changes on the screen and the
recorder never gets control when the target application
program alone is executing (i.e., not in a DOS call) then
an overrun may happen. The first two control flags
checked, at branches 340 and 344 deal with this situation
by allowing the clock interrupt 260 to return at 346 with
the done flag or write ring flag existing.
If a test at branch 340 write ring flag is on,
an attempt is made to write to the disk at step 342.
Therefore, the process flags 302 routine proceeds to check
for a done flag at branch 344. Otherwise, at branch 340,
the process flags 302 routine proceeds to the done flag
branch 344. If user indicates that the recording should
stop, via a keyboard interrupt done flag, process flags
302 returns via exit 346. Otherwise, the overrun flag is
checked at branch 348, which is set as described above.
If the overrun flag test returns positive, the buffer must
be emptied; thus it is necessary to cancel all flags, set
write ring to true, and return from 350 via 352.
Otherwise, if the get file name flag is yes at branch 354,
obtain the file name in step 356 so that an exercise
recording can be started. Thereafter, or-if-there is no
flag set in branch 354, process flags 302 test whether the
file exists. At 358, if the file does not exist, the
logic proceeds to create a file at 370. Otherwise, the
user is asked whether to overwrite, append, or cancel at
step 360. If the user selects to cancel, process flags
302 cancels all flags and sets write to true at 364 before
return 366. Otherwise, if no is detected at branch 368,
there is a return at exit 374. Finally, if overwriting is
desired, step 370 creates a file and returns at 372.
FIG. 17 shows screen differs 312, which checks
to see if the present screen is significantly different
from the previous one. This routine is the driver of the
assembly code compare routine tmp=cmp_screen 376, which
checks the current configuration and coordinates all the
screen compare routines.




.- - , - -

W091lO0575 PCT/US90/03878

?. `~Q~9
The screen differs 312 is called after every
sample time is elapsed, and calls an assembly routine 376
which compares the screen to see if any target application
screen writes have occurred since the last sample was
taken. If there is no difference, i.e., if tmp==O, then
return to 380. If only one difference is found it is
interpreted as a single typed character. The routine then
checks if the typing is in an ignore region of the screen
by calling the tmp in ignore region at branch 382. If a
positive response is returned, the screen differs routine
exits at iret 384 and ignores the screen change. If the
change was not in an ignore region, the new screen is
saved at step 386. If the type-in position flag is set at
branch 388, the character and its position are recorded in
the small type-in ring buffers at step 392. Thereafter,
390 and 394 indicate returns.
FIG. 18 details tmp=cmp_screen, an assembly
routine which uses the 8086 block compare instructions, to
quickly compare the video with the last recorded copy. If
only one difference is found, the recorded buffer is
updated and the location of the difference is returned~
If no differences have been found, branch 402 sets the
value of cmp_screen to zero and exits through return 404.
If more than one difference has been found, branch 406
sets the value of cmp screen to 1, and returns through
408. This value of cmp_screen is interpreted in branch
378 of FIG. 17 and will cause the new screen to be
recorded if the value equals 1, provided the difference is
not in an ignore region as tested by the routine in FIG.
19 discussed more fully below.
IG. l9 details the tmp in ignore region 382
routine in FIG. 17 used to ignore a rectangular region of
the screen. This region is dictated in the SYS
configuration file 14. The region ignore may be triggered
by a specific phrase appearing on the screen at a specific
location. Branch 414 checks for the specific string that
should mark the beginning of an ignore region. If not
found, the routine exits with a negative value at 416. If




:: . ~ . , . :
. ~ , . . - .. , ., . . -

WO91/00575`-- PCT/US90/03878
~ ~ 47 ~ 2~0~

a qualify string is found, the routine checks if the
changed character falls within the specified row and
column range of the ignore region. If it is outside the
row range, branch 418 returns a negative value and exits
at 420. If outside the column range, branch 422 returns a
negative value and exits at point 424. If the difference
is within the ignore region (branches 414,-418, and 422
all return positives), the routine returns a positive
value through point 426, and screen differs of FIG. 17
subsequently ignores the screen change and exits at 384.
FIG 20. Describes in more detail the record
screen step 334 of C clock code at FIG. 15. This routine
checks the type-in mode at branch 428 and if active,
allows the routine to finish the typing input at step 430.
Once finished, the header and screen data is re-ordered at
step 432 in the buffer for saving. If a 40 column screen
is being recorded, the routine exits at 436. If an 80
column screen is present, step 430 reorders the second
header and screen and exits through 440.
FIG. 21 is the keyboard interrupt 228. This
interrupt is monitored first for the "on key" sequence.
When this sequence is detected then the interrupt sets the
flags to start recording and to query the user for the
file name. Once recording, characters are buffered by the
keyboard interrupt and then examined by the clock
interrupt where they are recorded. The off key sequence
causes a flag to be set and the clock interrupt performs
the cleanup task. Interrupt entry 228 KB INT, then step
442, gets the BIOS pointers; and then step 446 calls the
BIOS and branch 448 tests for an key up. If yes, iret
from the interrupt all release key interrupts are
virtually ignored 450. If no, branch 452 tests to see
whether to dump the character. If yes, branch 454 tests
if the ROM code is in use. If it is, then step 456
replaces the BIOS pointer. If it is not, then there is
returns at iret 462. Branch 458 tests if the character is
in the handler. If it is, then there is a return at iret
460. Otherwise, branch 464 tests if there is a shutting




., ~, :,, , ~ " - ,

WO91/00575 PCT/US90/03878
48 -

d~r r-quese. If there is, then branch 482 tests whether
to write the request. If yes, step 484 calls write A to
disk routine, then returns at iret 486. If no, branch 466
checks if the character is turned on in branch 466. If it
is not, branch 468 performs a single screen request.
Thereafter, if no, step 470 set flags for single screen,
then returns at iret 472. If yes, branch 474 checks for a
turn on recording request. If there is none, there is a
return at iret 480. If there is, branch 476 set flags for
recording, then returns at iret 478. If step 466 returned
yes, then the system is recording. Step 490 checks for a
turn off key sequence request. If yes, step 492 set flags
to shut down, then returns at iret 494. If no, branch 496
checks for a BIOS OK. If there is none, then step 498
brings on a translate key. Either way the key is then
recorded to a small temporary buffer in step 500 where it
will be processed by the next clock interrupt. The write
request flag is then checked in branch 482, and the write
routine called in step 484, etc.

7. CBT State Program Structure
- Since all the keystrokes and pointer selections
are handled in a control loop outside the functions, the
CBT 12 code must keep track of where it is at any moment
so that on return the information received can be
processed properly. This is, in effect, state-driven
processing.
The major states are referred to by page number.
The author menu 20 is page l. When the system starts
initially or returns from completing a task, it usually
finds its way back to the author menu 20 or page l state
for authors (again note that students have their own first
page which they see at start-up and they never have access
to the author menu 20 or the authoring functions).
When on page l there are certain expectations
3S about what keystrokes are acceptable and what actions to
take when those keys are hit. The code will test if
p CBT_Page = l.


~ .
. - .: ` , , ' ' ': ' ' ; :, ' - . ~ ': ' -


: . - ~ ; .. : .
::: : ,. .,.:, .
~ ;, ~ ::

WO91/00575 PCT/US90/03878
~, .
~ 49 ~ 2~3~

There is also a page la which is a submenu off
the author menu 20 for the file functions. This is really
a separate state in that it has different choices off the
menu and two file input fields instead of one. However,
as the two are similar in so many ways they can be looked
upon as one entity.
Page 3 handles the defaults (F10 off the author
menu 20). There are two screens in this mode, one for the
- session drive and automatic mode time delay, and the other
for the super password, default time display, disk drive,
light pen adjustment field, and printer type.
Page 4 is the single screen utility 56 mode (F7
off the author menu 20), much like the modify 46 mode for
an exercise, but has some special differences. It is, in
effect, a one screen work area into which one can bring
in, change, and save a single screen. Page 4 is used for
the modification of control screens by developers, and
for the creation of QSCRs by authors and developers. Two
additional submodes (color-ASCII 54 and options menu 52)
are available in page 4.
The remaining page state is zero and it holds
the states and substates involved iniselecting and playing
back an exercise. Each of these additional states for
page zero has a flag value to determine if it is
operational.
The student registration page is a one screen
state that is flagged by whether or not p_Reg Page is set.
When the user runs the critique 38 routine,
which allows them to rate the course, he or she will see
four screens and the state is identified by p Crit Page.
If the student has registered properly (or
authors and developers have run a student diskette 32
session by selecting F9 from the author menu 20), the
p_Dir_Page flag is set and the course directory is
displayed to allow selection of an exercise.
Once an exercise is selected (including by entry
of its name and selecting F1, F2, or F4 off the author
menu 20 for authors and developers), the screen that shows




, . . . . , :, ..., . ~ . :

-: ~:.. , . , ~ . -: .

W09l/00575 PCT/US90/038
50 -

what modes are available for that exercise (automatic
display 24, manual display 26, instructional 28, or
proficiency 30) is called QSCR 4 and this provides another
- state. Finally, the CBT 12 goes into playback mode and
the exercise is run. However, authors and developers can
enter modify 46 mode with the selection of an exercise
- name and entering F4 off the author menu 20. So the user
can be in p Playback_SW and additionally p Modify_Mode_SWO
Modify 46 is where most of the work to customize
the exercise is done. In this mode one can also have
additional substates. One can bring up the light pen
window 57 which will be up if P_LP_Modify-Mode is trueO
Color/ASCII 54 mode may be selected and identified or the
options menu 52 may be accessed for editing (the options
menu is active if p_Err_Mess_Select = TRUE). In modify 46
mode, multiple edits will add an edit mode flag to
identify operators (i.e, D for deleting).
,,
D. Menu Structure
Conceptually, it is helpful to understand this
invention by looking at each of the menu options to
- - illustrate the possible system flow.
The author menu 20 comes up with the following
choices:

(F1) Manual Playback (FIG. 25)
(F2) Automatic Playback (FIG. 24)
(F3) Connect to Live System to Record
,(Optional)
(F4) Modify (FIGS. 29-34)
(F5) Print Exercise (FIG. 28)
(F6) File Functions (Submenu)
(F7~ Screen Utility (FIGS. 35-36)
(F8) Simulate Student Exercise (FIGS. 22-27)
(F9) Student Diskette Session (FIGS. 37-38)
(F10) Change Defaults (text)
With the exception of the file functions at F6,
each of these goes off to a particular task. File


, . : . ~ ,, ' ', ..... ..

, . . : :.. : : . , -:
. ,. ' I
:: : :: . ~ :: : . . :
-: . .,:. ~

WO9l/~0575 PCT/U590/-3878
f~ 51 2 ~

functions will take the user to a submenu which is as
follows: ;
.
(F1) Copy Exercise to Drive A (FIG. 40)
(F2) Copy Exercise to Drive B (FIG. 40)
tF3) Copy Exercise to Drive C (FIG. 40)
(F4) Copy Exercise to Drive D (FIG. 40)
- (F5) Rename Exercise (FIG. 42)
(F6) Delete Exer~iSe (FIG. 41)
(F7) Append (FIG. 43)
(F8) Replace Pathway (Text)

E. QSCRs
A QSCR could be defined as a screen which is
added to the recorded pathway since almost every added
screen is a QSCR. They must have QSCR in the first four
characters in the upper left hand corner of the screen
(from screen coordinates 0,0 to 0,3). It is not uncommon
for authors to think of QSCRs as instructional screens
since those are the ones that they make.
However, the selection error messages are stored
automatically as QSCR 2. And the screen-that allows
selecting the mode to run an exercise for the student is a
QSCR 4.
One other special QSCR is the QSCR X which is
the exercise statement that students can review while
doing an exercise by hitting the PgUp key. It will
retrieve the last QSCR X that had been seen in the
exercise. If none has been seen yet, it will do nothing.
The flag p_QSCR_X_Exists is set (first to three then to
TRUE once the screen itself is saved in the temporary
storage).
All the other QSCRs affect whether a screen is
seen or not during playback 22 in the four modes (manual
26, automatic 24, instruction 28, and proficiency 30).
A QSCR P will show up in proficiency 30 mode
only, whereas a QSCR P will show up in all modes but
proficiency 30.




- . ... :. .: . : :, ::. .

WO9]/005~5 - 52 - PCT/US90/038 ~

L
QSCR M will show up in manual 26 mode only,
while a QSCR M will not be seen if the mode is manual 26
or automatic 24.
A QSCR A is automatic 24 only, a QSCR C
instructional 28 mode only, and a QSCR B is seen only if
manual or automatic.
Q5CR N will not be seen by users in any mode (it
is for authors making notes), while QSCR with no letter
(QSCR blank) will be seen in all modes.
There is one other -- QSCR G -- which provides
the option of placing a time delay for the particular
screen.
All of the playback 22 QSCRs are handled in the
code in CBT8.C in P_Display_l which makes the
determination of whether to go on to display the screen
(done in the function P_Display_2) or move forward.

F. Play~ack
With further regard to playback 22 in FIG. 2,
recall that an exercise can be "played" in several modes.
The mode will determine what screens will be displayed and
whether help or error messages will be shown. The four
basic playback 22 modes are automatic playback 24, manual
playback 26, instructional playback 28, and proficiency
playback 30. An exercise may come with the acceptable
modes attached to it from a management system. When
selected from the course directory or from the author
menu, the proper QSCR 4 screen with the available modes
will be displayed.
The variations available of those four options
are housed in a series of compressed screen files
CBTS4x. SCR with the x being a number from 0 to 7. The
screen will not show the characters to the left of each
entry -- either (M), (A), (C), or (P) -- as they are
printed blue on blue. They are there so the line can be
pointer device selected -- the pointer device routine
searches to the left for the parenthesis to read the
proper option [(See routine Plpsrch in CBTl.C) ] .




: ~ . :,:; :: :: . .: .: . , -

WO91/00575
PCT/US90/03878
_ 53 _ 2~6~

What users do see is the bar, currently white on red
although this can be changed in a control file called
stO.pew, and this bar works going up and down by reading
the attribute in the first position where an option
description is written. This must be yellow foreground.
Thus, if modes are available with a gap because one option
is not available, the program will search for the next
yellow start line and skip the space when displaying the
bar. This color key is crucial to the proper~operation of
the bar. The Check_For_PTR_Simul routine that handles
this is in CBT2A.C. Each mode has a different intent.
The proficiency playback 30 mode, or the test
mode, does not provide the user with any substantive
assistance in the way of procedure lines or explanatory
material and requires the correct answer or action be
selected before the screen is advanced. The number of
correct answers is kept so that a score can be returned.
There are variables for number of consecutive errors and
total errors and so on, all software and user driven, so
that students may be taken out of the exercise and
required to start again or run again at a mode where they
can learn again.
On those exercises without proficiency, the
highest mode is instruction. Here, the user is again
required to select the proper selection mirroring the
expert's selections. However, there are procedure lines
and other explanatory materials to guide-one along the
way, and hitting Page Up will always bring up the exercise
statement screen -- the one that explains the purpose of
the exercise.
The other two options are different only in
whether the computer or the user advances the screens
without valid selection being a requirement. One is
manual 26, which requires users to pointer select or enter
any function key to advance. The other is automatic 28,
where the system will run the screens with a specific time
delay and highlight the proper choices as it goes along.


,


: . .: ,. . . . .

.. :. : , , ~ '

WO91/0057S PCT/US90/0387
54 -

~ The impact of automatic 24 on playback 22 should
be apparent (p_Select_Time is one variable tested to see
if the mode is automatic). The instructional 28 and
proficiency 30 modes are referred to as the teaching modes
and the effects of whether it is teaching mode or not are
littered throughout playback 22.
The highest mode of an exercise must be
completed for the student to get a completion flag for the
cxercise in their course dire-ct~ a~d c ~ di~ for ~he
exercise.
Several of the author menu 20 and file function
items effectively run their way through the playback
functions found in CBT8.C. Even when printing an
exercise, it is really printing while doing an automatic
playback 24, reflecting the fact that the screen is the
real data, though unlike automatic-playback, printouts see
all screens in an exercise.
Because the user can enter playback in various
modes (Automatic 24, Manual 26, Instructional 28,
Proficiency 30) and user-levels (student, author,
developer) and options (printing 45 or modifying 46), the
code has an numerous conditional statements and blocks of
code that may not be activated during any particular
playback 22.
In addition, it may be necessary to leave CBT 12
code and go back to the control loop for input. This
requires setting flags to remember where the user was,
what the user was doing, who the user is and the like,
which adds to the complexity of the playback code. Note
that any statement in a function in the playback 22
functions loop that is a return with TRUE or FALSE as a
condition is actually relinquishing control back to the
control loop and some flags will have been set before that
call to determine where playback 22 will pick up from.
Let's take a simplified approach first and
pretend, for the sake of elucidation, that input is
obtained locally, to see the actual flow of the playback
process itself.




:: , . ; ~: . ~ j: :., :

W091/OOS75
PCT/US90/03878
~ - - 55 - 2~

The loop begins by initializing all the
variables, opening the exercise file, loading in as much
as will fit in the big buffer, and then reading the first
few records into staging areas. In effect, the first
screen will find its way into the buffer that is ready for
video display. If an error screen is affiliated with it,
that error screen will have been read and staged in the
error buffer (p_Err_Buf). Then the next screen is read
and, normally, the process will be stopped as a flag
indicating the first screen is a stopping place should
have been encountered in header byte seven of the screen
following the first screen.
This staging process-is a key to the
understanding of what is happening in playback 22. In
essence, each read fills a buffer pbuff and then has its
header read into p_Tempbuff. Depending upon the
situation, that information is then moved somewhere and
the next screen is read into pbuff. Eventually, the
buffers ptbuff and p_Low_Buff house the screen displayed
(they are filled and then copied to the screen such that
the screen and the buffers both hold the same
information). Remember that the default screen size is
expected to be 40-character so it takes two buffers to
hold an 80-column screen. If an error message was found
for the screen it would be moved from pbuff to p_Err_Buf
and that would empty pbuff again so another read would be
made. At the end, if along the way that stopping byte was
found, the final filling of the buffer with nowhere to put
the information is the end of this staging. When
completed there will always be something in ptbuff (and if
80-column a second half in p_Low_Buff) and in pbuff with
the first 38 bytes of pbuff also sitting in p_Tempbuff.
P Tempbuff holds the header information frequently
referred to in the code when looking for the next record
to see what it tells about what is to come and about what
is displayed. It should be noted that if there is typing
it comes in a typing record which will set flags and fill --~
p_Typ_Buf in the staging.




: : :. . .. .
.

WO91/00~75 PCT/US90/0387
~g~ 56 -

Note that two QSCRs back-to-back would mean only
two reads since a QSCR has no error message and the second
QSCR has no place to go so the staging stops. An exercise
screen with error and typing might do several reads.
.. . i,
Also note that pbuff houses only one record and
this means that an 80-column screen is only half-read when
the user has stopped reading (the important part -- the
header which will later tell that the user has an 80-
column screen and needs another read -- is in pbuff).
Still another caution: as the buffers include
reading the three bytes that precede the header but the
staged buffer locations do not. Thus, there can be some
confusion about the location of a byte. For example,
while offset 7 in p_Tempbuff houses the vital From Code
flag, it is found at offset lO in pbuff.
In Playback 22, the user has staged information
in the various buffers and has data sitting in p_Tempbuff
to further describe what's ahead. Now the playback 22
loop begins.
The functions are, in order, P_Display_l,
P_Display 2, P Display_3, P_Save_l, P_Move_l, P_Move_3
(Move2 is missing -- it became part of l), P_Move_4,
P Move_5, P_Move_6, P_Play_Sel l, P_Play_Sel_2,
P_Play_Sel_3, P_Proceed_l, P_Proceed_2, P_Proceed_3.
These go through till the exercise is over.
Depending on who the user is and what the user is doing,
some of those may have no use and be skipped.

P_DISPLAY_1 This sets up the display of the screen on
the video. It checks whether the screen
will in fact be displayed (if, for example,
it is a QSCR C it is not supposed to
display in any mode except instructional
and would therefore be skipped and jump the
user past the remaining display routines.

P_DISPLAY_2 Now the system actually puts the screen
onto the video by poking ptbuff to the




: . . .:.. : : .: : , ,:

WO91/00575 PCT/US90/03878
~ 57 - 2

video buffer (and p_Low_Buff if the screen~
is an 80-column screen).

P_DISPLAY_3 This function will check any page condition
(like GoForward or print through some page)
to see if it has been met, will increment
the displayed page number for modify 44,
and finally test whether it should now be
waiting for a keystroke or continue
forward.

10 P_SAVE 1 Before saving what is on the screen the
system makes sure the user is not deleting
or in the deletion phase of a replacement
(in which case the system won't write).
Otherwise, the system saves it in the file
if modifying. For both modify 44 and
non-modify modes it does some checking for
last record.

P_MOVE 1 This will lead to the next mode -- the
Selection Error Mode -- if an error screen
exists.

P_MOVE_3 If the user is printing, the system now
prints.

P_MOVE_4 If the screen is a QSCR, the system tosses
out any error message. In modify 44 this
is where the EndOfExe.SCR is ~isplayed if
the last record has been reached.

P_MOVE_5 Now the system is ready to stage the next ;~
block since the user has left the original
screen. Any errors, etc., use the error
buffer and don't need the original screen
anymore. While the next screen is now
buffered in ptbuff, it will not display




- . : : . ~ .,. ;.. : ., . , ~: - . . :

WO91/00575 PCT/US90/03878
- 58 -

until the user reaches the start of this
loop again. The system also handles the
typing at this point. This is function
P_Playback_Typing.
. . .
5 P_MOVE_6 Gets ready for the next user action.

P_PLAY_SEL_1 Basically timer tests.
P_PLAY_SEL_2 Displays the auto block highlight of the
correct entry.

P_PLAY_SEL_3 Handles the intensity of the top and bottom
lines, something handled differently by the
host and CBT. This type of screen
adjustment is application-dependent.

P_PROCEED_1 This tests the user's input.

P_PROCEED_2 This is another time test.

15 P_PROCEED_3 Timers and returns to handle what to do
next.

1. Playback with Control Loop
With the above introduction to the flow of
playback, add the leaving and returning issues presented
by the fact that keystrokes and such are captured from
outside the function.
In the playback 22 loop there are various exit
points. Normal movement through the loop happens when
each function réturns a value called P_CONTINUE which is
in effect an incrementing value returned to the loop to
say go on to the next. A new location may be set before
that return so the loop increment is reset to a particular
playback 22 function to skip unneeded functions and jump
ahead. As to the third exit, whenever a playback 22
function returns with FALSE, it is the same as "go to" the
control loop to await further action. When an action


...,, -.... ~ ... . - ~ ~: ,;,


.: : :,`-.. : : ': ' . ::. :: ': : : ,

WO91/00575
PCT/US90/03878


triggers the return, there are two basic variables
involved. The first is P_Play_Int (transferred into P_Int
later) that handles the larger issue of what the user was
when the user left (a zero means the user is starting for
5 the first time). If the user is modifying, p_Play_Int
will-come in with a value of four and the user has an
additional variety of locations the user may return to
above and beyond those handled by P_Play_Int. There is
another variable set when the user leaves called
10 P_Play_Int_Code which will identify the function to be
reentered.
In the normal process, after the screen has been
displayed in function P_Display_3 the program goes to get
the next keystroke in modify mode. P_Play_Int_Code is
15 set to return to the next function, P_Save_1. The exits
may be timer delays or tests used in the automatic
playback 24, where screen advances are at timed intervalsO
Sometimes the logic waits for the correct answer to be
selected. Sometimes the logic waits for the keys to
20 advance to the next screen in modify 44 mode.

2. Playback Flow Charts
FIG. 22 details playback 22 of FIG. 2. Step
502, open file, opens the file for reading in the data.
Open file leads to step 504 to load the big buffer bytes
25 into RAM which reads in a large piece of the file 10 from
memory to RAM of computer 2. Thereafter, step 504 leads
to branch 506 which checks whether a working buffer is
empty. If it is not empty then playback 22 proceeds to
branch 508 where, if the record in the buffer holds an
30 error record, the error record is detected. Playback 22 r
proceeds to step 510 to move that record from the working
buffer to error buffer, and then to step 512 empty working
buffer so that the buffer can be refilled by the next
record. Thereafter, playback 22 proceeds in a loop back
35 to 506, the branch which determines whether the working
buffer is empty. At branch 508, if there was no error
record, then playback 22 proceeds to step 514 to determine



- : .. .. : . . : ..

- .:
: . - ., .
: . . ' . ' . ~ :

WO91/00575 ~ PCT/US90/03878
. ', "; ~,
- 60 -

if there is a typing record. If there is, playback 22
proceeds to 516, a step which moves the working buffer
data to the typing buffer, and then loops back to branch
506 via step 512 as shown in the FIG. 22. With further
regard to the branch 514, if there is no typing record,
playback 22 proceeds to branch 518 which checks whether a
virtual screen buffer, which houses the basic page 47, is
empty. If the buffer is empty, playback 22 proceeds to
step 520, which moves the working buffer data to the
virtual screen buffer because, if it is not an error or
typing, then it must be a basic page. Thereafter,
playback 22 again loops back into the program via step
512. However, if branch 518 determines that the virtual
screen buffer is not empty, then all buffers are full,
there is no place to store data. Thus, it is now
necessary to process the current data. Playback 22 then
proceeds to step 522 process playback record which is
discussed below. Thereafter, playback 22 proceeds to
branch 524, which checks whether the current working
buffer data holds the last record flag indicating the
exercise is at the end. If the record was set, then the
CBT 12 returns to the program at 526. The loop at 506
will read data into the working buffer and find it's
proper buffer (error, typing, virtual screen), until the
virtual screen buffer is full, at which time that set of
records is processed. At this point the next record is
still in the working buffer. Thus, after process playback
record 522, the next record header is checked for the last
record flag. The error, typing, and virtual screen buffer
flags are set to empty at step 528 and the process con-
tinues as the loop finds the next record in the working
buffer when it returns to 506.
FIG. 23 shows a more detailed explanation of the
process playback step 522. In FIG. 23, the CBT 12 begins
with step 538, which tests whether or not to display, as
some screens are not displayed depending on the playback
22 mode or user type. With respect to 538, if the answer
is no, then the program goes via return 542 back to the




.: : . .. .. .
: . ~ . ~: , ., , :,
:: ~: .
, ~, .... .

WO91/00575 PCT~US90/03878
~ - 61 - 2~$~

program as shown in FIG. 23. Otherwise, at 540, the CBT
12 proceeds to step 544 to move the virtual screen buffer
contents to the screen, as is more fully described belowO
Thereafter, the CBT 12 proceeds to branch 546 which tests
whether the tutorial is being played back in the automatic
mode. If the answer is yes, the CBT 12 proceeds to
automatic playback step 24 and then onto return 542.
Otherwise, at branch 546, the CBT 12 proceeds to determine
whether the playback is in the manual mode. If the answer
is yes, the CBT 12 proceeds to step 26 manual playback and
then onto return 542. Otherwise, at branch 548, the CBT
12 proceeds to branch 550 to determine whether it is being
played back in the instruction mode. If the answer is
yes, the CBT 12 proceeds to step 28, instructional-
playback, and then onto return 542. At branch 550, if theinstructional mode query is negative, the CBT 12 proceeds
to branch 552 to determine whether it is being played back
in the proficiency mode. If yes, then the CBT 12 proceeds
to step 30 proficiency playback 30 and then onto return
542. At branch 552, if a negative is returned, then the
CBT 12 proceeds to query whether.to enter the print modeO
If the answer is yes, the CBT 12 proceeds to step 42 to
commence printing and then onto return 542. At branch 28,
if a negative is returned, the program proceeds to branch
556 to determine whether enter the modify mode 44. If the
answer returned is yes, then the CBT 12 proceeds to step
44 modify and then onto return 542. If the answer
returned at the modify mode query of 556 is no, then step
558 is reached. If this happens, there must be an error
condition which is processed, and then the program moves
to return 542.

a) Automatic Playback (Page 1 F2)
Like Manual Playback 26, in this mode if called
from the author menu, the name of the exercise desired is
entered in the exercise name field on Page 1 and the
required flag is set by calling P_Automatic_Playback in




: ,. - . . - , , .
,,. : -
.. . . . . ..

: ~ :

W091/00575
PCT/US90/03878
2~ 62 -
CBT7.C. Students would select the exercise from the
course directory.
The function will set p_Select_Time to whatever
value is in p_Select_Timel or to 0.
PPlaybck is called as the last option in
P_Automatic_Playback.
Normal stopping places in playback 22 are
ignored when in automatic 24 mode. For example, since
p Stop_Each_Screen_SW is FALSE, P_Display_3 simply
continues on without going back to the control loop. Most
functions have no action to do in automatic 24 mode.
P_Move_5 reads the block and automatically display any
typing, and P_Play_Sel_l will set a timer interrupt and
return until that automatic time delay has been met (the
logic sets pseudo interrupt P_Play_Int to 1 and when
playback 22 is called again, that interrupt sends the
logic back to this function to check the clock again)O
There is a final return to the last step in the playback
22 loop, P_Proceed_3, before displaying the next screenO
This is to be sure that nothing critical is happening in
the control log that requires attention.
FIG. 24 details the automatic playback step 240
The CBT 12 commences with a wait time step 560, which
causes the program to wait the time delay specified in
this automatic playback mode before proceeding to the next
screen. Thereafter, the CBT 12 proceeds to branch 562 to
determine whether this screen has a user selectable item
i.e., if it is in playback 22 in instructional or
proficiency mode. If it is not, the CBT 12 proceeds to
return 564. Otherwise, at branch 562 the CBT 12 proceeds
to 566 put highlight block on the correct choice to show
the right answer. Thereafter, the CBT 12 goes to return
564. Automatic playback 24 mode proceeds without user
intervention.

b) Manual Playback (Page 1 - F1)
In the normal student playback 22 (or when
simulating student with F8 or running a student diskette

WO91/00575 PCT/US90/03878
- 63 - 2~ f9'~ ..

session with F9), this mode is selected from the QSCR 4
choices. By selecting 1, Psnot4ck sets the key variables.
If called from the author menu, however, the name of the
exercise desired to run is in the exercise name field on
Page 1 and the required flag is set by calling
P_Automatic_Playback in CBT7.C. PPlaybck is called as
the last option in P_Automatic_Playback and the user is on
his way.
In essence, the flow will stop at each raw page
and wait for the user to hit any function key to advanceO
The P_Display_3 function finishes putting up that screen
and then returns to await input. In manual mode, once any
function key is pressed the answer is assumed correct and
the exercise will continue forward to the next page. Any
typing will be done for the user.
FIG. 25 provides the details of step manual
playback 26. The CBT 12 proceeds to step 568 to wait for
any user input. In manual mode the screen will change on
any user input. It will wait as long as the user wants
20 (unlike automatic playback 24, which plays back in a fixed --~
time interval) before cycling to the next screen.
Thereafter, the CBT 12 proceeds to branch 570 to determine
whether the input is a selectable item. If it is not a
selectable item, the CBT 12 proceeds return 572. However,
if a selectable item has been entered at-branch 570, the
CBT 12 proceeds to step 574 to put highlight block on
correct choice (see discussion of FIG. 27 above).
Thereafter, the CBT 12 proceeds again to return 572.

c) Instructional Playback
FIG. 26 provides the details of step 28,
instructional playback. This mode commences with step
576, display procedure line. If procedure line exists, as
in instructional mode an extra line of 'advice' is often
put on the screen for help, it is displayed. Thereafter,
35 the program CBT 12 proceeds to branch 578 which determines
if a type-in record exists. If yes, the CBT 12 proceeds
to step 580 get and test type-in, which has the user input



- . . .
. : ,, :: . ' ;~. :, .


. . : :

WO91/00575 PCT/~S90/03878
. ~ - 64 -
2~
the typing, and the program test it against the expected
response on file. Thereafter, the CBT 12 proceeds to
branch 582, to check the result of the test. If the
answer is no, (the response is not correct) then the
program CBT 12 proceeds to 584, error count, to see if the
maximum number of incorrect attempts has been reached. If
this is not the case, then the flow proceeds to step 586
display appropriate error level, where it displays the
error message and increments the number of errors.
Thereafter, the CBT 12 loops back to step 580 get and test
type-in. However, if an affirmative answer is returned at
branch 584 (that is, the user has exceeded the max number
of attempts), CBT 12 proceeds to display the correct
answer at step 588, and then loops back to 580 again to
15 have the user enter the correct answer now displayed.
This looping can be exited by entering a correct answer at
branch 582 which, like returning a negative answer at
branch 578, leads to step 590 get test action key which is
the function key or pointer selection that is required to
20 take the next action which gets the next screen. Step 590
leads to branch 592, which tests the input for the right
answer. If a no is returned at branch 592, the CBT 12
proceeds to branch 594, to check to see if the maximum r
number of incorrect attempts has been reached. If a no is
returned at 594, the CBT 12 proceeds to step 596, to
display appropriate error message, and increment the error
count, and loop back to step 590. Alternatively, if the
number of incorrect answers reaches its limit, an
affirmative answer is returned at branch 594, and the
program proceeds to display correct answer at step 598.
Instructional playback 28 then loops back to step 590, and
can be exited by returning a yes at branch 592 which leads
to return 600.

d) Proficiency Playback
In proficiency there are two error counts -- one
to test number of errors on any one item and one for
testing the number of errors on the total exercise.



,',, .. ', ? :~
... .. ~ .. .. ... ~.. . . ... .
. , .. .- ;. .~
- .. . . . . ..
: . .
,. - . .

WO91/00575 PCT/US90/03878
- 65 - 2 ~ ~0 ~

Exceeding the maximum on either aborts the exercise. The
first case is to protect against the user being stuck on a
subpage forever if he is unable or unwilling to find the
correct answer.
With regard to FIG. 27, detail is shown of step
proficiency playback or test mode 30. -The flow proceeds
to branch 602 to see if a type-in record exists. If an
affirmative answer is returned, the CBT I2 proceeds step
604 to get and test type-in. Thereafter, the CBT 12
proceeds to branch 606. If it is not the correct answer
at 606, the CBT 12 proceeds to branch 608 to ask if this
is the first error made in this selection. If a no is
returned, then the CBT 12 proceeds to branch 610 to ask if
the error count is the maximum for this item. If a yes is
returned at 610, the logic proceeds to quit 616.
Otherwise, at branch 610, the CBT 12 proceeds to step 614, --?
to display an appropriate error message and increment the
item error count. The logic then loops back to step 604.
At branch 608, if a yes is returned, the logic proceeds to
step 612 to increment the maximum error count. Only the
first error on an item increments this exercise error
count because an error on a particular selection should
only count as one error in the exercise, even though there
may be multiple errors made on that single selection. The
program then moves to step 604 to continue looping.
However, if a no is returned at branch 602 or a correct
answer is returned at 606, the CBT 12 proceeds to branch
618, to check if the maximum error count has been
exceeded. If it has, then the CBT 12 proceeds to quit
616. Otherwise, the CBT 12 proceeds to step 620, to test
the action key for the function key or pointer hit
required to advance to next page. This step leads to
branch 622 to verify the user input as correct. A
negative answer returned at this branch will lead to
branch 624, to check if this is the first error of this
selection. Again incrementing the exercise error total
only once but allowing, in branch 632, for more than one
error on the item's specified error count. If a no is




:

.
,:. :

WO91/00575 PCT/US90/038
2~ 66 -

entered, the CBT 12 proceeds to branch 626, to check the
error count max for this item. If a no is again returned,
the CBT 12 proceeds to step 628, to display the
appropriate error message, increment the error counter,
and then loops back to 620. Alternatively, if a yes is
entered at branch 624 the CBT 12 proceeds to step 630, the
maximum error count is incremented and then moves to the
test at branch 632 of the max error counter. If a yes is
return from either branches 626 or 632, because the user
has exceeded either the max allowed item or exercise
errors, the flow leads to quit 616. However, if a no is
returned at step 632, the CBT 12 loops back to step 620
via step 628. This looping is exited at branch 622 by
receiving a yes when a correct action key is entered, to
lead to branch 634. At branch 634, the last record flag
is checked to see if the end of the exercise has been
reached. If it has not, the CBT 12 proceeds to return
636. Otherwise, the CBT 12 proceeds from step 634 to
calculate and display score at step 638, before also
ending at return 636.

3. Print Exercise (Page 1 - F5)
Printing an exercise calls the playback 22
routine with some special flags set. The exercise will
flash on the screen while printing, which is like the
automatic playback 24 in that the system advances through
the exercise on its own.
When F5 is selected off the author menu 20 the
CBT_Character_Trap function evaluates the keystroke. In
this case, it ends up calling a function to handle page
one activity and that translates the F5 to a 'P', which is
interpreted in CBT7.C in the page 1 routine that handles
the selections. This translation is to preserve an
original implementation.
The flags are then set (p_Print_All is set TRUE,
p_Dont_Print set FALSE, p_First_Print to TRUE,
p_Modify_Mode to TRUE, p_Repeat_Playback to FALSE, and
p_Stop_Each_Screen_SW to TRUE), and then reset to FALSE



'' : : :,,,
. :: ,. , .: . ":- , , ,:
, : . : : :: , . :. :
.: , . ,: . :

: ,

W091/00575 PCT/US90/03878
- 67 ~ 20~ 7

before starting the printing. After these flags are set
PPlaybck is called.
The exercise is loaded and the initialization
. function P_Play_Init will then set additional flags if
p_Print_All is TRUE. These are p_Start_Page_Nbr as 1,
p_End_Page_Nbr as 999, p_Wait_Each_Char_SW as TRUE,
p B_F_Number as 10,000 (this is to assure that the logic
goes to the end because this is one test of whether the
user has finished). The logic does reset
p_Stop_Each_Screen_SW to FALSE.
Then beginning the loop to put up screens, with
the switches set so the user does not stop at each screen,
screens keep on displaying. P_Move_3 will actually test
p_Start_Page and p_End_Page and, if they have been set and
meet the test, a print is required and the logic calls
p_Print_This_One.
In the print routines (in CBT14.C), the error
screens, if any, are read into p_Scr_Buff into fixed
locations such that if there is a selection error it will
always appear at a certain row on the printed page, a
typing error at the following rows, and finally the page
itself. Each page is printed with header information.
FIG. 28 details the print step 42. This step
starts at step 640 and prints the screen on the printer
device. Thereafter, the CBT 12 checks to determine if an
error message exists (i.e., was there data in the error
buffer) at branch 642. If there is an error message, the
error message is also printed by means of step 644. If no
error message is determined at branch 642, or after the
error message has been printed at 644, the CBT 12 proceeds
to typing buffer 646. From this branch, a yes response
leads to step 648 which prints typing buffer information.
Thereafter, or if a no is returned from branch 646, the
CBT 12 proceeds to return 650.




.
.... . :


..
- . . . : . :

WO91/0057S
PCT/US90/038
68 -

4. Modify (Page 1- F4)
To modify an exercise by selecting F4 off the
page 1 menu, information on any individual screen can be
changed by typing in new information. Colors and graphic
attributes may also be changed. The expected location of
the pointer hit, the function key needed to advance, or
any error messages may also be changed.
By selecting this option, the user wiIl set the
p Modify_Mod2_~l to TRUE, p_Stop_Each_ScYee~ SW to TRUE,
p_Repeat_Playback to FALSE, and p_Select_Time will be set
to zero. The user is off to PPlaybck.
When the user modifies an exercise, he is
frequently returned to the control loop for the next
action unless one of the "hurrying" situations has been
specified (e.g. the END key -- see below). It is a full
step-by-step process. Even if advancing in a hurry, each
screen mode will be flashed onto the screen and eventually
saved as the new file. Recall that the screen is the real
data and modify will always rewrite the file if the user
advances all the way to the end (an ESC key will exit
without saving if done before the end). The user can
enter modify mode and go through to the end without change
and have the same exercise as before, but it will still
build the new file along the way and save it (see
subsequent discussion regarding the .100 file).
There are four "modify states" which describe
the type of page being displayed. The basic page is the
raw page (R). If there is typing, the typing error
message state (T) is next. The selection error page (B)
is the more normal second mode to appear. Any extra edit
paqes would show up as (E). For the purpose of talking
about pages, only an R type increments the page counter
with the others being subsets of that R page.
The three display functions will put the screen
up, but in modify 44, P_Display_3 must also deal with page
numbers and the row and column location of the cursor.
The logic is here that determines whether the page number
needs to be incremented before display. In addition, this



: . . : . :, . ~ ~ , : ;

. -, ., , ,,; . :
: . . . . .

WO91/00575 PCT/US90/03878
--69 2 ~ f1~ ~

function also tests whether the page number has reached
the end point of the go forward command (if end page is
greater than the current one the logic keeps going).
In P_Save_l, deleting screens (and the delete
part of a replace) are handled by not writing the screen
to the .100 file. Keep in mind that when a screen is
deleted information about the prior screen is also
deleted. That information must be saved to pass to the
first screen that follows the one(s) being deleted.
P_Move_l leads to the selection error mode. If
there is such a mode for the screen and the user is
stopping at each screen, the user will return to the
control loop with p_Play_Int_Code equal to two for
returning back to the next function.
P_Mo~e_3 handles the print test -- recall that
all printing is done like a hurrying modify 44 mode. If
the page falls between the start and end page numbers, the
page is printed.
QSCRs have no error messages so P_Move_4 kills
them if they were found. If the last record is reached,
the logic will get the ENDOFEXE.SCR, a screen-to inform
the author that the last record has been reached from the
disk.
- - Generally, modify 44 does not-involve selection
testing in any way so the P_Play_Sel and P_Proceed
functions have no real impact.
- As to the keys hit to affect the way modify
works, the keys and their actions are found in CBT2B.C.
If advancing by using the F9 key, one will
advance one modify state at a time, seeing any error and
extra edits screens.
If F10 is depressed, the system will be advanced
through any error and extra edits to the next raw page.
The F10 key activates a flag, p_Speed_Modify, that will
keep the user going until the page is a raw page, at which
time the flag will be reset to FALSE and the logic will
stop at that display and wait for input again.



.. .
,, :, , ' ' :
..

: , ,. . :

.

WO91/OOS75
PCT/US90/038
' - 70 -

If the END key lS depressed, the logic will be
put into a hurrying mode which is like a fast automatic
. .
display where the screens will all fly by until stopped or
until the exercise reaches the end. A '+' or ESC will
stop the hurrying. When END is depressed, it sets
P_Play Int_Code += 50 and p_End_Flag to TRUE. Then, in
playback, p_Stop_Each_Screen_SW becomes FALSE and
p_B F Number is set to 10,000 to assure that the logic
will head toward the end.
Insert and Delete have word wrapping word
processing implications depending on the borders
encountered -- word wrapping uses the discovery of a box
character or the borders of the screen as the wrap border.
Two control key combinations can be used if the
screen being modified is a 40-column screen. Control-V
will center that 40 column screen in 80 column mode (a
centered reduction). Control-L will take the screen and
reduce it and place it on the left side of the screen --
i.e., the 40 columns in 80 modes takes the first 40
characters of each line, leaving the other 40 for
instructional data.
F2 will toggle the options menu 52.
If F6 (or Shift-6) is hit, the logic will be put
into color/ASCII 54 mode where the color or graphic
attributes can be changed and boxes can be built. This
key toggles to turn on and off this mode (although ESC
will also turn this mode off). The last line of the
screen will have a bar which, when F6 is hit, allows
` shortcuts for the color, graphic, or window options. For
example, C may be hit to get the full color chart
displayed.
Selecting F5 will bring up the light pen window
which allows a change in the location of the selection
that should be made to advance from the raw page. This
~5 information will be the row and column of the pointer
device hit if the information is within the valid screen
rows on a page. Currently a 25 as the row indicates that
the action can be a function key and the determination of




~ ~ '' ``-:.' .~' :' . : . .

WO91/00575,,,, PCT/US90/03878
- 71 -
2Q~8~.~ .. :.~ .
which key is found on the window and placed into the
column specification. Note also that F5 can only be used
when in selection error mode since the information it
saves is, as noted before, information about the record
before -- the raw page. For display purposes, the row and
column are incremented by one so users can see the count
begin at one, not zero, for the top line. This is also
the case whenever the cursor row and column are shown on
the screen.
When modifying an exercise, the letter M will
appear in the lower right hand corner of the screen. The
letter M is put there by calls to Pchangec.
P_Blink_Marker handles putting into line one (actually
line zero) the page number and the modify state name.
P_PutRC puts up the row and column location of the cursorO
Modifying is at the heart of the system because
it is what allows pathways to be turned into planned,
organized exercises.
FIGS. 29-34 provide a more detailed description
20 of the modify 44 subsystem of the CBT 12. FIG. 29
provides a flow chart of the overall-structure, logical
functions, and sequence of steps of modify 44, and FIGS.
30-34 describe in further detail various subparts of
modify 44.
Modify 44 uses a .100 file for the screen data.
Therefore, to modify requires "rewriting" the file from
start to finish. When proceeding through the .000 file in
linear order, and screen to screen, another copy of the
screens is being written to a newly opened file which has
the same name but an extension of .100. At the end of the
modify 44, the .100 file has all of the screens with any
changes. The original .000 file is then replaced by the
.100 file which now becomes the exercise.
Because of this, the flow is structured to go
forward in modify 44 mode. However, some liberties have
been taken with repositioning the original file and the
.100 file in multiple edit mode. This involved
repositioning the pointer in the .100 file and starting


.,- ; ,, ~ -;

WO91/0057~ PCT/US90/038
~ 72 -
2~
the linear write. For example, an insert might add
several screens to the .100 file and then have the user
says no on saving the insert. This requires the pointer
to be moved back so that next write will overwrite the
beginning of the inserted material. Since a last record
is written, effectively an end-of-file marker, it will not
matter that there is additional material in that .100 file
from an aborted insert that did not get overwritten.
The linear "rewrite" is also the reason that all
information passes from the .000 to the screen and then to
the .100 file. Hence if choosing to modify and then
hitting the END key advances to the end, all the .ooo
screens will flash on the CRT. Another key reason for
this is that the modify routine will "correct" some
deficiencies that might have occurred in processing a
file. For instance, if an exercise screen was turned into
a QSCR with an error message, the next modify would
recognize the QSCR and skip the error message display.
Without the display, no error record is written to the
.100 file and hence the file is cleaned up.
FIG. 29 begins at entry point 44. The initial
step 652 of modify 44 is to wait for input from the user.
At branch 654, the program checks for the status of the
options menu 52. If the options menu 52 is active, the
program enters options menu mode 52, as is more fully
discussed below. If the options menu 52 is not up, branch
656 checks the status of the options menu toggle key. If
the toggle key is in the active position, modify mode 44
proceeds to step 658 to turn on the options mode menu 44.
After the options menu mode 52 has been turned on, the
logic returns to wait for more input at step 652.
Returning to branch 656, if the menu toggle key status is
not obtained in the options menu mode 52, the program
proceeds to branch 660 to check the status of the print or
forward flag. If the print or forward flag is set, the
program moves on to branch 662 to see if a stop key or
stop page has been reached. If this is the case, the
program then returns to the wait for input step at 652.




.: , :: . .................. : : ::. ::. . .,,:.:. :

~. . :. . :
- ' ~ ::,

WO91/00575 PCT/US90/03878
~ _ 73 _ 2~

Otherwise, the program moves on to branch 664 to see if
printing is desired. If the answer-is yes, the program
moves on to step 666 and prints a page or pages, as per
the user's request. However, at this point this mode is
processing one page at a time in-a loop so that the first
page is printed, and, if more pages exist to be printedt
the flag for print or forward has been set. Printing
stops when the flag is turned off again. `:Next, the
program proceeds to save the printed screen or screens at
step 668. If the response to the query at branch 664 was
no, modify 44 skips the print pages step 666 and proceeds
directly to save screen(s) at step 668. Once the
screen(s) have been saved, modify 44 exits and returns at
670 to the point from which modify was entered.
Returning to branch 660, if the print or forward
flag was not set, the program continues to branch 672,
where the program checks the status of the page advance
key. At this section, the logic is testing for keys. If
the key struck is the page advance key, that key will skip
the error modes and go to the next basic page. There is
also a key for advancing to the next mode which moves from
the basic page 47 to selection error 48 or, if in-
selection error, to typing error, if there is one. The
mode advance continues through the exercise one mode at a
time. More specifically, if the answer at branch 672 is
positive, the program moves on to branch 674 and checks
whether the multiple delete 48 or replace 52 modes are
active. If the reply is yes, the program exits at 670
from modify 44 and returns to the point from which it was
called. If the status at branch 674 is negativej the
program moves to save 676 where a screen is saved before
returning through exit point 670 to the point at which
modify 44 was entered.
Returning to branch point 672, if the test for
the page advance key was negative, modify 44 moves to
branch point 678 where the status of the mode advance key
is checked. If no, the program moves to step 696 to check
the color/ASCII toggle key at branch 696. Otherwise, the


~ .. . . . . -. .



, ~ .

WO91/00575 PCT/U59-/038

~ 74 ~
CBT 12 moves to branch 680 to check for a multiple mode.
Delete, save, replace, etc., can be for more than one page
and hence when selected, the user is placed into multiple
mode. .This mode is ended by hitting the mark key and
appropriate actions are then finalized. If the response
is yes, the logic moves on to branch 682 to check for `
multiple delete or replace 682 modes. If the answer is
yes, the program leaves modify 44 through exit point 6700
Tn the alternative, the pr~ n~ m~v~s ~o s~ep 684 which
saves screen(s) and advances the page. Thereafter, the
CBT 12 exits modify 44 through point 670.
Returning to branch 680, if the program is not
selected to run in multiple mode, it moves on to branch
point 686 to check for an error message. If an error
message is desired at branch 686, the program checks to
see if the error mode has been completed. If it has not,
the logic advances to the selection error mode 48, where
the error message can be modified. After the execution of
the selection error mode in step 48, the program returns
to its original wait for input step 652. If the response
at branch 688 is positive, or the status at branch 686 is
negative, the program moves on to branch 690 to see if the
typing error-mode is to be selected. This is a routine
for editing a typing error message. If the response is
positive, the program moves to branch 692 to check if the
typing error mode has been completed. If the program has
already modified the error message, for this screen, the
response is no, and the program moves on to step 50.
After executing the typing error mode of step 50, the
program returns to the wait for step 652. However, if the
response at branch 692 is positive, or the response at
branch 690 was negative, modify 44 moves on to step 694.
At step 694, the program executes a save, and then exits
from modify 44 through exit point 670.
Note that in an exercise, there is the basic
page, and usually a selection error mode 42 that allows
editing the error message that will be displayed during



' ~ '- . .:



, ::

WO9!~00575 PCT/US90/03~78
_ 75 - ~ $ ~-

playback 22. The typing mode 50 allows changing the
typing that the user inputs or any typing error message.
Returning to branch point 678, if the mode
advance key status is negative, the modify 44 moves on to
branch point 696 and checks the status of the color/ASCII
toggle~key. If the key is toggled on, the modify 44 moves
on to step 54 in FIG. 29 and enters the color/A5CII mode.
After executing step 54, modify 44 returns to the original
wait for input step 652. If the c~lor/ASCII key is
toggled off, the modify 44 moves on to branch 698 to check
if the escape key has been struck. If it has, the modify
44 moves on to step 700 and verifies the particular desire
triggered by the escape key. Modify 44 proceeds to branch
702 to see if the escape has been verified.- If the answer
is yes, the program executes a quit through exit point
702. That is, at this point, the program ~uits modifying
the exercise and restores the exercise as it was before
the user started, and returns the user to the menus.
Returning to branch 698, if none of the escape
keys were struck, modify 44 moves on to branch 706 to
check the status of the LPW action key. If the key is
toggled on, modify 44 proceeds to step 58. The LPW mode
58, as in FIG. 2, is entered. After the execution~of step
58, modify 44 returns to its original wait for input step
652. If the light pen toggle key is off, from branch 706,
modify 44 proceeds to branch 708 to check if a character
has been typed. If no character has been typed, modify 44
returns to the wait for input step 652. If a character
has been typed, however, modify 44 moves to step 710 which
echoes the character typed at the cursor location on the
screen. Once this has been accomplished, the program
returns to the wait for input step 652.

a) Options Menu
FIG. 30 describes in further detail the
functions and logical progression of the options menu mode
52. The options menu mode 52 in FIG. 30 is entered from
step 52 in FIG. 29. FIG. 30 describes the various




. , .

WO9!/00575 PCT/US90/038~
20~89;1~ - 76 - ~
optional functions the user may employ to do editing. In
general, this part of the program presents the user with a
menu of various options and then accesses the various
functions as the user chooses them. The portion of modify
44 described in FIG. 30 allows the user to enter an option
key, then executes the function triggered by that key, and
returns to subsystem-modify 44.
Most of the options available to the author
while in modify mode 44 or in screen utility mode 56 can
be found on this separate menu called the options menu 52
which is displayed on the bottom two (if 80 column) or
four (if 40 column) lines of the screen. This menu is on
the screen when p_Err_Mess_Select is set to TRUE. In
modify mode 44, if the user advances through the various
stages past the raw page to the error modes, the user will
have the error message and options menu 52 pop up at the
same time.
The function P_Err_Mess_Options in C8T3.C
controls the menu; with TRUE as a parameter it will put it
up and FALSE will take it down. Along the way either the
selection error window or the typing error routines will
be called (depending-on whether p_Type_Err_Mess-is TRUE or
not) though if no error awaits those routines will do
nothing. The p_Do_Authors_Menu and p_Undo_Authors Menu
control here and they both save and display the old area
of the screen displaced by the menu and windows.
The menu can be light pen selected or chosen
from a keyboard input of a plus followed by the letter of
the choice as shown in the menu. The plus part is handled
by the versatile variable p_Select_SW which is set TRUE
when a plus key is hit. Light pen selection will set that
variable TRUE and send the character in the parenthesis
down just as if the key had been hit on the keyboard. (The
select switch is used for other options like page one
choices where an F1 is turned into a plus one and
processed. The P_Select_ SW variable stops the logic when
the user is in modify and hits the END key -- this




. :: . :,- . :: ..::.. :. : ~
,.:,:- :-: :
: ~,, - - . . . -. : ~

WO91/00575 PCT/US90/03878
77 ~ 2~08~
variable must always be reset FALSE to avoid having
unexpected results when a key is hit).
P_Err_Mess_Options will do a little bookkeeping
before handling the options selected. P Err_Mess_Options
tests the printer, sets off p_Delete_Screen_SW if on and
the next key was not an F to verify the delete, and tests
some conditions against the EndOfExe screen (the last
screen message displayed in modify mode).
There- are five op~io~s ~hat are allowed in both
modify 44 and screen utility mode 56 -- L, R, S, P (though
it will only do the one page showing in ScrUtil) and F.
The other options are allowed only in modify mode.
Option P is for printing, which will evaluate
the start and end pages based upon the input entries
sitting in those fields in the menu. The function
P_Setup_No_Print_Pages will see the start and stop pages
and p B_F_Number is set to p_End_Page Nbr. The flag
p_Stop_Each_Screen_SW is set FALSE so the playback will
continue on until the condition is met (i.e., the end page
is reached). Then the p_Play Int flag is set to four and
the menu is taken off the screen.
Option L is the list directory which will
display a directory based upon the file specification in
the lower right hand corner of the options menu 52. A
flag will be set indicating a directory is showing
(p_Author_Dir_SW) and the calls to the directory writing
functions in CBT7.C will be made. Note that the file
specification allowed is based upon who the user is
(developers can do anything but authors are restricted to
TDS and 000 files) and can include wildcards (PR*.TDS is
all TDS files beginning with PR and that is all that would
be displayed). The name is filled in and conditions
explored in P_Setup_File_Name in CBT3.C.
Option R is for replace and will act differently
on ScrUtil then modify mode. The replace in Single
Screen Utility 56 is really more like an import a single
screen facility in replacing whatever was active or
showing. The function insert_Single from CBT18.C is - -~



. . : .. .. ..
.. .

; ~ ~ : - . - ,
:. ~ . .:: ,, ,:
.. :, . .. .. - . .

WO9~/00S75
PCT/US90/038

2 ~ a~ 78 - /
called to display the file (screen) indicated. In modify
44, any replace, whether single or multiple, will follow
the deletion of other screens. Thus, at this stage, there
is a verification that the replace file exists, temporary
pointer$ are set to the existing file to restate the
condition if the user decides later not to accept the
replacement, and there is a return to playback 22 after
taking off the options menu 52. Replace is like a delete
followed by an insert. In modify 46, replace will act on
an edit_mode of R and simply not write the screens until
the user indicates the stop place of the delete (using
option M which follows).
Options S, or save, acts upon the file name
shown in the lower right corner of the options menu 52.
If there is a single screen extension (like TDS)
identified by the user, a simple Save_Screen call is made
and the save is finished. If on ScrUtil this is the only
save possible so any invalid file extension would cause a
return. For multiple saves, the edit_mode flag is set to
S, the output file open using open_edit_mode_save_file in
CBT18.C, and the p_Play_Int set to four for a return to
playback 22. While in S edit_mode copies of the screens
will be written to both the standard .lOO file and to a
file for the new save. The M option will close out the
save.
Option F, the delete scre~en option, allows the
user to flag a screen for deletion. The first time
encountered, F sets the p_Delete_Screen_SW flag to TRUE.
It must then get another plus F or light pen F to actually
call the function P_Delete_Screen. Any other key will
reset the flag to FALSE and requires the user to select F
again to start the delete. If delete, the directory will
be reset (through a recursive call to this function with
an L parameter).
Option ~ allows going forward in the exercise in
modify mode. There are two options -- a number that will
bring up to that page number, or an F# where # is the
number of pages to be advanced (i.e., the user is on page


.: . . , : : . .
; ;,, , . . :.


,:, ,,; ,

:

WO91/00~75 PCT/US90/03878


six and, to go forward five pages, enters either F5 or
11). The function P_Setup_No_B_F_Pages is called to set
the ending page. p_Stop_Each_Screen_SW is set FALSE so the
exercise will run until the desired page (the ending page)
is reached. The options menu 52 is taken off and-the
variable watched is p B_F_Number. -
Options 0-9 and X will fall through into the
insert section for a single insert of a screen. The
character will be placed in front of the word NEW to call
a file called 4NEW.SCR for a blank 40 columns screen and
is also +4 on the menu, or 8NEW.SCR for an 80-column
screen which is set when the filename is blank - see
function P_Setup_File_Name. In essence, p_Make_QSCR is
set to the character and insert_single will then be called
in the insert option (see Option I, below ). If there is
a p_Make_QSCR value that file will be called through the
p_Get_Or_MAKE_QSCR function and the screen will be
displayed.
Option I, insert, will be selected by +I but the
first part of the code can come from the 0-9 and X options
above because those cases fall through to insert. If
there is no proper single file extension in tXe file
specification found in the lower right corner of the
options menu 52, or it is not on a raw page, the system
2S will return. Otherwise, insert_single in CBT18.C handles
the insert. This inserted file is not a part of an
exercise until the program moves past, where the file is
written to the .100 file. In order to delete or save that
screen and any possible changes to the file, the edit_mode
value of I is retained after the insert. There is also a
need to reset the p_Record Type at the EndOfExe screen if
the user inserted at that spot so that the end screen will
be redisplayed after the inserted screen is saved. A
multiple insert will save the existing file pointers (.000
and .100 , though if the .100 doesn't exist yet, a value
of OL is set) and then calls insert_exercise in CBT18.C.
Once completed, the user will verify that the insert is




;: - , . ,: , ;
,: : :.. :- : . . . .
. ,. :: . :. .. . ~ . : : .. : .. .

WO91/00575 PCT/US90/03878
~;
% ~ ; 80 - ~ ~

accepted and if NOT the files will be reset to their old
state.
Insert_Exercise wrote the inserted screens to
the .100 file and in a manner not visible to the user. In
addition, the screen that was displayed when the insert
was selected will still be the one on the screen even if
the insert is accepted. The value of p_Play_Int_Code is
dependent upon whether the insert is accepted or not, and
in all cases the options manu ~2 is then~-~e~ved and
exercise modification continues.
Option D, delete, will always require an M
option to indicate a stopping place so there is not single
or multiple. The edit_mode flag is set to D and
p Speed_Modify set to true so the user can only advance
and thereby delete from raw page to raw page. The screen
up at the start will be the first deleted. A ~D followed
immediately by +M will delete just that screen and any
affiliated screens (error and typing and extra edit
screens). If the edit_mode is I on entry, a single screen
has just been inserted and only in this case will a +D by
itself actually delete (there is no advance and no reset
since the screen is not "real" yet -- the program just
reset what was in ptbuff[] from the last real screen of
the exercise).
Option M, the mark, indicates the end of a
multiple edit action -- replace, save, or delete. If
edit_mode is R a number of .000 pages have been 'skipped'
in the .100 file and the new single or multiple file will
be inserted (using insert_single or insert_exercise). The
page number for display must reflect the pages not written
and the new pages written. If a user decides not to do
the replace at the end, the pointers saved before are used
to reinstate the condition before +R was hit. If
edit_mode was D the header information found in bytes
7-8-9 of the first screen deleted will be placed into the
header of the first screen that is NOT deleted (the one
which ~M was hit from) since this information is always
about the screen that precedes and the current one is now `-

WO91/0057~
PCT/US90/03878
~,'.:',......................................... ~
- 81 - 2 ~ r

the one following, not the one(s) deleted. In addition,
the page count is adjusted. Finally, if the edit_mode was
S, a final P_Saveb call with parameter X is made so that
a last record is placed at the end of the screèns being
saved thus far. The system then continues processing the
current screen.
The edit_mode variable is used primarily in
CBT3.C and in the playback 22 functions to control
multiple insert, save, replace, and delete (although it is
used briefly in a single insert and a ScrUtil replace to
deal with being able to undo the action). Simplistically
speaking, an S will be read by the playback 22 routines to
write a second copy of the output file starting from where
the S was hit until an M is hit. A, D, or R will flag the
situation so that when it comes time to write the screen
to the .lO0 file the write will not be done and an
incrementer of the number of times (or pages) this is done
for is made so an adjustment can be made. In the case of
D this is all that is required and an M finished things.
With an R, the code now differs in that an insert is now
required!as the second half. Almost all edit_mode and
multiple routines not part of the original CBT 1.0 can be
found in CBT18.C.
- To properly reinstate the condition as it was
before a multiple in the case of the user saying that he
does NOT accept the action, the p_Tempbuff_Full flag must
be set to FALSE to begin staging from the pointer
indicating the active record. p_Tempbuff[2] must also be
set to zero and p_Err_Mess_Waiting to FALSE, to avoid
adverse impacts on how the restaging is done. The page
number is then decremented and will be incremented again
when the screen is restaged.
Because delete, insert, replace, and save all
have different actions and are caught at different places
in the loop, there are some localized impacts in both the
accepting and rejecting of any of those options as an
attempt was made to keep from making any real changes in
the heart of the playback code since it had proven stable.

WO91/00575 PCT/US90/038
; - 82 -
2~
P_Setup_File_Name is used in the options menu to
weed out certain improper conditions and then to set up
both p File Name file which is the file specification used
for the processing and p_Save_File_Name File which is the
variable used for what is displayed in the lower right
corner of the options menu 52. There are checks for DOS
characters (those allowed are A-Z, 0-9, _ , -, and blank)O
If listing directories the asterisk and question mark are
allowed. I. not a developer the user can only have files
10 with TDS or 000 extensions and 000 is allowed only if the
option is R, I, s, or L. File names like .EXE or .COM are
not allowed. This function also handles the list
situation if a name is blank the function substitutes an
asterisk so that all files will be listed.
The cursor movement on the options menu 52 is
handled with the Cursor Table assignments with functions
like P_Wrap_Table_Set in CBT3.C providing the start/stop
values for p_Cursor_Table[]. These table values are used
as offsets for positioning the cursor.
- In FIG. 30, starting from entry 52, the program
reads an option keystroke entered by the user at step 712.
The input keystroke is examined to determine which of the
various option keys the user has entered. Branch 714
checks to see if the option mode toggle key has been
pressed. If the option mode toggle key is the one that
has been entered, options menu mode 52 moves to step 716
which turns off the option mode. The logic then exits
through return 718 to modify 44 at step 52 in FIG. 29. If
the input key was not the option mode toggle key, the
program moves on to branch 720, which checks if the
program is in multiple edit mode. If the answer is yes,
the program moves on to branch 722 and the part of FIG. 30
that describes the multiple mode functions. Branch 722
checks to see if the input is the marked end key,
whereupon the program exits through point 718 and returns
to modify 44 as described above.
If the mark end key was the input, the options
menu mode 52 moves to branch 724, which checks to see if




: ~ ::, ~ -, ; : : :

W O 91/00575
PC~r/US90/03878
~ . , A 8
2 ~ 3
the function is the save mode. If this is the case, the
program moves to step 726, where the save file is closed
and the multiple flag is turned off. The program then
moves on to step 728 and verifies multiple command, which
is the last chance for the user to indicate the intent to
make this choice, and then exits from options menu mode 52
through point 718 as previously described.
At branch 724, if the option desired was not the
save mo~e, ~-he ~r~g~m moves on t~ branch 7~, which
inquires whether the desired function is the delete mode.
If yes, the program moves on to step 732, where the
multiple delete flag is turned off, and then on to step
- 734. At step 734, the verify multiple command is
executed. The program then exits the options menu mode 52
at point 718 and returns to modify 44.
At branch 730, if the desired option was not
delete, the program moves on to branch 736 and checks if
the desired option is replace. If yes, the program moves
to step 738 where the multiple replace flag is turned off.
Then, at step 740, a new file is inserted, and, at step
74?, the verify multiple command step is executed prior to
a return 718 to modify 44. If the program is in multiple
edit mode at branch 736, the mark end key has been pressed
at branch 722, but the mode is not save, delete or
replace, the program automatically exits at point 718 and
returns to modify 44.
At branch 720, if multiple mode is not selected,
options menu mode 52 continues to branch 744, which also
checks if the mark end key has been input. If the answer
is yes, the options menu mode 52 returns through exit
point 718, as previously described, i.e., to modify 44.
If the mark end key has not been pressed, the program
moves on to branch 746. At branch 746, the program
examines the key entered at step 712 and asks if it is the
exercise statement key. If the answer is yes, the program
moves to step 748 where an exercise statement template
screen is inserted. An exercise statement template screen
is just a special screen that outlines the objectives of

- . .


- ~ ;. :, :, ~ , . , : ::

. . ~.:
. . -:. . . .

WO9l/00575 PCT/US90/03$78
84 -

the exercise for the student. The template screen is
inserted at the spot in the exercise that has now been
reached (i.e., the student is advancing in the exercise
page-by-page). After step 748 has been executed, the
program exits from the option menu mode 52 through point
718, and returns to modify 44 at point 52.
At branch 746, if the input does not match the
exercise statement key, the program moves on to branch
750. At branch 750, the input is checked to see if it is
the blank 40 character screen key. If yes, the program
moves to step 752, which causes a blank 40 column screen
to be inserted. These inserts are being made into the
tutorial screen file after being "moved" over to make
room. Modify 44 reads the old file and then saves to a
new file. Thus, insert is actually just writing to the
new file 10. Then, when the next old file screen is read
- and written, the new file 10 is located in sequence after
the previously inserted file 10. At the end, the new file
10 is given the name of the old file, thus deleting the
old file 10. Once step 752 has been executed, the program
exits the-options menu mode 52 through point 718 and
returns to modify 44 at point 52.
At branch 750, if the input does not match the
blank 40 character screen key, the program moves to branch
754. At branch 754, the input is checked for a match with
the delete screen key. If the delete screen key has been
pressed, the program moves to step 756 to carry out the
required function. Step 756 sets the multiple mode delete
flag and saves the current pointers. The program then
moves to step 758 where the exercises advance to the next
page. After step 758, the program exits the options menu
mode 52 through point 718 and returns to modify 44.
At branch 754, if the input key is not the
delete screen key, the options menu mode 52 moves on to
branch point 760 and asks if the input key is the replace
key. If the answer is yes, the options menu mode 52 moves
to step 762 to set the multiple mode replace flag and save
the current pointers. After this is accomplished, the




,,: ,' , ' : ' ~ ' ;; , ' '

WO91/00575 PCT/US90/03878
~ - 85 - 2~ 91

options menu mode 52 moves to step 764. Step 764 tests
the validity of the replacement file. At branch point
764, the options menu mode 52 asks, is the replacement a
valid file. If the answer is yes, the program exits from
the option menu mode 52 through exit point 718 and returns
to modify 44 at step 52. If the replacement file is not a
valid file, options menu mode S2 indicates this and
returns to require reentry.
At bra~c~ 760, if the input key is not the
replace key or a valid file, the options menu mode 52
progresses to branch point 768. Branch 768 checks whether
the input key is the save key. If it is, the options menu
mode 52 moves to branch 770. Branch point 770 checks to
see if the file name entered, that is the destination file
for the save, is a valid name. If it is, branch 772 asks
whether the file name is an exercise file name. Exercises
are files with an extension tacked onto the name (.000).
However, the user can automatically save single screen 774
which are not exercises but which are files. If the user
20 saves using a single screen name, it îs not necessary to - --
set a-multiple flag. If the answer at 772 is no, the
program moves to step 774 and saves the screen in the file
named at branch 770. After the screen has been saved, the
program exits from options menu 52 through exit point 718
and returns to modify 44. If the file name examined at
branch 772 is an exercise name, step 776 sets the multiple
mode save flag. From step 776, the program advances to
the next page of the tutorial at step 778. The program
then exits from the option menu mode 52 through exit point
718 and returns to modify 44.
At branch 768, if the input key is not the save
key, the program continues to branch 780. Branch 780
checks to see if the input key is the insert key. If the
answer is yes, the options menu mode 52 moves to branch
782 to see if the input file name is a valid file name.
If the file name is not valid, like replace, options menu
mode 52 would show the error in name on the screen. If
the file name is valid, branch 784 checks to see if the



, .~., , . ;, ~ ,~ , ; . , ::
- .: ~ ,: : " - . . :

: - . . :
:;, :- ~ :: . . ~: . .
- . : :

WO91/00575 PCT/US90/0387~8
~ ".
2~ ~8~ 86 -
input file name is the same as the exercise file name. If
not, the options menu mode 52 moves to step 786 which
inserts the present screen into the file identified by the
file name. The options menu mode 52 then exits at exit
point 718 and returns to modify 44. If the response at
branch 784 is yes, the options menu mode 52 continues to
step 788. Step 788 inserts the screen into the exercise
file and saves the current pointers. The options menu
mode 52 moves oTrt~-step 790, wller~a V~Yify multiple
operation is conducted, and after completion, returns to
modify 44 through exit point 718.
Returning to branch 780, if the input key is not
the insert key, the options menu mode 52 moves to branch
792, which checks the input to see if the list directory
key has been struck. If yes, the options menu mode 52
moves to step 794 and builds a directory from the file
specification and displays it on the screen. After the
directory has been displayed, the options menu mode 52
exits through exit point 718 and returns to modify 44.
Returning to branch 792, if the input key is not
the list directory key, the options menu mode 52 moves to
branch 796 to check for the go forward key. If the input
key matches the go forward key, the options menu mode 52
moves to step 798, which evaluates the number of pages to
advance and sets the advance page flag. After this is
accomplished, the options menu mode 52 exits through exit
point 718 and returns to modify 44 at step 52.
Returning to branch 796, if the input key is not
the go forward key, the options menu mode 52 moves on to
branch 800 to check for the print key. If the input key
is the print key, step 802 sets the number of pages to
print by setting the appropriate flag. After step 802,
the options menu mode 52 exits through exit point 718 and
returns to modify 44.
At branch 800, if the input key is not the print
key, the options menu mode 52 advances to branch 804 to
check the input key to see if it is the delete file key.
If yes, at branch 806, the options menu mode 52 asks if

:

W091/OOS75 PCTiUS90io3878
- 87 ~ 2~ ~ g~

the specified file exists. If the file does exist, branch
808 asks the user to verify the delete. This extra step
prevents any accidental deletions caused by the user.
After the delete command has been verified, step 810
deletes the file from the file directory. After the file
has been deleted or if the responses to branch point 806
or 808 were negative, the options menu mode 52 returns to
modify 44 through exit point 718.
Returning~to branch 804, if the input key was
not the delete file key, the options menu mode 52 advances
to branch 812. Branch 812 checks to see if the directory
list is up on the screen. If yes, the options menu mode
52 moves to branch 814 and asks if the key is a valid list
mover. If yes, the options menu mode 52 moves to step 820
and moves the list highlight bar. After completing step
820, the options menu mode 52 leaves at exit point 718.
If the response at branch point 814 is negative, branch
816 checks to see if the input, usually the enter key, is
to make a selection from the directory list. If the
answer is yes, the options menu mode 52 moves to step 818
- where the selected choice is put into the file name slot.
After step 818, or if the response to branch 816 was
negative, options menu mode 52 exits through point 718 and
returns to modify 44 at step 52.

b) Modifying Screens
In modify mode 46 and in screen utility mode 56,
an author can modify recorded screens or create new
screens. Once-in modify mode 46 (p_CBT_Page is zero and
p_Modify_Mode_SW is set to TRUE) or in screen utility mode
56 (p_CBT Page is four), any page can be changed using
special editing functions. The situation is that the
screen has been displayed and input is now desired. If
alphnumeric keys are typed, they will appear wherever the
cursor is and wrap around will be in effect.
The standard creation of boxes and colors and
graphics come from hitting F6 which will toggle the
color/ASCII line across the last line of the screen.


- , . ;- .: . - - :. . - : -
: : ., ~ .. , ' .... : .: . :-'-
- - ::., : , . :: ~, -
: . ,,, : . .: ,:,. .. .: , .
.. :. :: . . ;,
~ : .: ~, : ::, ':: :., .
: , : . . - :: . :: :
.: - : , : .

WO 91/00575
~ PCT/US90/03878
~ 8~ ~ : 88 - ~
The flag p_Clr_ASCII_SW will tell the user if
the color/ASCII mode, as F6 is known, is on. With that
area there are two flags for when the user is changing
color or ASCII graphics characters, p_Color_Mode and
p_ASCII_Mode, that determine whether the respective window
is on the screen.
These color/graphic issues are toggled and
controlled with the function Pattrib in CBT4.C. This
fun-ction-ha~dles calling, processi~, ~nd leaving-
color/ASCII mode 54 although ESC or an F2 for options menu52 can also take down, restore, or leave these modes.
The current color and attribute can be found on
the first line of the screen just after the row and
column. They are placed there when the function P_Put_RC
is called. When the user is entering colorjASCII mode by
hitting F6 or Shift-6, the 25th line display is shown
which has the current most logical colors displayed with
the numbers 0-7 along with the letter key codes for other
options like C to see the color chart and S for
single-line box or D for double-line box. With this line
up, the keys would be handled by.Pattrib as indications of
the action to take; If the key is C the function will
call P_Display_ASCII with a C parameter to bring up the
color chart, set p_Color_Mode, and await further action
above. If a G it will call p_Display_ASCII with an A and
put up the graphics chart, set the p_ASCII_Mode, and
return for action. Note that a parameter of R is then
used to restore the old screen underneath the window when
the user has finished making a selection. Note also that
it is currently possible to make a choice outside of the
displayed window and the system will accept that graphic
or color attribute at the cursor position as the one
selected.
Most of the other options will call one of four
functions -- Psetchr, Psetatt, P_Color_Box, and
P_Line_Box. The Psetchr function sets the current cursor
location character or graphic to the current active ASCII
character code or the one reflected in the choice made



.- .. - . : : : ' . : .. ;~
~ , . ::
., - ;: ,
'- '.: ' ~

.: ,-. ~ , : : ~

WO91/0057S
~ PCT/US90/0387
89 2 ~ ~ ~ g 9 ~

from the possible choices on the 25th line, while Psetatt
will set the attribute at the cursor location to the
current color or the one reflecting the color number
selected on the 25th line. The coloring and lining of
boxes,-used in creating, painting, and erasing or removing
things related to and within boxes, are also handled in
this function. The box functions must worry about~start
and stop locations and use the upper left and lower right
corner markings to detèrmine ~he ~ s~ze-. The firs~ time
the color box function is called the row-column is marked,
and the second time will result in getting the row-column
pair to end and a box will be filled with the color
attribute from the character at the first coordinate -- an
N colors the box but a B parameter will color and blank
out the area-as well. The p_Color_Box_SW variable toggles
whether it is first time in or not, just as p_Line_Box_SW
does for the line routines. The line box function is
similar in operation with S for single and D for double
lines and an R for blank border. The S-D-R parameter is
evaluated, in effect, with the second call which actually
draws. . --~ --
Besides drawing boxes and changing colors, theuser can use other editing tools much like word processing
to put anything on the screen. There is a minimal word
wrap facility that essentially uses the border or window
characters as the begin/end boundaries for any wrapping
around while typing. Arrow keys will get the user out of
any window unless the options menu 52 is up, which is the
case when the user edits an error message window, for
example.
The CTRL-L and CTRL-V combinations can have an
effect on a 40-character mode screen being edited. The
screen mode is switched to 80 character mode and if the
option is CTRL-L the original 40 will be flush left in
columns 0-39. If the CTRL-V is chosen, the 40 are
centered (hence in 19-59). The function is
P Center_Display in CBT3.C.

WO91/00575 PCT/US90/03878
, ~,
9

c) Selection Error
FIG. 31 is a more detailed description of the
logical functioning of the selection error mode step 48 of
~IG. 30. Generally, the selection error mode 48 allows
creating and editing error messages. FIG. 31 explains how
error messages are created and modified and how the
screens containing the errors can be changed.
- From its call in step 48 in FIG. 30, the
selection er~o~ fflode 48 enters the flow chart of FIG. 31
through entry point 48. At this point, the selection
error mode 48 saves the current screen at step 822. Next,
in step 824, the selection error mode 48 displays the
error message and the options menu 52 window. Later, when
an exercise is displayed via playback 22, the error
message formed in step 824 will explain to the user what
error has occurred, and provide the user with options as
to how to proceed. When the error message in the option
menu 52 has been displayed, the program moves to step 826
and waits for an input keystroke. Once an input key has
been struck, the program moves to branch 828 to see if the
option menu error message has been displayed. If it has
not, the program proceeds to branch 830 to check the
status of the option message toggle key. If the option
message toggle key is on, the program moves to step 832 to
restore the option menu error message and return to step
826. If the reply at branch 828 is yes, or at branch 830
is no, the program proceeds to branch 834 to check the
status of the advance key. If this key has been hit, step
836 accepts the present screen as it is displayed. That
is, the user has finished changing error message or didn't
make a change. After step 836 has been executed, the
program exits the selection error mode 48 through exit
point 838 and reenters modify 44 at step 48 of FIG. 29.
At branch 834, if the advance key has not been
hit, the selection error mode 48 proceeds to branch 840 to
see that a valid option menu item has been selected. If a
valid item has been selected, branch 842 asks the user if
he would like to print the present screen. If the
..~




" ., , " , , ~ ~:
- . - :, . , . , , :

WO91/00575 PCTiUS90/03878
,f~ ~` 9 1 - 2 ~

response is yes, step 844 prints the screen. After the
screen has been printed, the selection error mode 48
returns to step 826 and awaits further input. If, at
branch 842, the user did not want to print the screen,
branch 846 and asks the user if he would like to save the
present screen on disk. If the answer is yes, step 848
saves the present screen. Once the screen has been saved,
or if the user has responded no to the screen save query,
~ïe selection error mode 48 returns to step 826 and awaits
further input. If, at branch 840, a valid option menu
item has not been selected, the selection error mode 48
moves to branch 850 and checks to see that a valid key has
been pressed. If it has not, then step 826 gets a new
input. However, if a valid key has been pressed, step 852
is where the input keystroke is processed, and the error
message is changed accordingly. From step 852, the
selection error mode 48 returns to step 826 to await
further input. The selection error mode 48 automatically
exits when the advance key is hit.
20- d) Typing Mode
FIG. 32 details the typing error modify mode 50,
which saves the current screen at step 854, which saves
what will be 'replaced' by the window so it can be reshown
or restored if user toggles into options menu 52. This
leads to the display typing error message window 856
before reaching step 858, which gets input keystrokes.
This option allows the user to 'exit' the typing error
message The CBT 12 proceeds to branch 860, where it
checks if the options menu 52 and the typing message are
on the screen. If they are not, branch 862 asks if the
key input at step 858 is the options menu 52 toggle key.
If yes, step 864 restores the option menu typing message
and loops back to get input at step 858. Otherwise, at
branch 862, the typing error mode 50 proceeds to branch
866, which looks at the cursor to see if it is in a valid
typing location. If it is not, mode 50 loops back to get
input keys at step 858. However, if it is, the typing
mode 50 proceeds to step 868 to change the type-in

WO91/0057S PCT/US90/03878
2~ 92 - ~
character by putting the input key onto the screen, and
then loops back to get input keys at step 858. However,
if a yes is entered at branch 860, the-typing mode 50
proceeds to branch 870 to check if the advance key was
hit. If the advance page or advance mode key is hit (see
'modify' keys) the user is satisfied with what is on the
screen. Thus, if a yes is entered, the typing mode 50
leads to step 872 which accepts the screen as displayed
and leads t~ return 874. If a no is entered at branch
870, the flow leads to branch 876 which checks whether a
valid key has been entered. If a valid key has not been
entered, the program loops back to step 858 to get input
keys. Otherwise, the typing mode 50 proceeds to branch
878, which allows the user to enter a value that will set
the level of matching required for the type-in to be
accepted. The author could specify that anything is an
acceptable type-in or may specify up to an exact match
with all letters exactly as intended. If a yes is
returned, the typing mode 50 proceeds to step 880 to
change level of accuracy required, which in turn leads
back to step 858 get input keys. If there is a no at
branch 878, the typing mode 50 proceeds to step 882 to
process the key as a change in typing error message
itself, that is, the key hit in step 858 was in the typing
error message box and it is used to edit the message.

e) Color/ASCII
FIG. 33 describes in further detail the
functioning of color/ASCII 54 from FIG. 2. The program
enters the color/ASCII 54 from modify 44 in FIG. 29. In
general, this function allows the user to modify the color
or graphic components of stored screens.
The flow chart of FIG. 33 begins at entry point
54. Branch point 884 checks to see if the color/ASCII
mode is already on. If it is, the program moves to step
886 and turns the color/ASCII mode off. The program then
exits from this function mode through exit point 888 and
returns to modify 44.



. : ,;, ,. , /

.. : ~. ~ , .
. .

WO91/00575 PCT/US90/03878
~ , . ~

Returning to branch 884, if the color/ASCII mode
is not on, the program moves to step 890 and turns the ~`
mode on. The program then moves to step 892 and waits for
an input keystroke. Branch 894 checks the input keystroke
to see if it is the color toggle key. If it is, branch
896 checks to see if the color mode is on. If it is not,
the color/ASCII 54 moves to step 898, turns on the color
chart, and then returns to step 892 to await further
input. If at branch 896, the color mode is on, the
color/ASCII 54 moves to step 900, turns the color chart
off, and returns to step 892 to await further input. If
the result at branch 894 is negative, the color/ASCII 54
moves to branch 902. At branch 902, the color/ASCII 54
checks for the graphic toggle key. If this key was input,
the logic moves to branch 904. Branch 904 checks the
status of the graphic mode. If graphic is on, the
colortASCII 54 moves to step 906, turns the graphic chart
off, then returns to step 892 to await further input. If
at branch 904 the graphic chart is off, the color/ASCII 54
moves to step 908, turns graphic chart on and returns to
branch point 892 to await further input. If the graphic
toggle key was not the input key, the color/ASCII 54 moves
from branch 902 to branch 910. Branch 910 checks the
input character to see if it is the box character. If it
is, the color/ASCII 54 moves to branch 912 and checks if
the box start has been marked. If at branch 912 the box
has been marked, the color/ASCII 54 moves to step 914 and
draws a box. If it has not, the color/ASCII 54-returns to
step 892, after marking the box start in step 916, to
await further input. Note that the user hits a special
key when in color/ASCII mode 54 to indicate that the user
wants to start a box with that spot as the upper left cor-
ner. Because the box is now marked, the next time
through, the box character will draw the box using the
second spot as lower right. If, at branch 910, the input
character is not the box character, the color/ASCII 54
moves to branch 918 to see if the attribute code has been
entered, and if so moves the color/ASCII 54 to step 920.

WO91/00575 PCT/US90io3878
2~ 94 ~ ~

Step 920 changes the attribute at the cursor and advances
the-cursor one space. From step 920 the color/ASCII 54
returns to step 892 to await further input. If the input
key is not the attribute key, the color/ASCII 54 moves
from branch 918 to branch 922 to see if the graphic code
key has been input. If it has, step 924 changes the
graphic at the cursor to the active graphic and advances
the cursor. After step 924, the color/ASCII 54 returns to
step 892 to await further input. If, at step 922, the
input key is not the graphic code key, the color/ASCII 54
moves to branch 926. Branch 926 checks for the
color/graphic code and if it matches the input key moves
- to step 928. Step 928 changes both the color and graphic
at the cursor and advances the cursor. From step 928
color/ASCII 54 returns to step 892 to await further input.
If the response at 926 was no, the color/ASCII 54 moves to
branch 930. Branch 930 checks for the paint code key. If
the paint code has been entered, the color/ASCII 54 moves
to branch 932 and checks the paint start point. If the
paint start has been marked, step 934 paints the marked
area with the active attribute. After step 934, the
color/ASCII 54 returns to step 892 to await further input.
If the paint start has not been marked, the color/ASCII 54
moves to step 936, marks the paint start and moves to step
892 to await further input. If the paint code has not
been entered, the color/ASCII 54 moves from branch 930 to
branch 938. The branch 938 checks for erase code. If the
erase code has been entered, the color/ASCII 54 moves to
branch 940 and checks for the erase start marker. If the
erase start has been marked, the color/ASCII 54 moves to
branch 942 and erases the marked area. After the erasure,
the color/ASCII 54 moves to step 892 to await further
input. If at branch 940, the erase start has not been
marked, the color/ASCII 54 moves to step 944 and marks the
erase start. After step 944, the color/ASCII 54 returns
to step 892 to await further input. If, at branch 938,
the input key is not the erase code, the color/ASCII 54
moves to step 946. If the color/ASCII 54 has reached step




- ~ , : ~ .;:-

WO 91/00575
PCI`/US90/03878
; '
- 95 - 2~&91

946, the input key is not a valid key within the C/A mode.
At this point, the color/ASCII 54 returns to step 892 and
awaits further input. Note that there is no space on the
flow chart that will allow an exit from color/ASCII mode
54 past branch 884, the color/ASCII toggle key. However,
in fact the logic actually leaves color/ASCII after every
', keystroke.
K. LPW
CBT 12 will react to an~f pointer hit, putting
together the row and column, but before it can act the
CBT Pointer_Trap in CBTl.C will check whether the hit is
valid to handle and/or whether the program should either
process it or not. If the CBT12 is to process a light pen
hit the user can evaluate it several ways. The CBT12 can
simply look at the row and see if it is a valid row on the
screen showing as in a selection from the exercise
directory, going on then to highlight that row's entry.
The CBT12 can take the location and begin a search to the
left top find the parenthesis and then take the character
between parenthesas as the selection, examples being found
on the.options menu 52 or on the Page 1 menu (handled by
function Plpsrch in CBTl-.C). To know what to highlight is
often a case in CBT of looking for two blanks between
choices .
Another feature comes from the use of functions
keys as pseudo-light pen hits with the row equal to 25 and
the column e~ual to the code for the desired function key.
This is how a recorded screen tells what key was hit if a
function key was hit to advance instead of a light pen or
30 pointer hit. Function keys are translated that way and
passed through CBT_Pointer_Trap for some processing on
occasion.
Light pens, mice, or other alternate devices to
the keyboard simply make for having to look at a few
35 places to see where the input came from, and evaluating it
properly. In the control loop, a pointer hit is first and
then the keyboard.


: : ' : . ,' ' : , : . !. .


.. .'1 . ' .' '''

W091~00575
PCT/US90/03878
2 ~ ~ ~ 8 9: ~ `
FIG. 34 is a flow chart that describes in detail
the change light pen modify mode 58 from FIG. 2. Light
pen modify mode 58 changes the action key to advance from
a screen in playback 22. FIG. 34 begins at entry point
5 58, which corresponds to step 58 from FIG. 29.
The first step in FIG. 34 is step 950, where in
the light pen modify window is displayed on the screen.
After displaying the modify window, step 952 and awaits
user input. ~hen the user~has hit a key, branch 954
checks to see if the input key is the escape key or the
light pen modify toggle key. If it is not, branch point
956 checks to see if the input key is some other valid
key. If it is not, the modify mode 58 returns to step 952
and waits further input. If at branch point 956 the input
15 key is a valid key, the modify mode 58 moves to step 958.
Depending on the particular key input at step 952, step
958 changes the action key or light pen location values
accordingly. After step 958 has been accomplished, the LP
modify mode 58 returns to step 952 to await further inputO
20 If the input key is the escape or light pen modify toggle
key,~the modify mode 58 moves from branch 954 to step 960,
which turns off the light pen modify mode, to exit at
point 962 and returns to modify 44.

G. Screen Utility (Page 1 - F7)
In the simplest sense, this function is a single -^~
screen option that allows users to create, change, and
save single screens using screen painting and editing
functions. These functions are effectively also available
in modify 44 mode, except that p_CBT_Page is equal to 4,
whereas in modify 44, it is equal to zero.
The major use for this option is in the creation
of instructional screens tQSCRs) and, for developers, in
the modification of control files. Since most control
files are in fact nothing more than stored screens which
3 5 are read in without display and assigned to their proper
variables, these screens are to be modifiable.



.


,,. . ,' ~ :

W091/00575 PCT/US90/03878
- - 97 -
2 ~
When beginning this function the system displays
a screen (with Screen Utility written in a box). The
options menu 52 is displayed across the bottom on the
assumption the user will want to immediately bring in a
different screen or bring in a blank 80 column screen to
author (done by a +R with a blank file name).
While the options menu 52 has many options,
there are only a few of those in this mode. One is to
tR)Replace. Conceptually, this is like bring in the
screen from file -- it essentially replaces the current
display with the one requested. Generally, to look at a
screen or change a default or control screen, this option
should be used.
The user can also (S)Save so that whatever is
created can be saved. The option to (L)List files is
available here as well.
The Page 1 menu selection of F7 triggers the
call to this function. The logic begins by resetting the
key to the RESETKEY (F7) and setting the Function_Key_SW
to TRUE again, before calling the CBT_Character Trap
function. This time CBT2B.C does the page one translation
and, if the user is not on page la, the logic turns the
key into the SP2KEY. Thus, when the logic falls on down
the line of calls in the trap, it hits the function key
call, and finds that it is on page 1 with SP2KEY hit.
This sets p_CBT Page to 4, pcolorl to FALSE, displays the
screen utility screen, sets p Clr ASCII_SW to FALSE, turns
off p Select_SW, and then sets the cursor and goes to the
control loop.
FIG. 35 describes the functions associated with
the single screen utility 56 shown in FIG. 2. In general,
the screen utility 56 allows the user to manipulate
screens. These manipulations include changing the color
or adding alphanumeric, or graphic characters to a screen
so that the screen: could eventually be inserted as is in
a tutorial file; or could be a template screen that would
be inserted into a tutorial and then customized; or could

W091/OOS75 PCT/US90/03878
. ~ .
- 98 -

be a system control file screen. The utility 56 can also
be used to add help message data to an existing screen.
The screen utility flow chart begins at point 56
on-FIG. 35. Step 966 loads a default screen identifying
that the user is in screen utility. Step 968 displays the
option menu 52. The program moves to step 970 and awaits
user input. Branch 972 checks for the escape key. If
struck, the escape key causes the program to abort the
scree~ utility 56 function and exit through point 974. If
the escape key has not been struck, the program moves to
branch 976 and checks for the color/ASCII toggle key. If
the color/ASCII toggle key has been hit, branch 978 checks
to see if the color/ASCII 54 mode is already on. If yes,
the program moves to 980, turns the color/ASCII flag off,
and returns to step 970 to await further input. If the
color/ASCII mode is not on, the program branches instead
to step 982 and turns the color/ASCII flag on. The
program them returns to step 970 to await further input.
If at branch 976 the color/ASCII toggle key was not struck
the program moves to branch 984 and checks for the options
menu toggle key. If the option menu toggle key has been
struck, the program branches to branch 986 and checks the
status of the option menu 52. If it is on, the program
turns it off at step 988 and if it was off the program
turns it on at step 990. After toggling the option menu
mode either on or off, the program returns to 970 to await
further input. If the input key was not the-option menu
toggle key, the program moves to branch 992. Branch 992
checks if the color/ASCII flag is on, whereupon the
program branches to 994. Branch 994 checks if the input
keystroke is a valid color/ASCII option key. If yes, the
program proceeds to 54 and calls the function process
color/ASCII. This is the same function as color/ASCII 54
shown on FIG. 2 and explained in the part of the
specification that describes modify 44. If the input was
not a valid color/ASCII key or the color/ASCII flag was
not on the program moves to branch 996, which checks if
the option menu 52 is on and, if so, branch 998 checks if

.. . ~ ,. ~ . 1

', . . ,; ' " . ' i ` '
.... - - ` ~

WO 91/00575 PCl`tVS90/03878
20~989~ ~
the input is a valid option menu key. If yes, the program
moves to step 1000 and calls process option function, as
is described more fully below. Once 1000 has been
completed, the program-returns to program 970 and awaits
further input. If-the option menu mode was not on, or the
input was not a valid option menu key, the program moves
to branch 1002. Branch 1002 asks if the input is a valid
keystroke other than the keys examined in branches 972,
976, 984, 992, and 996. If the keystroke is valid at
1002, step 1004 displays the keystroke at the cursor
location, and returns to step 970 to await further input.
If at branch 1002 the input is not a valid keystroke, the
program ignores the keystroke in step 1006 and returns to
step 970 to await further input.
FIG. 36 is a flow chart describing the sub-
function, process option, entered at point 1000 on FIG.
35. This function allows the user to perform a number of
operations on the subject screen. The flow chart is
entered at point 1000 and proceeds immediately to branch
1008. Branch 1008 checks to see if the input is the
exercise statement key, and if so, moves to step 1010 and
inserts an exercise statement template screen. The
program then returns to step 54 through exit point 1012.
If the response at branch 1008 is negative, the program
moves to branch 1014 and checks if the input is the blank
40 character screen key. If yes, the program moves to
step 1016 inserts a blank 40 column screen, and thèn
returns to step 54 through exit point 1012. Branch 1014
checks for the replace key. The replace keystroke, moves
the program to step 1016. Step 1016 checks to see that
the present file name is a valid file name. If the file
name is valid at branch 1018 the program moves to 1020 and
inserts the named screen, replacing the current screen at
that point in the file. The program then returns to step
56 through exit point 1012. If at branch 1018 the file
name is not a valid file name, branch 1022 checks if the
file name is blank. If the file name is blank, the
program inserts a blank 80 column screen, replacing the




, ~,
'` '. : :.; '; ;'~' ' ~ '
,,: : . -

,, .: .. . ...

WO91/0057~ PCT/US90/03878

2~89i ~ 100- ' ~ ,
current screen in step 1024. In either case, the program
then returns to point 56 through exist point 1012. If at
branch 1014 the replace key has not been struck, the pro-
gram moves to branch 1026 and checks for the save key. If
the save key has been struck, the program moves to branch
1028 and checks that the present file name is a valid file
name. If not, the program aborts at this point and
returns to step 54 through exit point 1012. If the file
nal-u~-is-vd-lid, tl~e progr~ ~oves ~o step 1030 and saves
the present screen in the specified file, before returning
to point 56 through exit point 1012. If at branch 1026,
the save key has not been struck the program moves to 1032
and checks for the print key. If the print key has been
struck, the program moves to step 1034, and prints the
present screen on the output printer. The program then
returns to step 56 through exit point 1012. If the
exercise statement key, blank 40 character screen key,
replace key, save key, or print key have not been struck,
the program will end up at step 1036. At this step, no
legal option has been entered, so the program aborts the
process option sub-function and returns to step 56 of the
screen utility function.

H. Student
The author or the deveIoper may run the student
subsystem from a diskette like the students by changing
the session drive to A (using defaults --F10 off the
author menu 20) before running this option of F9 off the
author menu.
Selected from the CBT7.C page 1 options, the
p_CBT_Page is reset to zero and the function
P Start_Student in CBT4.C is called. This will display
the student start-up screen and set p_Reset to three and
p_Temp Student_SW to TRUE. It positions the cursor off
the page and calls the control loop to await a keystroke.
That keystroke goes through CBT_Character_Trap,
gets to P_T_Char_Process_Reset in CBT2B.C which will reset


- - . . : . :.


,:.. : . , , :
-: .: , ~ : - ..

. .

WO91/00575 PCT/US9~03878
: :", ' . L
- lol - 2~

the p_CBT_Page to zero, set pdemof to 33, and call the
registration page with P_Reg_Page.
That function will, of course, display the
registration page (see subsequent registration page
descriptions for processing information). Upon successful
entry, p_Reset is put to zero, pdemof to 33 to be sure,
and PMasterm is called.
Based on the current state, pdemof being 33 is
the key, the next call is to bring in and write the course
directory information from the diskette (all this in
PMasterm). The function P_Dir_Page found in CBTlO.C is
called. It displays the directory (note if returning from
an exercise, the program would return to this area of
PMasterm with the flag p_Dir_Page_Was_SW set so it would
not get the directory again from disk but merely display
by calling P_Dir_Page with a FALSE parameter). After
display of a directory, the logic returns with the state
P_Dir_Page_SW set TRUE. CBT_Character_Trap or
CBT_Pointer_Trap will take the input and, with a valid
selection, the user will be ready to go forward to the
mode selection or QSCR 4 screen.
A selection on the directory page is handled by
Process_Selection in CBTlO.C and, if valid, the functions
sets p_Dir_Page FALSE and p_Sn4_Page_SW and p QSCR_4_SW to
TRUE. The exercise name is placed in the file
specification and it is necessary to select the mode to
run the exercise in. The QSCR 4 is displayed and the
system waits for a keystroke or pointer hit.
From the traps, the hit is evaluated and the
character passed to the function Psnot4ck which sets the
flags. This function is called-from CBT_Pointer_Trap or
from CBT_Character_Trap based on p_Sn4_Page_SW being TRUE.
There is a condition that allows a call in the playback
key handling in CBT2B.C to allow a change of mode during
the playback 22 by inserting a QSCR 4 into the exercise.
This option has not been used.
Psnot4ck, found in CBTl.C, will set
p_Play_Mode_Flag (to 'A' for automatic 24, 'M' for manual



,. : . , : : :
:.: , , , :,:

WO 91~00575 PCl'tUS90io3878
æ~ 102- ' ~'' '

playback 26, 'C' for instruction 28, and 'P' for
proficiency 30) and p_Select_Time (as 100 for instruction
and proficiency 30 and 101 for manual 26 with the
automatic 24 time being whatever was found in variable
auto demo time -- set from the default screen) In
_
addition, the instruction 28 and proficiency 30 modes will
set the p_Teaching_Mode_SW to TRUE.
. When running playback 22 there are branches on
p_Select_Time and on p_Teaching_Mode_SW. The flags for
automatic 24, manual 26, instructional 28, and proficiency
30 are A, M, C, and P, respectively.
The function calling Psnot4ck will also set
p_Play_Int to four before returning above. This will '''
cause CBT_Low_Interrupt to call the function that starts
the playback - Pplaybck. ~.
On return from the exercise, pdemof will be 33
and p_Dir_Page_Was_SW will be TRUE and the user can
continue in this directory - exercise loop for as long as
the user wishes.
With further regard to student interaction/ the
CBT 12 provides a student registration page. Once the
student hits the Enter key from the first introductory
screen (or once the author/developer has used the F9
option the page one menu), the state of the system is
identified by p_Reg_Page_SW being TRUE and the function
P_Reg Page is called. The majority of registration code
can be found in CBT9.C.
The process begins by the reading of the
registration file (CBTREG.DAT) off the diskette. This is
an ASCII text file that can also come from the management
system and is rewritten if the information is changed or
entered for the first time (keep in mind that as an ASCII
text file the rewrite requires an end-of-file hex lA).
Once the file is opened and the data read into the array
p_Reg_File_900, that array is parsed to give values to the
various fields, if any. The temporary holding variables,
all declared in the CBT9.C source file outside any
functions, are last_name[], first_name[], middle_initial,

: . '' : , ,. ~' ' ':
: ' ': '.
'
`~
`. ~ ~ ' ' ,'' ' .

.

W09t/00575
PCT/US90/03878
~'' i
~ - 103 2~

soc sec no[], department[], work center[] and
entered pwd[]. The parsing is done by parse_reg file.
If there is a password already, the p_Ident Good
flag is set to TRUE. The registration page itself is then
called from disk and displayed. The information on file
is-filled in and the process of entering the data begins.
If there is a password, the cursor is placed~on the
password field where the user can enter the password and
continue to the course directory. However, they could use
TAB or arrow keys to update any information.
If no password exists, the cursor is taken to
the first field since it is a new registration. The
student is then asked to enter data field by field. The
student cannot leave a required field if there is no data
in it, and these are last name, first name, student id,
and password.
The system now captures keystrokes at the local
level. However, it still needs to leave for help upon
hitting Shift-F1 for help. It therefore sets up a global
variable to hold the field that it was on when help was
requested, and sets P Play Int to 88 so that on return to
the Reg Page function (it will come back due to the state)
it will not reread the file or retrieve the screen again.
The input function is Full_Fill_In and will fill
in the data (if the p_Play_Int was not 88) for all fields
before going to the field sent down as a parameter for its
first entry. There is a loop on the variable value that
is incremented after each successful entry to bring one
through the possible cases and, finally, to the password
field.
Password entry is either a call to
create new password for a new user -- this requiring the
entry of the password and a second entry to verify that no
typing error was made -- or to enter verify_password where
the test of an existing password is made.
Enter verify will accept either the real
password, or a super password that the administrator of
the system would know in order to help students who forget




... . . . . ~ . :
:: : . . , , : ,-~ , . ~

W O 91/0057S
PC~r/US90/03878
. - 104 -

their password to continue. There is a default password
of RANDALL that comes with the system and this is
p_Sup_Ident_Code. If no password is found on the default
control screen then it places the super password into
p_Def_Ident_Code. Otherwise the default one is
p_Def_Ident_Code. Once that default password is entered
the program will call create_new_password just as if the
student were new. ;
If the user accepts the entries, the
p_Reg_File_900 array is reassembled using a sprintf with
the temporary fields in the function build_reg_file, and
then written out with a final CR,LF, and CTRLZ in
P_Write_Reg_Data. This file would now be ready for the
management system importation if the information on
students was being tracked.
Once the user has completed the registration,
the P_Reg_Page function will set p_Reg_Page_SW to FALSE
and pdemof to 33 and sends the user back though PMasterm.
In effect, this will call the course directory (based on
the value of pdemof).
Developers can hit the END key when the
registration page is displayed while running a student
diskette session to bypass having to enter any data
including password.

1. Student Start-Up Flowchart
FIG. 37 explains the limited mode of student
interaction with the program, and this subsystem may well
be provided to the students on a diskette separate from
the rest of the program. FIG. 37 commences with step 1038
which displays a first screen 1038, which is a welcome or
introductory screen. After the first screen is displayed,
there is a wait for a start-up key in step 1040. This
start-up key input leads to the load registration template
screen 1042, in which the registration page with blanks
where data will go, is displayed. Step 1044 allows a
student to load in registration data, including; name, ID,
work number, and a password at the end. Step 1044 leads



,

WO91/00575
PCT/US90/03878
05 -2~8~

to branch 1046 which queries whether the student has been
- previously registered by checking if any data already
exists. If no previous registration, the CBT 12 proceeds
to request registration data to be entered by the user in
step 1048. This leads to branch 1050 which checks whether
all the-registration data has been successfully completed
and entered. If it has not, then the program CBT 12 loops
back to the display first screen 1038. Otherwise, if the
us~h-as pr~vi~usly be-en reg~stered as-determined in
branch 1046, or has completed entering the registration
data successfully as determined in branch 1050, the CBT 12
proceeds to entering a password in step 1052. Thereafter~
in branch 1054, the password is examined to determine
whether it is valid. If it is not valid, the CBT 12
proceeds through branch 1056 which counts whether there
have been more than three errors entered in an attempt to
provide a valid password. If there have not been more
than three errors branch 1056 loops back to allowing the
student to re-enter the password. Otherwise, the program
loops back to display first screen 1038. However, once
the student has entered a valid password, the CBT 12
proceeds to course directory 36.

2. Course Directory
The course directory is organized such that
items are indented based upon their significance, and a
highlight bar will only fall on those items that are the
most indented -- the exercises themselves.
- To be on the course directory is to have
completed the registration page and been returned through
PMasterm, which will note that pdemof is still 33 and
check the flag P_Dir_Page_Was_SW. The first time this
will be FALSE and the user will call P_Dir_Page with a
parameter of TRUE. If the user has returned from an
exercise, the switch would be TRUE and the routine would
be called with FALSE so as not to reload the directory.
P_Dir_Page (found in CBT10.C along with most of
the course directory code) will set the p_Dir_Page_SW TRUE

- . . ~. : . ..:

. ; - ., ': , ,: , ' " . , " . ,: ' ~ .

WO9l/00~75 PCT/US90/03878
~`'
~&~ 106 -
so that whenever the user leaves for keystrokes the user
will know where to return and what to do with the keys.
It will then call the routine Copy_Course Dir.
Copy is actually loaded into the proper
location. It first reads in the first record into
p Temp 600 on the assumption this will be the 600 record
or header record for the directory (if it is not it will
rewind the file and try again). Byte nine in the array
will be a '6' iE the header record is found and, if so,
the name field is read and placed as the title in the
directory header line. Then the file is read and each
line (the file is ASCII up to 80 characters with CR and LF
at the end) is assigned to its place in the array
course_dir[][]. A count of the number of records is kept
in recount to be used later for writing and for highlight
bar movement when needing to know the end.
The directory is then displayed using Course_Dir_Display.
This builds a screen buffer for display of each line,
handling the indentation problem (in byte 9 a '0' is an
exercise file and it gets its own indent and color
attribute assigned -- likewise module names and comments
have their indent and color based on their value in byte
9). In addition, if byte 45 is not blank the exercise has
been completed and the display is set with a dim
attribute. If a start date exists the started column gets
an X. If there are not enough rows to fill a screen, the
remaining lines are written as blanks. Finally, the
highlight bar is placed on the current position -- at the
start this Window_Pos is the first line it finds in the
display with byte 9 equal to zero. The user then returns
to the control loop to await a keystroke.
The valid keys to continue to process would be
Up Arrow, Down Arrow, Page Up, Page Down, End, Home and
Enter. When those keys are hit, the CBT2B.C routines will
call P Course_Dir_Page and send down a character
representing the key. If it is Enter, the function
process selection is called just as if that row had been
pointer selected. Otherwise, the calls are used to move


- -: . ~ , . .
. . . .. :, . . .- ~

WO91/00575
PCT/US90/03878
~ - 107 -2~

the cursor to the next valid position (Up Arrow goes up to
the first exercise record it finds before the current
Window_Pos, Down Arrow goes down one. Page Up and Page
Down go to the next or previous page full (currently 20
per page) and then seek the first exercise entry from the
top of the window. Home starts the user at the top of the
first page again (finding the first exercise from the top)
and End goes to the last page and finds the first-exercise
field starti~ fro~ the bottom. When the valid entry is
found for the bar, that is made the Window_Pos. The bar
is then moved there. This goes on until Enter or ESC is
hit.
As there can be multiple diskettes for any
student course, the directory has the diskette number on
which the exercise can be found sitting in byte 11. When
a selection is made, the value of that byte is compared
with the current header record value of byte 56 and, if
they are not the same, the system will ask that the proper
diskette be loaded. It does this by placing that 11th
byte value into p_Exercise_Name and calling
P_GP Mess_Display. This will pLace the value into the
proper spot-on a message asking for the proper diskette
number.
When the message is displayed, the directory
simply becomes active again as if no choice had been made
and the user may or may not actually enter the proper
diskette. The test would be made again when an exercise
is selected.
An ESC will lead to P_Setup_To_Exit in CBTlO.C
which checks if the user on diskette one, the required
diskette, or not. If not it will ask for diskette one and
not allow an exit until that one is mounted.
Critiques are an exception here. The critique
flag (byte 66) is checked and if yes the system wants
diskette one, even if the directory says it is on another
diskette (it is added to the last diskette in the
directory file but that number is ignored~.


- .,,- ,, . , . , ~
,. , . - .


.. : :: :.: .. : . ~: . .. -
,

WO91/00~75
PCTtUS90/03878
' '' ' ' ~ ' ' ' 1 0
- 8 -

2~ 9 Once an exercise has been selected and
completed, the system will run through PMasterm again and r
this time find p_Dir_Page_Was_SW is TRUE and call the
P_Dir Page function with FALSE and re-display the
5 directory again. However, this time the objective is to
update the status of the directory based upon what
happened. Update Status is called to start the exercise
-- it puts in a start date if none was there, increments
~ nu 6~ tr~ès by 6~e, ~d së~s ~he- time~; After the
10 exercise the function is called with an L parameter where
it puts in the time, a completion date if the mode done
was the highest mode the exercise runs in (these go, in
order, manual, automatic, instruction, and proficiency).
One special difference handled elsewhere is that an ESC
15 from the critique will mark all flags as if never called,
including erasing the start date.
When the user has finished with the directory
and chooses to ESC, the directory will be written to the
disk. If the proper disk is accessible the completion
20 flag will be written to the temporary header array
p_Temp_600 and that record will be written, followed by
all of the course_dir[][] through a loop which will then
end by writing out the hex lA required for the text file.
Byte 57, the completion flag in the header
25 record, is changed to incomplete at startup. A proper
exit marks it complete again. Thus, an improper exit will
be noted if diskettes are changed improperly or an
incorrect exit was made in the process, because diskette
#l would still have an incomplete flag.
With regard to FIG. 38, the details of the
course directory 36 are shown. This step commences by
reading the directory file in step 1058. The student disk
is read for the directory of courses available on the
specific disk. If multiple diskettes exist, the first (or
diskette #1), should be used at start. Thereafter, the
CBT 12 checks whether the proper diskette has been loaded
at branch 1060. The program will only accept properly
formatted student diskettes. If the loaded disk is wrong,



.. ~ , . . . ................... . . . . . . . .
~, : , . .: . .

.::,... ; ..,: :: . . :
::::: -. ~::. : : . : -.

WO91/00575
~ PCT/US90/03878
09 2 ~

a proper diskette is requested at step 1062, which loops
back to read directory file 1058. If the diskette is the
proper one, the CBT 12 proceeds to display the directory
file on the screen in step 1064 and onto requesting
student input at step 1066. Thereafter, if the student
elects to hotkey to the host at branch 1068 by selecting a
special key to branch out of CBT temporarily, the CBT 12
will connect to the host by means of step 1070. Step 1070
leads to read directory file which-, whe~r the st~den-t
disconnects from the host or application, will return then
to CBT at the point of reading in the directory file
again. At branch 1068, if the student does not select to
hotkey to the host, the CBT 12 proceeds to determine if an
exercise has been selected at branch 1072. If the key
selected at 1072 was to select an exercise off the
directory, the routine moves to branch 1078. If a no is
returned, the CBT 12 proceeds to branch 1074, which
changes the location of the directory highlight bar. This
just moves the highlighter to another location (valid keys
would be Home, End, Page Up, Page Down, etc.). If yes at
1074, step 1076 moves the highlight bar as per the key
and, thereafter, returns to get student input 1066. If a
highlight move key is not entered, the invalid key -
ignore step 1080 is reached. This step ignores what was
an in~alid input and loops back to read directory file
1058. If a yes is returned at branch 1072, the program
proceeds to query whether the student desires to enter a
critique using our special evaluation screens (one for
each directory) at branch 1078. If a yes is returned,
then the CBT 12 proceeds to step 38 critique, and
thereafter loops back to read directory file 1058. If it
is not a critique at branch 1078, the program asks whether
the exercise selected is on the loaded diskette, at branch
1082. If it is not, then the program requests the proper
diskette at step 1084 and loops back to the query at
branch 1082. If the exercise is on the loaded diskette,
then the CBT 12 proceeds to step 1086 to display the
allowable modes at this point in the program. After the


. .: ; : : -


....

WO91/00575 PCT/US90/03878

3 ~ 0

user enters a mode, branch 1088 examines whether a valid
choice was made. If a valid choice was not made, the
choice is examined to determine if it was an escape key
that was depressed. If the escape key was depressed, then
the CBT 12 proceeds back to read directory file 1058. If
the escape was not depressed, branch 1090 steers the CBT
12 back to step 1086 to allow the student to make a choice
of mode. Once a valid choice has been selected as
determined at bra~h 1088, the CBT 12 proceeds to step 22.
At this point the program accesses playback 22 and runs
through a tutorial session as explained above.
Thereafter, the program proceeds to update
directory 42, incrementing the number of attempts, scores
(if in a proficiency mode), and noting that the exercise
is completed if the user has finished the highest mode for
the exercise. Branch 1092 then examines if the highest
mode has been completed. The modes are, in order,
automatic, manual, instruction, proficiency. If an
exercise has not finished its highest mode the user is
returned to the mode selection screen.- Finishing the
highest mode completes the exercise, so the user goes back
to the directory. All exercises do not have all modes, so
instruction can often be the highest mode. If the answer
at branch 1092 is no, the CBT 12 returns to display
allowable modes at step 1086. Otherwise, the CBT 12
proceeds out of branch 1092 back to read directory file
step 1058.

3. Critique
A critique is a special exercise selectable from
the course directory that provides users the opportunity
to rate the course they have taken. It is another of the
possible links between the management and CBT 12 system in
that information is placed into a special file in a
special format for a management system to import. That
file, CBTCRIT.DAT, consists of eight blanks (which used to
hold an exercise name when critiques could be done on each
exercise), a block of up to 50 bytes to hold the rating


. - ::: - ; - . :


' : . ::, ''',,.. , ., - ;, .:~

wo 9l/oos7~
PCT/US90/03878
~ - 111 - 2~a~sl ,~,... . ............ .

values of 1-5, and a final string to hold the generalized
comments. As a basic ASCII text file it must be ended
with hex lA.
The critique consists of a variable number of
pages,,each page being a compressed screen file on'disk
named CBTCRITx.SCR. The x is the incremented page number
starting with 1 and currently ending with 4. The first is
loaded and processed and, upon completion, the number is
inc~m~nte~ an~ the ~xt p-~g~-b~o~t- in. As this is a
flexible situation, the page consists of one-character
fields which have braces around them and which have the
special attribute defined as p_Field_Att_Req. The cursor
location routines then seek from where they start to the
next spot that matches that attribute in advancing through
the page. A value must be entered in order to leave one
of these fields. It also stops on a p_Field_Att_Opt
althsugh this is only used for the comment field.
This whole process begins when the user selects
the critique in CBTlO.C form the course directory and the
function process_selection is called. It looks at the
information on the exercise selected and checks if the
critique flag is yes. If it is it sets p_Critique_Flag to
TRUE and returns to Pmasterm with pdemof equal to 33 and
p_Dir_Page_Was_SW set TRUE. When Pmasterm (in CBTl.C) is
called it then reads those flags and calls
P_Crit_Page(TRUE) to start the process.
, P_Crit_Page (found in CBT15.C) sets the
p_Crit_Page_SW to TRUE (note that p_Reg_Page_SW remains
TRUE also) so that any exit to the control loop for
keystrokes will know where to return. The function then
reads the diskette to see if it is diskette #l (the system
wants diskette #1 to have the most recent data read and
written). The file name held in p_File_Name_csr[] is read
in and the number 1 is added when the function is called
for the first time (the parameter passed was TRUE). The
file (a screen) is then displayed and the cursor position
set to 0,0 from whence begins the first search for a valid

WO91/00575
PCT/US90/03878
112 -

input field. That search is handled by the function
P_Reg_Adj_Cursor with a parameter C the first call.
Function keys are handled first in CBT2A.C in
P_T_Char_Crit while normal characters find their way into
P_T_Char_Char_Play. The only function keys allowed are
the four arrows, the F2 key, Backspace, and the Enter key
(called RETURNKEY in the control loop).
Normally, the user starts entering their ratings
and the characters are tested to see that the number is
between 1 and 5, with a valid entry causing the cursor
call to advance to the next valid empty field location.
The cursor stays put if the user is on the last field
already and awaits a Return (the Enter key on the PC) to
go to the next page. If the row is > 24 in the cursor
location loop looking for a valid field,
p_Ok For Next Crit is made TRUE. (If the user is on the_
comment field of the last page, an optional field, the
user will be allowed to type in anything and arrows,
backspace, and enter would allow movement there, although
word wrap on the borders is not allowed.)
:- Return is one of the valid keys found in
P_T_Char Crit. If p_Ok_For_Next_Crit, return will call
P_Get_Next_Crit Page is there is another page to retrieve.
That function sets p_Ok_For_Next_Crit off again, reads
p Crit_Buffer in a loop until it hits a null to advance
past any information entered on any previous pages, then
reads in the screen fields and adds them to the array. A
null is put at the end (ready for the next time this
function is called to seek the first null), and finally
calls P Crit Page with a FALSE parameter.
P_Crit_Page will now add one to the file name,
load the new screen and display it, set the cursor at 0,0
again, and search for the first valid field (again using
p Req_Field), to be ready to process keys again.
The beginning of the CBT2B.C P_T Char_Fn_Key
processing routine tests if for an F2 and a return value
for P_Check_Reg_Field. If F2 and P Check_Reg_Field
returns set to true and p_Ok_For_Next_Crit, the system



, , ,

'' " , . ' :
' ,'',: ''. ~';'' ' ' ;'

WO91/00575
PCT/US90/03878
~ 113 - 2 ~

tests whether the user is at the last page. If so, the
program will call P_Write_Crit_Data to complete the
process. This test looks at the page information at the
top of the screen to see if it is on the same page as
there are pages i.e., the user is on page 4 of 4, and is
thus at the end. P_Check_Reg_Field effectively checks
that the required field has been entered into. The Up
Arrow and Down Arrow keys do the literal movements.
The write function builds the output file by
copying eight blanks to the start of critique_buffer, then
adding in the P_Crit_Buffer array until a null is found.
It then reads in the comment from the screen and adds a
CR, LF, CTRLZ. Then the file is written by putc-ing the
array critique_buffer. P_Init_Crit_Virtual_File
initialized critique_buffer to 320 nulls at start-up, and
p_Crit_Buffer to 50 nulls although less than half of those
bytes are currently used.
As with any exercise, it is possible to ESC and
it will be as if the user had never started. Developers,
as always, can leave a critique with special keys -- F2 at
any time.
. ~. -
4. Help
At any time and at any place, the user can hitShift-Fl to get on-line help. Help system 44 is not
field-specific but state-specific. It is based upon which
- state and mode flags are active.
The hotkey (Shift-F1) is evaluated as a very
early part of CBT_Character_Trap in CBT2A.C.
P T Char Start_Help is called and if the user is not in
help mode and the hotkey was hit, a flag called
p_Start_Help_Soon_SW is set TRUE and the user returns up
to the control loop.
In the control loop in the CBT_Low_Interrupt
routine (CBTl.C), Help system 44 checks that flag and, if
TRUE, resets the flag and sets p_Help_Mode equal to TRUE.
Pphelp is then called to display the proper help screen




- , : . . , ~.......... ., , . , :.: :
- " ~

WO91/00575
PCT/US90/03878
2~ 114 -

and then P_Get_Help_Fn Char is called to process a help
screen.
Pphelp in CBTl5.C is called while in a help
mode. p_CBT_Page is used as a flag in that if the user is
S just starting help, the page is the normal zero to five,
but if the user has a help screen up on the screen, the
value is incremented by 10 so that it is 10 to 15. That
10 is added every time the help screen is displayed (and
subtracted every time the loop where page is 10-15 is
entered so that the proper page number is back when the
time comes to evaluate states).
The file specification array pdhelp[] is filled
with the first three characters based upon the state,
followed by the number of the help screen in the sequence
if more than one screen of help is available for the
option, followed by the period and the file extension hlpo
The current screen is then held in a buffer with a call to
Hold_Screen and the help screen is displayed.
CBT_Pointer_Ok is set FALSE so the light pen will not be
possible on help screens.
Once the screen is displayed, the function
P_Get_Help_Fn_Char is called (located in CBT7.C) to setup
the menu line for the option of Next, Back and Exit at its
initial location and saves that in p_Save_Help_Fn_Char.
At this point the program is waiting action.
Any key hit will be processed by the function
P_T_Char_Process_Help (again high in priority in CBT2AoC)~
If Enter is hit, the program will accept the current
highlighted option Back or Next (the letter of which was
saved in p_Save_Help_Fn_Char). Page Down and 'B' act the
same, calling Pphelp with a back parameter. Arrows keys
call P_Get_Help_Fn_Char with an N to move the bar to the
proper next option highlight. An 'N' calls the next help
page through Pphelp and again resets the bar to the
initialized location through a call to P_Get_Help_Fn_Char.
An 'E' or another Shift-Fl designates completion of help
and calls Preturn found in CBT15.C.

WO91/00575
; PCT/VS90/03878
- 115 ~ 2~

Preturn will set p CBT_Page back to its normal
state, p_Help Page_Nbr to 0 again and p_Help Mode to
FALSE. It will also reactivate the light pen with
CBT_Pointer_Ok. The old screen before help was called
will be restored and the program will be back in the
control loop waiting action just as before the hotkey was
hit (nothing changed the old state flags -- p_Help_Mode
was just processed with higher priority and handled all
the keys etc.).
In incrementing through help screen pages, a
blank in the right hand corner will indicate that the last
screen has been reached.

I. Search Utility
FIG. 39 contains a flow of the sub-program
15 search 44 of the CBT 12. In general, search 44 allows the
user to search through a specified file for the occurrence
of an input string. The chart shows the logical flow from
the input of the search string, the choice of search file,
and through the actual search process itself.
The program enters the sub-program search 44
through entry point 68. The first step 1094 inputs the
user's search string or strings. At branch 1096, there is
a check to see whether the input is valid. If there are
no valid strings, the logic moves to step 1098, provides a
message to that effect, and exits from the search sub-
system through exit point 1100. If the input string is a
valid entry, the logic moves to step 1102. In step 1102,
the input is compressed to match the compression of the
stored exercises. The program then moves to step 1104 and
asks the user to input a file specification. Branch 1106
checks for a valid file name. If no valid file name was
input, the program moves to step 1108 and provides a no
match message and exits through exit point 1100. If a
valid file name has been entered, the logic moves from
branch 1106 to step 1110. Step 1110 opens the search
result output file. Step 1112 tries to read the next file
in the input file list. Branch 1114 asks if the user is




,.. :, .. ~ : :: .. ,.. : ...

WO9l/00575
~ PCT/US90/03878
2~ 9 1 ~ - 116 -
. .
finished with the input files, i.e., has finished
searching. If yes, the logic moves to step 1116 and
closes the output file and then exits through exit point
1100. If the user is not finished with the files, the
logic moves to step 1118. Step 1118 reads in a header
from a record in the input file. The program then moves
on to branch 1120 on FIG. 39b. At branch 1120, there is a
check if this is the last record in the-input file. If
yes, the logic returns to step 1112 and tries to read the
next file on the list. If the record examined in branch
1120 is not the last record in the file, the logic moves
on to branch 1122. Branch 1122 examines the record to
make sure that it is a basic page from a stored tutorialO
If not, the logic moves to step 1124 to display an 15 appropriate error message, and then returns to step 1118
to read in another record header. If the record was in
the proper format, the program moves from branch 1122 to
step 1126. Step 1126 searches through the record for the
input string. Branch 1128 checks for the existence of a
match. If there is no match, i.e., the input string was
not found on the recorded page, the program loops back to
step 1118 and inputs another record. If a match has
occurrea, branch 1130 checks for a second input string.
If there is only a single search string, step 1132 writes
the page and file name to output file. After the data has
been written, step 1118 reads in another record. If there
is a second input string, the program moves from branch
1130 to step 1134. Step 1134 repeats the search of step
1126 using the second input string. If there is no match,
branch 1136 returns to step 1118 to read in another
record. If the second search string resulted in a match,
branch 1138 checks for the existence of a third input ~ i-
string. If there are only two input strings, the program
moves to step 1132 and writes out the page and file name
data where the match occurred. If there is a third input
string to search, step 1140 executes this search. Branch
1142 checks for the existence of a match, if the third
string was not found, the program loops back to step 1118




: - . . , :

WO91/00575
PCT/US90/03878
,:.;
I -
- 117 - ~ r

and reads in another record. If all three search strings
were found on the present page, step 1132 writes the page
and file name data to the output file. The program then
loops back to step 1118 and reads in another record. The
program contlnues through this flow of reading in records
and then searching them for the input search string, until
the last record of the file is reached. The program also
cycles through all the input file names to be searchedO
Once all of the files have been searched, the user exits
the sub-program search 44.

J. File Functions
Selecting F6 on the authors menu will bring up
the file functions menu. It sets a flag called p_Pagela
to TRUE. For most processing, the state is still has
p_CBT_Page equal to 1 and this is a subset of that. There
are a only a handful of differences between 1 and la.
Most functions in la can be found in CBT7.C
The most obvious one is in the CBT7.C function
P CBT_Pagel which processes the options for both page 1
and la. It will call P_CBT_Pagela if~on page 1 and the
user hits F6. That screen will be displayed and the
return is to the control loop to wait for the keystroke or
action that will recall the P_CBT_Pagel, this time with
the page la flag set so it looks at those options instead.
One other difference is in the function in
CBT2A.C that redefines the keys for page 1 in that an F5
translates to a 5 in page la, but because printing used to
be something else, a P if on page 1 only.
Another is that since the file functions page
has two exercise name entry fields, a tab moves from field
one to field two and Plpsrch does a pointer search and
puts a successful exercise name to the correct field.
The final difference is in the help screen that
is displayed.
An ESC from pagela will reset the system to page -
1 again and set p_pagela to FALSE.




' i; ;' ; ,
:' ' .' :. ' ~.', ;.'.'- " ' ,.': , . ' '
. ' : : ' "' "'.,' . ,. '.".. '.' '."~ '",':: ' :'~

WO91/00575
PCT/US90/03878
2 a ~ 118 - ~!
1. Copy Exercise to Drive x (Page la - F1-F4)
The four copy options all do exactly the same
thing. They call P_Copy_Exercise in CBT7.C with the drive
name as a parameter. Drive B will be tested using
bios_equiplist and not allowed if no second diskette drive
exists.
First the user tests the two file names using
the standard functions of P_Check_Name Typed for the top
name and P_Get_New_Exer_Name for the target name. There
is a test, if the target file already exists, on whether
to overwrite. Then, if proceeding, a simple getc from one
file and putc to the other occurs. At the conclusion of
the process, P_Display_Pagela is called again and the wait
above for action is begun again.
FIG. 40 is a flow chart describing the overall
logic of the copy exercise function 48. This sub-program
simply makes a copy of any stored tutorial exercise in
whatever disk drive directory the user specifies. The
program enters the copy exercise sub-program at point 60
and immediately gets the name of the exercise to copy from
the user in step 1144. Branch 1146 checks to see if the
user has hit the escape key. If the escape key has been
struck, the program automatically returns from the copy
exercise sub-program through exit point 1148. If the
input from step 1144 was not the escape key, branch 1150
checks to see if the input is the name for a valid
existing exercise. If not, the program returns to step
1144 to input another name. Once a valid exercise name
has been entered, the logic moves to step 1152. Step 1152
allows the user to input the desired destination drive.
Branch 1154 again checks to see if the escape key has been
hit, and if it has, the logic automatically exits through
exit point 1148. Branch 1156 checks the input to see if
it is a valid drive specification. If not, the logic
returns to step 1152 and requests a new drive. once a
valid drive name has been input, the logic moves to step
1158 and executes the copy of the file. Once the file has
been successfully copied, the program exits through point

WO9l/OOS75
PCT/US90/03878
- 119 _ 2~08,91 .

1148 and returns to the point at which the copy exercise
was called.

2. Delete Exercise (Page la - F6)
Delete Exercise begins with getting the file
name and verifying it exists. It then sets a flag and
requires the user to hit F6 again to verify the request.
F6 sets the p Delete_Exercise SW switch TRUE and-displays
a message indicating th-e nee* to depress F6 again to
delete the file. Then the system returns to await a
keystroke. Anything but F6 will set the flag back to
false. The F6 will set it to FALSE and then call
p Delete Exercise.
P_Delete_Exercise simply checks the name again
and attempts to call remove. After successful deletion
it will-blank the exercise name field. It ignores the
second field in this process. The return will be to page
la.
FIG. 41 is a flow chart describing the program
module delete 62 from FIG. 2. This option is a simple
delete file function. The function first gets the name of
the file to be deleted in step 1160, and`branch 1164
checks to make sure that the input is a valid file name.
Branch 1162 and branch 1168 trap the escape keystroke and
automatically exit delete 62 when the escape key is
struck. If a valid file name has been entered, the
program makes sure the user wants to delete the file in
step 1166. When the delete order has been verified at
branch 1170, the program moves to step 1172 and deletes
the file. If the user decides against deleting the file
at branch 1170, the program exits the delete function
through exit point 1174. After a verified deletion has
taken place, the program automatically exits from function
delete 62.

W O 91/0057~ , PC~r/US90/03878
. ,,'.' ' ~:
~ - - 120 -
~,~ $~
3. Rename Exercise (Page la - F5)
Not unlike copy 60 rename 64 gets the two
exercise names and then calls a rename function to do the
work.
S The rename field, which is the New Name field,
is then switched to the exercise name field since the
exercise has now been renamed, and page la is
re-displayed.
FIG. 42 shows the flow chart for the rename 64
exercise function. The function takes the name of any
existing exercise file and replaces it with whatever new
name the user desires. The function gets the name of the
exercise to be renamed at step 1176, checks the validity
of the name at branch 1180, and renames the file at step
1182. If at any point the escape key has been struck,
branch 1178 traps the key-stroke and exits the rename
exercise through point 1184. Once a file has been
renamed, the program automatically exits the function
rename 64 through exit point 1184.

4. Append (Page la - F7)
This effectively all happens in CBT18.C once the
append_exercise is called from the page one menu in
CBT7.C. This no longer treats the screen as the data, but
does a reasonably straight forward file read. It builds
25 the .100 file just as in modify 46. The first file is
read and written up to but not including the last record.
The-first record of the second file is written again to
the .100 file. A From Code of l is put into the first
record of the second file so that it forces the last valid
record of the first file to be a stopping point in
playback 22. At the end of the second record, the end
record can be written and the same routines that end a
modify on a single file modification can be called. It is
necessary to keep track of the page numbers that count for
selections as against the real total number of pages so
that those bytes can be written at the front three bytes
of the file for proficiency testing.

WO91/0057~
PCT/US90/03878
f,:
~ - 121 2 ~ 6 ~

Append_exercise calls a special routine called
Get_Write_lst_Append to read in the old file 10.
Insert exercise routine is called for multiple_edit
insert and replace_pathway to continue to write out
records. Insert_last_record is called to set up the
proper codes in the header and used to write a proper last
record at the conclusion of append exercise.
There is an append flag variable so that the verify_action
routine can know what message to place in the confirmation
request -- in this case, append 66.
FIG. 43 contains a flow chart showing the logic
of the function append file 66 from FIG. 2. This function
allows the user to take two stored files and append them
together to form one larger, recorded file. The
performing of this function is relatively simple.
Entering the flow chart at point 66, the name of the first
file to be operated on is entered at step 1186. Branch
1188 checks for the escape keystroke. If at this point
the escape key has been struck, there is an exit from the
append file 66 function through point 1190. If the escape
key has not been struck, the input os cjecled to make sure
it is a valid file name at branch 1192. If the input is a
valid name, the file is opened at step 1194. If the input
name is not valid, the program loops back to step 1186 and
the user is asked to re-input the desired file name. Once
the first file has been opened, step 1196 asks the user to
input the name of the second file. Branch 1198 again
checks to see if the escape key has been struck. If the
escape key has been struck, the present append attempt is
aborted and there is a return to step 1186 to start the
process over. If the escape key has not been struck,
branch 1200 checks the second input name. If the name is
not valid the program loops back to step 1196 and asks the
user to re-input the name of the second file. Once a
valid second file has been named, step 1202 opens the
second file. Step 1204 then opens the append output file.
At step 1206 the actual append process begins by reading
in the first record of the first input file. The flow

WO91/00575 PCTiUS90/03878
.~ . ~ , ~.
- 122 - -

chart then moves on to branch 1208. Branch 1208 checks
for the end of file pointer. If not at the end of the
first file, the program moves to step 1210 and writes the
present record to the output file, then loops back to step
1206 and reads in the next record. The loop continues
until the entire first file has been read and written to
the output file. When the last record in the file has
been reached in branch 1208, the program moves to step
1212 and begins to read the second file named by the user.
Branch 1214 checks for the last record in the second file.
Step 1216 writes the present record to the named output
file. The program loops through step 1212, branch 1214,
and step 1216, reading records in from the file and
writing them to the output file, until the end of the
second file is reached. At the last record, step 1218
writes out the last record to the output file. Branch
1220 asks the user to accept the completed append. If the
user responds negatively, step 1222 erases the output
file, aborts the append process, and exits from function
append 66 through point 1190. If the append is accepted,
the program closes the output file and input files in step
1224 and then exits through points 1190.

5. Replace Pathway (Page la - F8)
Like append file 66, this function is called
directly from the Page 1 menu in CBT7.C, in this case by
calling replace_pathway, and all operations then happen
mostly in CBT18.C.
The process begins by opening the old file and
reading it into the big buffer. The function
Get Old Header Write_Exercise reads the old file and
writes to the .100 file until it finds the first non-QSCR
which is presumed to be the first actual pathway exercise
field. At this point, the logic will skip along the .000
file without any writing until it finds another QSCR.
This is presumed to be the end of the original recorded
pathway. The pointer is kept for later reference. The
logic now switches to the new second file intended for use

... ,. .: . -; . .: - ;.: ,. . . .
. - . - :, . : .

, . , .: . . . : : : :.~: . . . . .
:: . : ::. : :, :. ... , ;

WO9l/00575
PCT/US90/03878
123 2~ g ~
, . ,
as the replacement. Calling insert_exercise, the new
file is read and written to the .100 file. At the
completion, and assuming the user verifies the
replacement, the function Finish_Old_Ex_Block will return
to the original .000 file and pick up writing again
straight through to the last record.
There are some key assumptions made about this
process. If the old file had a QSCR in the middle of the
pathway, all the exercise screens in the second half will
stay part of the exercise. What will be inserted is the
entire second file. So if the file has QSCRs in it and is
not just a "pathway", those QSCRs will be written anyway.
There is a test to be sure that if the first
file has no QSCR to stop at after having found the first
exercise screen, the replacement is still made and a last
record from the second file is simply tagged on to finish
the new exercise.

K. File Structures
Some of the key files used by the system include
the FTF file, the exercise file, the exercise directory,
the defaults file, and the control files. Examples of
these files now follows
1. FTF File
A sample FTF file 14, suitable for recording an
IRMA 3270 emulator is as follows:
Application_Name "IRMA3270"
;This file test the parsing and input of the CBT
recorder

Sample_Rate
30 Record_Holdoff 2
Function_Holdoff 2
Start Record F9-A
Stop_Record F8-A
Record_Screen F6-A
35 Type_in_Position Yes
No_RBD_Rom Yes




~:: .. ,, . ;. :. : ,

WO91/00575 PCT/US90/03878

~ - 124 -
h~e
Autoexit Code 24 134
Ignore_Region_80 24 0 24 79 0 0 ""
;Ignore_Attributes Yes

Begin_Key_Table

5 F1 FUNCTION 24 69
F1-A FUNCTION 24 104
F1-C FUNCTION 24 94
F2 FUNCTION 24 70
F2-A FUNCTION 24 105
10 F2-C FUNCTION 24 95
F3 FUNCTION 24 74
F4 FUNCTION 24 76
F5 FUNCTION 24 78
F6 FUNCTION 24 64
15 F7 FUNCTION 24 65
F8 FIJNCTION 24 66
F9 FUNl'TION 24 67
F10 FUNCTION 24 68
KEY1-A FUNCTION 24 120
20 KEY1-C- FUNCTION 24 135
KEY2-A FUNCTION 24 121
KEY2-C FUNCTION 24 135
KEY3-A FUNCTION 24 122
KEY3-C FUNCTION 24 135
25 KEY4-A FUNCTION 24 - 123
KEY4-C FUNCTION- 24 135
KEY5-A FUNCTION 24 124
KEY5-C FUNCTION 24 135
KEY6-A FUNCTION 24 125
30 KEY6-C FUNCTION 24 135
KEY7-A FUNCTION 24 126
KEY7-C FUNCTION 24 135
KEY8-A FUNCTION 24 127
KEY8-C FUNCTION 24 135
35 KEY9-A FUNCTION 24 128
KEY9-C FUNCTION 24 135


- : . ,.: :, -: .

: ~. ... .. ~. , . .:

" ' ' ' : . " ' . i , : ,,,

WO91/00575 PCT/US90/03878
- - 125 - 2~

KEYO-A FUNCTION24 129
KEYO-C FUNCTION24 135
KEY--A FUNCTION24 130
KEY--C FUNCTION24 999
5 KEY=-A FUNCTION-24 131
KEY=-C FUNCTION24 999
TAB FUNCTION24 134
ENTER FUNCTION24 133
UP FUNCTION24 72
10 DOWN FUNCTION24 80
LEFT FUNCTION24 75
RIGHT FUNCTION24 77

2. Exercise Files
With regard to an exercise file 10, an exercise
begins with a series of recorded screens stored in an
exercise file (having the extension O00). That recorded
pathway will be comprised of "raw" screens -- those from
which some keystroke or pointer hit is required to advance
-- and "extra edit" screens which are not stopping points
but are recordings of the extra screens in response to the
actions taken at the raw screen. One benefit of the CBT
file layout and recording capability is that it allows for
the recording of multiple screens with timing information
in a way that allows an "expert" recording which can then
be played back.
That simple exercise can be played back
immediately on the CBT system. However, for default error
messages to be placed in the pathway, the users must run
through the modify 46 process one time (this is usually
done selecting F4 off the author menu 20 and hitting the
END key).
Authors would then begin the process of
customizing the exercise by surrounding the pathway with
instructional screens (a QSCR) and by providing more
specific error messages and adding procedure lines. This
may include some standard QSCR insertions to cover the

,. . j. ,,
. -, ~


.,. , . . :. .,

:,',:: ' ' , .

WO91/00575 PCT/US90/03878
. ~ . t ~ :, .
126 -

objectives of the exercise and the key points to be
covered.
The recorded exercise ends with a tag record
called the "last record." Any modified exercise must also
have a last record flag in the file. When the system
loads the exercise, it will begin by filling the buffer
with as much exercise as will fit. Normally the whole
exercise will fit in the buffer. If an EOF is hit before
a last record is found, a system error will be generated
and processing will stop. That exercise will be unusable.
The actual file layout is based on a
40-character per line screen. To handle an 80-character
per line screen, two records are needed. The first record
will identify in its header that it is an 80-character
screen. A special sequence is also placed in the final
few bytes of that record to indicate the one that follows
will finish the 80-character screen.
Because the system has a 40-column base screen,
any 80-column screen is handled in two parts, the top half
and the lower half. In-addition, the mode that the video
display is in must display the 40 as 40 and the 80 as 80.
Because an 80-column screen requires "two" screens of 40,
it is normally stored in playback in ptbuff[] (the top
half) and p_Low_Buff (the bottom half). When written to
video memory with pokes, it is done it two stages. It is
worth noting that when staging screens in playback 22, one
may stop after loading pbuff[] with just the first half of
an 80-column screen. That screen's header becomes
p_Tempbuff[] which is critical to operation, but the
bottom half won't come in until the upper half moves on to
ptbuff[].
One identification of 40 or 80 is found in byte
10 of the header with the test: if the value of the byte
& 0x80 equals 0x80 it is an 80-column screen. Another
flag set when an 80 is in effect is Have_80_Column_Data_SW
which is used by both CBT and recording emulator 8a.
Other flags include p_80col_SW, p_80col (set TRUE if 80),
p_Cols (set as 40 or 80), and p_80col_cols which is set to


- . . ... , . .: .. :

: . - ~ - :.: :: : . : : : ::: :~, .

WO91/00575 PCT/US90/03878
",
~ - 127 - 2~

80. If the screen is 40, the TRUES become FALSE and the
80's become 40 (which means p_80col_cols is 40 also). The
p_Cols value is very significant because it is used in
calculating where to display characters on the screen with
the calculation row times p_Cols, etc.
Most of the flags are taken care of in the
function P_Change_Screen_To. It takes two parameters,
one for 40 or 80 sent as the values 40 and 80, and the
other a true/false which says if false, only the flags and
variables need to be reset (the presumption is the screen
mode is the one the user wants already).
All screen blocks are together in one linear
exercise that is loaded into a big RAM area called a "big
buffer." Optionally, this could be a so-called "virtual
buffer" that is a 64K block loaded in and handled by a
separate assembly language module. However, it is
preferable that memory be allocated directly in the
program with a far pointer. The variable used is
essentially 64K and writes in and out of it are simply
moving through the offset in that array. This array is
named vbuf2.
- The far calls need a-segment and offset and new
variables to get the segments.
The routines that read and write the files, are
found in CBT6.C. They make calls to routines still named
vbuf fetch and vbuf_store, vbuf2_fetch and vbuf2_store.
They effectively poke into the vbuf or vbuf2 arrays, using
the segment and offset. The offset is the location within
that array added to the actual offset location of the
vbuf2 array within the segment. These fetch and store
routines can be found in CBT17.C.
An exercise file consists of several variable
length records all sharing a common format. The first
three bytes are used as an identifier (though in the first
record of the file they are used to provide information
about the exercise used for testing and scoring purposes).
The next 22 bytes provide header information that
describes the contents of the record. This is followed by


t ~ r


"';"', ~`:,; ''' , " ~:

:: . ., . ' ,

WO9l/OOS75
PCT/US90/03878
f'~
- 128 -

2a~ a~b~e length string comprised of the data that was on
the screen, compressed using a standard algorithm, and
then the attributes on the screen, also stored in
compressed form. There are five bytes attached to the end
of the recordj the last four of which are unused in
40-column screens. An 80-column screen will use three of
those bytes to house the sequence to identify that the
user reached the second record that makes up that screen.
The first of those five bytes is used by the program for
keeping track of what part of the file is currently loaded
in memory.
There is an exception to the standard record
type to handle any typing that was done on the screen that
was recorded. Typing buffers have as their variable
string a loop of five-byte components that hold the timing
and location considerations along with the actual
character typed for each character.
The basic layout of the 22-byte header
information is as follows:
20 Byte No. Description

[o]~tl] Buffer length minus 1 (including Control
data and Display data). Byte [1] is units
(to 99). Byte [0] is lOO's. This is
referred to as "p_SizeMinusl".

25 [2] Record type (p_Record_Type).
=0, display recorded in buffer.
=1, type-in recorded in buffer.
=3, display recorded in buffer but LAST
buffer

30 [3],t4] Timerl. This is the time from the last
screen write to the Light Pen selection
which caused the screen write which is
recorded in this buffer.




':' . ' :. :,~ ' ', :, :- ,

WO91/00575 PCTtUS90/03878

- 129 -
2 ~
[5],-[6] Timer2. This is the time from the Light
Pen selection (or uninvited screen write~
to the screen write which is recorded in
this buffer. If [5],bit Ox80 = 1, this is
a screen recorded from the host.

[7] From code(p_From_LP_Sel).
= 0, this screen write was preceded by
Screen wrlte.
= 1, this screen write was preceded by
Light Pen Hit.
= 2, this screen write was preceded by
"Request Init."

t8],[9] Light Pen address of the Light Pen or
Function Xey selection which immediately
preceded this screen write. ~8] is row,
[9] is column - integers.

[10],[11] Cursor position of cursor on-the screen in
- - - this buffer. [10] is lOO's, [11] is units.
- - - integers.

20 [12] If TRUE, this is an error display - active.

[13]-[17] Used in Playback mode - Reserved for this.

tl8]-t2l] Extension (format is .xxx) is not used.
.
The typing buffer, identified as such when
byte two in the header has a value of one,
has the loop format beginning at byte three
in the header and the remainder of the
header is not used as a header but as `~`
storage for these typing blocks. The block
below shows the five-bytes beginning at
byte three but note the second block would
begin at eight, the third at 13 and so on.




:~. .

W09l/00575 PCT/US90/03878

130 - ~ `

[3],[4] Timer 1. This is the time from the last
typed character to this one.

t5] Typed character.

[6],[7] Address in the screen buffer where typed
character was typed (screen buffer is
character, attribute format). [6] is
lOO's, [7] is units.
If the character is hex FF, it indicates a new
field is starting due to a function key having been hit
10 when recording from the host. The typing cursor is moved
to the new location but no character would be displayed
for that block of five.
Reviewing the header information in more detail,
the first two bytes are very important in the loading and
15 saving of files. When an exercise is read into the buffer
it is done on a record-by-record basis. The only way the
size of the record is known is through these two bytes.
The read functions will read five bytes (the three that
precede each header and then these two bytes), determine
20 the number of bytes that follows in the record, and read
those bytes in. The first byte after that initial five
will hold the record type and is significant at read time.
When it has a value of three the last record has been
reached and reading will cease. The two size bytes are
25 called p_SizeMinusl.
The next key byte is seven. With a value of 0
in this byte, a screen would be displayed but would not
stop for input. The screen following would be written
over it immediately. This category is primarily the
30 "extra edit" mode -- screens the mainframe generated in
response to a keystroke or pointer hit before the next
resting place. A special case of this -- the mainframe's
message that it recognizes a request has been initiated --
is handled by a value in byte seven of two. The screen
35 itself under that message is not saved again and this r
screen cannot be stopped even in modify mode.

WO91/0057~
PCT/US90/03878
- 131 ~ 2~ ~ 08~ ~

A one in byte seven of the header indicates a
stopping point, but not at the screen attached with the
header. Rather, the stopping point is at the-previous
screen. The system stages screens in a temporary buffer
before placement on the monitor. So after a, screen is
displaced, the temporary buffer is examined to see what's
in the header to know to stop. Bytes eight and nine will
then indicate the key or pointer hit location that would
allow the user to leave the screen.
Thus, if the user has a screen up asking to
select the proper action and the user points to row 11
column 22, the screen itself was already recorded when it
was received from the host. The action will generate
another screen and that screen will get in its header the
From Code of one with the values ll and 22. In this way
the system can know at playback time what is a valid
response to leave the first screen (a pointer hit at row
11 column 22).
Thus, to have the full information about any
Z0 screen one must look at the header of the screen that
follows. A QSCR is always followed by a header with a
From Code of one in order to stop and show users these
instructional screens, and modify must always be able to
stop at QSCRs so they can be changed by users.
Default error messages are generated by the
system. They can be modified by the user. -The main
selection error message is also identified by a QSCR. It
is a QSCR 2. Note that a QSCR does not have an error
message but all other raw pages will have one created.
Typing records will also have an error message
generated but these will not be a separate record. They
are found in the typing record itself and are not QSCR 2
records.

3. Exercise Directory
The exercise directory is the list of available
exercises that will appear throughout the system for
authors and developers (students will only see the course

.: . . - - .



,
,, -

WO91/00575 PCT/US90/03878
f~ 8`~ 132 -

directory described above). This list will reflect those
available on the active drive (default starts at C for
non-students usually).
An exercise list appears at the start-up on the
non-student page one. The only time the user actually can
bring it up to see when it's not there is in the List (+L)
function off the author's menu when the user is modifying
an exercise or a screen (F4 Modify or F7 Screen
Utilities).
The directory entries themselves are read into a
structure called disp_window of which display_array is an
array of 500. The system uses the dos_findfirst and
dos_findnext functions to build the exercise list (see
CBT7.C). Each name is read into the array and using
binary_insert is inserted in alphabetical order in the
list as it grows and fills the display_array. When the
last file is found, a filecnt variable tells how many were
read in to tell where the end is.
The first 'page' worth is then placed on the
screen on the shell that came as part of the page one
screen itself. Thus the middle of that shell is used for
- read/write purposes. The disk drive is diplayed in the
shell using pdisk (the session drive indicator which can
be changed and, when it is, requires the system to rebuild
the directory). Variables are kept for the Top_Of_Window
which tells the number of the file now at the top (if 0
- its first page and thus setting this 0 and redisplaying
will be what Home does), and Window_Pos which gives the
location of the current choice -- the highlight bar
location. The keys may be processed based on current
values and desired effects.
At this point in the program, Up Arrow, Down
Arrow, Page Up, Page Down, Home, End or Enter key and the
result will be reflected on the directory. A function key
will be reflected on the menu options. A letter or number
will be reflected on the exercise name field along with
leftarrow, rightarrow, and backspace. (Enter off the




: : , :

WO9l/00575
PCT/US90/03878
- 133 ~ 2

directory also displays the name of the exercise selected
automatically in the exercise field).
-On page lA, file functions, the user has two
file fields with the directory. The only difference is
that the Enter will take the choice selected and put it in
the exercise name field that is active (there are two
because it handles copy and rename etc.). - ¦
- The p_Dir_Write functions build the directory
for those pages, but because it also handles the directory
function for the author's menu and the wildcards and
differing extensions allow a directory of files other than
just directories, this function builds the string for the
filesearch specification. In the author menu-the selected
item shows up in the file name location in the lower right
of the screen. The function p_Dir_Display handles putting
up the right entries and handling the keystrokes and
redisplay.

4) Defaults (Page 1 - FlO)
- Called as F10 off the author menu, this sets
p_CBT_Page equal to three. It has two screens attached,
however.
If the user selects F10, the current exercise
name is saved using function Psavefld before the page is
officially changed to three. The first default screen is
25 --then-loaded and displayed using function pdispr.
- - There are-three choices that can be made. The
session drive is first. It allows the user to change the
drive where the exercises are to be found and the change
will be immediate. It will last until-the user comes in
to change it again or until the user leaves the program.
Another session default is the time delay for automatic
playback display. Because these two blocks both require
an entry and are both active at the same time, the typical
menu bar (the white on red bar in the exercise directory,
course directory, or QSCR4 screen) is not applicable. A
new display attribute (found by reading the screen itself)
is used for the highlight.



,, , . , . ~ . ~ ....: .. ., .. . ,.. : .. ,

:
: ; : ~ . .

.
WO91/0057S PCT/US90/03878
,~-~,~
134 -

A CBT5.C function, Prev, calls the proper
highlighting by giving the block parameters and the
location of the one to highlight. This is called once for
each block at start-up.
The third option is F10 again which will display
the standard default screen -- the permanent one.
After the initial display the system awaits the user entry
of the appropriate function key or an ESC to exit. At
this paint, any keystroke is evaluated in Character_Trap
translation of Page 3 information, and then handled in a
CBT7.C function P_C8T_Page3.
The selection of F1-F4 will change the drive,
though if drive B is chosen and there was none, the change
would not be allowed. The variable pdisk is updated at
this point and that is the one used throughout for the
disk drive in file names in the system.
F5-F9 will change the session time (listed in
the case of this function as 5-9).
The F10 (translated to 0) results in a call to
the standard default screen which is found and displayed
with the logic returns above again to await action. It
will set p CBT_Page to five (not three now). This way,
the F2 key saves the defaults back to the control loop
automatically. The user is then sent back to the control
loop.
Fields here include the permanent disk drive
default, the super password used when students forget
theirs, the auto_demo_time which sets the normal delay in
automatic playback, light pen adjustment figures that
allow the user to fine tune the light pen, and a choice of
two printers. Here, only F2 and ESC have any effect.
These are defined in CBT2A.C for ESC which has as its
default the resetting of the system to page one. F2- is
handled with the SP2KEY routine in CBT2B.C that says if
the page is five call Save_Screen so these new defaults
will then be made permanent.
Note that Page five is really not used in the
system except here. It is a catchall for future options.




, : :,: . ~ : ;, ;: ;:.
' ; ::i : ~ ' ' ~ . -:::`

W091/0057S
PCT/US90/03878
,_,....
~ . . - , .
135 -

With regard to other file layouts, besides the
main exercise file detailed elsewhere, there are a few
other structures that could be called files. These are
mostly compressed screens that are loaded into global
variables, normally in CBTl.C.- The primary files are
stO.pew, sto.pew, st9.pew, and default.pew (which is the
copy of default?.tds that is appropriate -- i.e., s for
students and x for everyone else).
St9.pew is the easiest and has been noted
before. It is the array of error messages with a
three-byte finish that indicates the display row, the time
to be displayed, and the last number of the message used
for programmer convenience in looking at the file.
The first screen (use ScrUtil -- F7 off the page
one menu -- then enter file name stO.pew and +R to
display) holds several variables and constitutes a file.
A screen is easier to look at as row,col and not linear.
The row and column here are the computer's row and column.
The ScrUtil function adds one so that row,col of 0,0 is
l,1 when the user is referring to the screen.
These will show up as offsets into pbuff when
loaded starting after the 22-byte header. Therefore an
entry's offset is determined by adding 22 then 40*row (the
screen is 40 column) plus the column offset and finally
multiplying that by two (remember the pc has a pair of
bytes for the character-attribute pair), i.e.,
pbuff[22+(40*2+1)*2].
The file layout of for the course directory file
is composed of the header record and then the exercise
records, all of the same length. The header layout is as
follows:

A - 12 Chars. - Always "xxxxxxxx.601"
B - 24 Chars. - Course Title.
C - 1 Chars. - (Not Used)
D - 8 Chars. - (Not Used)
E - 8 Chars. - (Subdivided Field)
2 Chars. - (Not Used).

., . . . ., , ,,.- ,- - . .
. ~ ' . , ! ~

-' . ~ . ' . . , :
' ~

WO91/00575 PCT/US90/03878

- - 136 -

2~ 2 Chars. - (Not Used).
2 Chars. - No. Errors, this "Selection",
- allowed.
2 Chars. - No. Consecutive "Selections" with an
Error, allowed.
F - 2 Chars. - Session No.
G - 5 Chars. - (Subdivided Field) `
1 Char. ~ Display Score Flag(Y or N).
1 Char. - Current Disk Number.
1 Char. - Disk "Complete" Flag(O = No, 1 =
Yes).
2 Char. - (Not used)
H - 4 Chars. - Always "O"-Score.
I - 2 Chars. - (Not Used)
J - 1 Chars. - (Not Used)
Using the same essentially fixed length record
size as the header, the remaining records in the file
follow the normal exercise file layout which is as
follows:

A - 12 Chars. - Exercise Number.
Col. 0-7 - 8 Chars. - Exercise Number.
Col. 8 - 1 Char. - Always "."
Col. 9 - 1 Char. - Exercise "Level".
7=module header
8=module comment
0=exercise
Col. 10 - 1 Char. - Always "O".
Col. 11 - 1 Char. - Disk Number, in Multple
Disk Series.
B - 24 Chars. - Exercise Name.
C - 1 Chars. - Option Override(O thru 7).
D - 8 Chars. - Start Date.
E - 8 Chars. - Completion Date.
F - 2 Chars. - Number of Tries.
G - 5 Chars. - Elapsed ~ime, in Minutes.
H - 4 Chars. - Score.
I - 2 Chars. - Maximum Errors(percent of total).


,~,, : . . . ~, ,: .

- `, '~ ~' "~"' ,. ' '
' :"."' , " ' . " ," , . ~

WO91/00575 PCTIUS90/03878

- 137 _ 2~ ~ 9~

J - 1 Chars. - Critique Flag(IF Y this Exercise is
Critique). critique skips over QSCR4
stuff and requires disk 1 be installed

ROW COL VARIABLE DESCRIPTION

5 2 0 p Window_Background. Used for 'normal'
directory pg current-
ly blue on grey.

2 1 p_Dfalt_Attribute.

2 3 p_Fl_Rows. Number of rows in
40-col Authors Menu
(4).

2 4 p_F_Key_Set. Current function key
interpreter (S).

2 6 p_Error_Cnt_Ok_SW. I f E student error
~ handling ok.

2~ 7 p_Bar_Background. Used for menu
highlight bar now
white on red.

2 8 p_Timel. Time in half-seconds
after display of
typing Accepted
message before
putting up author's
typing. (see 20,23).

25 2 9 p_Time2. Time delay between
author typing from
above and allowing
user to continue.




,., ;,, ,. , - .

WO 91/00575
PCT/US90/03878
~ - - 138 -

2 ~ 60 8 ~1 ROW COL VARIABLE - DESCRIPTION
2 10 p_25th_Color. Attribute for 25th
line in teaching
mode.

2 ll p Field Att_Opt. Optional field
attribute in the
critique. (used to be
registration too).

2 12 p Field Att Req. Required field
attribute in
critique/reg where
exit is not allowed
without entry.
2 13-21

2 22-27 p Insert Name. The word INSERT.

2 28-33 p Block Mark Name. The word MARK.

2 34-39 p_Block Move Name. The word BLOCK.

3-6 0-39 p S2 Fn Buffer. The default authors
menu template.

7 0-19 p Err Mess Print Title. Message 'Select Err
Window.'

7 20-39 p Type Print Title. Message 'Typing Error
Window.'

8 0-14 p Top Mes T. Message 'Typing Error
Mode.'

8 20-39 p F2 Buffer. Words 'EDIT MENU.'

9 0-19 p Type Err Title C. Currently 'Try Again'
for QSC4-mode C.




- . : :. , :. , ... : ......... -
. : :, , .:.:~ . :: ,.:, ::: :.: : .: :. :., :
. : .: . . ::., . :,: ,, . . : ::: . i~ .
~, . : . ::. :: ::: . . : . . .:: ;: .

:


WO91/00575 PCTtUS90/03878

~ t~,~, , '

ROW COL VARIABLE DESCRIPTION
9 20-39 p Type Err Tltle P. Currently 'Type-in
error #' for
- proficiency mode
.
10 0-19 p Err Mess Title C. Currently 'Try Again'
in instructional
mode.

10 20-39 p Err Mess Title P. Currently 'Error No.'
in proficiency mode.

11 0-19 p Top Mes E. 'Last Screen' for top
line mode message if
last screen.

11-16 20-39 p Type Error Blk. The full typing error
block to be
displayed.

12-16 0-19 p_Err Mess Init Blk. The default error
' ~ messagè screen to be
displayed.

18-23 0-12 p Third Error Buf. The third error
window for a
selection error --
now 'select or press
the itme shown in lt.
blue.'

18-23 13-25 p Third Terr BUf. The typing third
error window now
'Type the item shown
in lt. blue on top
line.'




- . - : . ... ~ , ::

:
WO9l/0057S
PCT/US90/~3878
140 -
ROW COL VARIA~3LE DESCRIPTION
18-23 26-39 p_Typing_Sub Buf. Message when typing
is accepted but then
expert typing
replaces it.
The second file used is sto.pew (note this is
the letter oh as opposed to the number zero above).

ROW COL YARIALLE ~ESCRIPTION

2-9 0-39 p_Id_Mess[]. Six password messages
used in registration
password handling.

10 0-14 p_Top Mes_R. Messaye 'Scr Edit
Mode' for top line
mode message.

10 15-19 p Page_No_Chars. Message 'Page =' for
lS top line.

10 20-34 p Top_Mes B. Message 'Select Err
Mode' for top line
mode message.

11 0-9 p_Sup_Ident_Code. Super password to
help unlock student
diskettes (RANDALL).

11 20-33 p RC_Nbrs. 'Row = Col = ' for
top line.

12 0-1 p_Dir_St_Row. Start row for display
of directory.




12 2-3 p_Dir_St Col. Start column for
directory.


.,: . . :: , . :~:: :. .. , , . , .: .. . :.


-. : . .: -. ::: .,. : : ~ :

WO 9l/OOS75
(~ ~ 141 2~ 9~ Pcr/Us~o/03878
~ow COL VARIABLE DESCRIPTION
12 4-5 pfldsrl. Field 1 start row
(9)

12 6-7 pfldnrl. Field 1 number of
rows (5).

5 12 8-9 pfldscl. Field 1 start column
(46). ;~

12 10-11 pfldncl. Field 1 number
columns (16~.

12 12-13 pfldsr2. Field 2 start row
(9).

12 14-15 pfldnr2. Field 2 number of
rows (4).

12 16-17 pfldsc2. Field 2 start column
(12).

15 12 18-19 pfldnc2. Field 2 number
columns (14).

12 20-21 pfieldlr. Row for Name field Pg
1 (6)-

12 22-23 pfieldlc. Column Name Field Pg
1 (19)-

12 24-25 pfieldln. Length of Name field
Pg 1 (8).

12 28-29 pfield2r. Row for Name Field Pg

25 12 30-31 pfield2c. Column Name field Pg
2 (20).



:~

W091/OOS75 i ~ PCT/US90/03878
- 142 -
2 ~
ROW COL VARIABLE DESCRIPTION
12 32-33 pfield2n. Length of Name field
Pg 2 (8).

12 36-37 p Auto Row. Row for display of
auto-time on Page one
S (9)-

12 38-39 p Auto Col. Column for display of
auto-time on Page one
(32).

13 0 p Dir Color Row

10 13 1 p Dir Color Indent[O]

13 2 p Dir Color Indent[l~

13 3 p Dir Color Indent[2]

13 4 p_Dir_Color_Indent[3]
.
13 5 p Dir Color Dim

15 14 0-9 p Print Page Heading The word 'Exercise :' -

14 25-29 p Print Page. The word 'Page:'

14 30-34 p Print Date. ~he word 'Date:'

14 35-39 p Print Time. The word 'Time:'

15 0-1 p_No_Sel Allowed. Failing grade (70).

4-5 p No_This Sel_Allowed. Return if this no.
errors on this one
selection.



;, , ~, , ! . : :: :

' . '' "::: ":: ". ' '.'', :; ': ',. :': . ' ,:'.'" :',' ' ::~ " ', '
. :: ::: : - : ' ,"' ' . , ., `:

W091/OOS75 2 0 ~ O ~ 9 ~CT/US90/03878
f - l43 -

ROW COL VARIABLE DESCRIPTION
15 8-9 p No_Consec_Allowed. Return if no.
consecutive errors
~ reached.

16 0 CBT_Bckgrnd_Enable_SW. Allows for coloring
of field when LP hit.

17 0-35 Mono_Attributes[] 12 three-character
- Color_Attributes[] sets with the first
being the last char
of the char sent from
the host and the next
being the mono attr.
and the third the
color.

18 0 -no variable - If Y sets color
above.

l9 0-24 p_STO_Rl9_Err Mess. 'No file name given'
message.

20 0-24 p STO_R20_Err Mess. 'CONTACT SYSTEM ADMIN
' message.

20 21 0-39 p Color Menu. The color/graphics
line displayed when
F6 is hit in modify
or ScrUtil.

The most obvious control file is the defaults
file which is default.pew at run time. The students are
given a copy of defaults.tds as their default file, other
users get defaultx.tds. The following is the layout for
the main defaultx.tds.
.

W091/00575
, PCT/US90/03878
- 144 -

ROW COL VARIABLE DESCRIPTION

3 o pdisk Reads in current disk
drive to use for
exercises.

- 5 4 0-7 p_Def Ident Code The supervisors
password to unlock
student diskettes (if
one exists it
overwrites the super
password from
stO.pew).

5 0 auto demo time. A digit from o-9 that
changes the default
time for automatic
demonstration mode.
6 0 no variable If 'N' it kills the
light pen and the
directory.

- - . :; . : ,, . - . . .
7 0 resets OPT Color[O] If 'N' sets
OPT Color~O~ to N.

14 0-1 p_Ptr Adjustment Positive adjustment
figure.

15 0-1 p Ptr Adjustment Negative adjustment
figure.
.
25 17 0 p Printer Type ' A 1 if IBM a 2 if
T-2330.
There is another file used for the dif erent
user types that sets a file called CTR.PEW. The proper
CTR.~EW is copied from the options of CTRS.PEW (student),
CTRA.PEW (author), CTRD.PEW (developer), and CTRDM.PEW
(automis). The only piece of data used is the first three




' . ' ' , ' . ' "' ' ': " ' . '' '::.:., ' ' '' ' :,~

WO91/00575 : PCT/US90/03878

- 145 - 2

characters of the screen. If they are 'STU' it sets
student flags, id 'DEV' developer mode, if blank it
defaults to author.

L. Management Interface
Because there is a need to constantly go back
and forth between Control Loop and CBT, leaving CBT in one
state or another, the logic is littered with global
variables. In addition, copies of values in the global
variables are stored as the logic proceeds so they can be
restated if they need to be in pristine state for Control
Loop.
unsigned int p_Big Block_Size
(PEW_BUFFER_SIZE);
unsigned char pbuff[P_SCREEN_SIZE]; /* working buffer */
unsigned char p_Typ_Buff[P SCREEN_SIZE]; /* typing buffer
*/
unsigned char ptbuff[P_SCREEN_SIZE]; /* buffer for top
half scr */
unsigned char p_Scr_Buff[P_SCREEN_SIZE]; /* actually only
holds hdr */
unsigned char p_Low_Buff[P_SCREEN_SIZE]; /* buffer
"".~,.-,.i,.;P~ low-half scr */
- unsigned char p_Err_Buff[P_SCREEN_SIZE]; /* Error buffer
*/
unsigned char p_Tempbuff[38]; /* Remainder of buffer is
saved in virtual mem. */

int p Reset;
-

int p_CBT Page; /* CBT "Page" no. (1, la, 2, 3, 4
or 5) */
30 int p Pagela =FALSE; /* Indicates CBT Page la (subset
of-l) */
int p Playback_SW; /* Playback mode indicator */
int p_MIS Recording_SW; /*~Recording mode indicator */


_ _ _ _

WO91/00575 ~ - ~ PCTtU590/03878
~6~8~ 146 -
int p_Select_SW; /* Set when + Key pressed, Modify
mode */
int p_Modify_Mode_SW; /* Modify mode indicator
(Playback also set*/
5 int p Help Mode; /* Help mode indicator *~
int p Clr ASCII_SW; /* Color/ASCII mode Indicator
/
int p_Student_Mode; /* Student mode (not simulated
student */
l0 int p_Student_MIS_SW; /* Set when student is in MIS
mode */
int p_Temp_Student_SW; /* Set when Author chooses
student mode */
int p_Student_Set_Mixed; /* Set=student diskettes mixed
up & recovering*/
int p_Disk_l_Already; /* Disk l has been seen, but this is
not it */
int p_Last_Disk_Nbr; /* Last disk no. of student
set *~
20 int p_Scan_All_Disks_SW; /* Set of disks mixed,
set=scan all disks */ . -~
int p Current Disk, /* Current disk no. ;~
* / ~ .
int p_MIS_Page_SW; /* Set when student or author is
25 in MIS */
int p Ptr_Modify Mode; /* Mode allowing changes to
Light Pen sel */
int p Dev Mode = TRUE; /* Development mode (allows
special options*/
int ppbck Only = FALSE; /* If = TRUE, Only Playback
allowed. */
int p Auto MIS Flag = FALSE; /* Indicates if Auto-MIS mode
*/
int p Author_Dir SW = FALSE; /* Indicates Author
Directory mode */
int p Play_Mode_Flag =0; /* M= Manual, C=Instruction or
p=Proff~ */

WO91/00575 . PCT/US90/03878
~ - 147 - 2~

int p_Pstart_Flag = TRUE; /* Switch set indicating initial
startup */
int pdemof =0; /* 0=reg 3=student 33=temp-in playback */
int pdebug =0; /* If not = 0 (set = 4) offset for PQ debug
routines */

int p_Reg Page_SW = FALSE; /* Indicates Registration
Page mode */
int p_Crit_Page_SW = FALSE; /* indicates Critique page
series */
int p_Dir_Page SW = FALSE; /* Indicates course Directory
Page mode */
int p_Sn4_Page_SW = FALSE; /* Indicates now displaying
QSCR 4 */
int p_Dir_Page~Was_SW = FALSE; /* Indicates have seen a
Directory page */

int p_Hex_Color_Mode; /* Type Hex Color Attribute
mode */
int p Hex_Color_4bits; /* Store 1st hex char
*/
20 int p_Hex_Char_Mode; /* Type Hex Character mode
*/
int p_Hex_Char_4bits; /* Store 1st hex char
*/
char p_ASCII_Char = Ox02; /* Current stored char in
ColorASCII */
char p_Color_Attr = Ox71; /* Current stored attr in
ColorASCII */
int p_ASCII_Mode; /* ASCII character selection
mode */
30 int p_Color_Mode; /* Color attribute selection
mode */
int p_Save_Color_Mode_Flag; /* Indicates that Top Line was
*/
/* "Displayed" when screen saved
for Color mode */
char p_Color Save; /* Saves color for painting */

WO91/00575
PCT/US9OtO3878
- 148 -
2~089~.
int p_Color_XY_Save;/*Save row,col for color paint option
in '^' mode*/
int p_Line_XY_Save;/* Save row,col for box drawing option
in '^' mode*/
int p_Line_Box_SW; /* Indicates top, left corner marked
for box */
int p Color_Box_SW; /* Indicates top, left corner marked
for paint */
unsigned char p_Top_Row_Attr ; /* check is used or just
set in CBT1 */
unsigned char p_Tab_Color ; /* Tab field attribute */
int p_8Ocol ;
unsigned char ptemp[l60~;

int p_Alt_Cursor SW = FALSE; /* Indicates alternate
cursor being used */
int p_Alt_Cursor_Loc = O; /* Screen location of
alternate cursor*/
int p_Ident_Code_SW = FALSE; /* When set, cursor is in
Ident. field*/
int p Ident_Verify_SW = FALSE; /* If TRUE, verify Ident.
of student */
char p Cur_Att Save = Oxll; /* Reg page saved att for
alt typing cursor */
int p_Mess6 SW = FALSE; /*Indicates if err message should
be erased */
- int p First_Ident SW = TRUE; /* Indicates first
identification message */
unsigned char p_Reg File 900[200]; /* Buffer for reading
30 Reg file */
int p Reg_Sz = 200; /* Size of the
Registration file*/
int p Crit_Sz = 1000; /* Max. size of the
Critique file*/
35 unsigned char p_Crit_Buffer[PCRSIZE]; /* Critique
Buffer */
unsigned char p_Ident_Code[15]; /*
Identification code from Dir.*/

WO9l/00575
- PCT/US90/03878
~ - 149 - 2~ ;7

unsigned char p_Ident_Code2[15]; /* Newly typed
Identification c. */
unsigned char p_Sup_Ident_Code[15]; /* Master Ident.
code(from STO.PEW) */
unsigned char p_Def_Ident_Code[15]; /* defaults.tds ident
code */
unsigned char p_Id_Mess[40*8]; /* 8 Messages for
Reg. mode~STO.PEW) */
int p Field Att_Opt; /* Non-required field
10 attribute */
int p_Field_Att_Req; /* Required field attribute
*/
int p_Critique_Flag = FALSE; /* A Critique has been
selected */
int p_Crit_Data_Added_SW = FALSE; /* If TRUE, new added to
old data */
/* next two - why here? */
int p_End_Flag; /* Indicates End key pressed in
Modify mode */
20 int p Typing_Was ; /* Indicates that there was typing
last time */
/* */
int p_Ok For_Next_Crit; /* It is OK to display next
Critique page */
int p This Is_Critique_Flag; /* This Dir sel is of a
Critique */
int p Tempbuff_Full = FALSE; /* Switch set if p_Tempbuff
is full */
int p Cheat Mode = TRUE; /* On for Authors-allows F7 key
to "cheat */
int p_Top Line_Display_SW = FALSE; /* Set=top line disp
and saved in Mod */
int p Save Blk Ok = TRUE; /* Set = now ok to save block
_
in Modify mode */
int p Go To_End EXTVAL3(FALSE); /* Set in Mod = run to
the end(printing) */




:, ,
'', . . ':, ~ '. ~

WO91/00575
~ PCT/US90/03878
2~ 9 ~ 150 -
int p_Dir_Color_Row; /* From STO.PEW, color of dir.
rows. */
char p_Dir_Color_Indent[4]; /* From STO.PEW - Indenting
colors */
int p Dir_Color_Dim; /* From STO.PEW - "Half
Intensity" color */
unsigned char p_Student_Course_Id[10]; /* Stores Course
Name */
int p Dir Counter; /* Location on Dir shell of current pg
of entries */
int p_Last_Dir_Ptr_Row; /* Saved, last selected
directory row no.*/
unsigned char p_Bar_Background; /* Color of directory
background bar */
unsigned char p_Dfalt_Attribute; /* "bar " for Default
page */
int p Saved_Dir_Attr_SW; /* Set=attribute for the color
bar is saved */
unsigned char p_Saved_Dir Attr; /* Saved Dir attr on QSCR
4 for bar */
int p_G$0ffset 40_Bar; /* Color bar screen location in
dir & QSCR4 */
int p_No_Sel_Misses; /* No. sel or type-ins where
error(or more) was made */
int p No_Misses This_Sel; /* No. errors on this
selection or type-in */
int p No Consec Misses; /* No. consec. sel or Type-ins
of >= l error */
int p No Sel Allowed; /* Min. ~ score before student
30 "terminated */
int p No Sel Allowed l; /* Min % score if !=
blank(from dir.) override */
int p No This Sel Allowed; /* No.errors allowed on one
sel. or type-in */
35 int p_No Consec Allowed; /* No. consec. sel./type-ins
allowed with err */
int p Total Score; /* No Pages - No. pages with
error */


. . , . - ., ~ -, . .. . .


:: :. :::.: .. ,. :: . . , : -
''
:

WO 91J00575
PCT/US90/03~7
- 151 ~ 2 ~

int p Total_Pages; /* No. of pages in an
exercise(not */
/* counting extra pages
*/
5 int p_Official_Score; /* Final, % student score
*/
int p_No_Type Fields; /* Number of Type in fields in
the Exer. */
ur.signed char p_Temp_600[80]; ;* Buffer for~the 600
directory record */
int pscore; /* Score */
int p_Dir_Page_Nbr EXTVAL3(0); /* Directory page no.,
currently displayed */
int p_Dir_Last_Page_Nbr EXTVAL3(0); /* Directory last
page no. */
int p_Dir_Attr; /* Attribute used for directory
page(obtained)*/
/* from the shell */
int p_Dir_Page_Upper; /* Contain page no. of upper half
page */
int p_Dir_Page_Lower; /* Contain page no. of lower half
page */
unsigned char p_Current Dir_U_L;/* Is 'U' or 'L', arg. to
P_Write_Dir Page */
int p Mode Option_Override EXTVAL3(0); /* Directory Mode
Option Override */
int p Display_Score_Flag EXTVAL3(TRUE);/* Directory switch
allowing score */
/* display */

int p Elapsed Time EXTVAL3(0); /* Student elapsed
time,this exer.- */
unsigned char p Temp_Dir_Store[4]; /* Temporary storage
for results of */
/* Exercise */
unsigned char p_DOS_Date[8]; /* DOS Date(ASCII) */
unsigned char p_DOS_Time[5]; /* DOS Time(ASCII) */
unsigned char p_DOS_Date_S[8];/* DOS Date, start */


,, , ,, ,. ,~. :


: . . . . ,, : . ., -., ~

WO91/00575
- PCT/US90/03878
-~ - 152 -

int p_DOS_Min_Bin; /* DOS Minutes, end
*/
int p_DOS_Min_Bin_S; /* DOS Minutes,start
*/ . .
int p_DOS_Sec_Bin; /* DOS Sec., end
*/
int p_DOS Sec_Bin_S; /* DOS Sec., start
*/

int pfldsrl; /* sr=starting row */
int pfldnrl; /* nr=no. rows */
int pfldscl; /* sc=starting col */
int pfldncl; /* nc=no. cols */
int pfldsr2; /* sr=starting row */
int pfldnr2; /* nr=no. rows */
int pfldsc2; /* sc=starting col */
int pfldnc2; /* nc=no. cols */
/*--Defines type-in fields on CBT page
3 */
int pfieldlr EXTVAL3(4); /* Row--Name, type-in
20 field,p-1 */
int pfieldlc EXTVAL3(13); /* Col--Name~, type-in
field,p-l */~ ~ -
int pfieldln EXTVAL3(8); /* Length--Name, type-in
field,p-l */
25 int pfield2r EXTVAL3(7); /*
Row----------------------p_2 */
int pfield2c EXTVAL3(13); /*
Col p 2 */
int pfield2n EXTVAL3(8); /*
Length----------------------p-2 */

int p Auto Row; /* Location on page 1 of automatic
playback */
/* time */
int p Auto Col; /* Location on page 1 of automatic
playback */
/* time */




: : . . . ..

, - :: . ,

WO91/00575 PCT/US90io387X
~ - 153 - 2~ 93`

int p_Dir_St_Row; /* Starting row of the Author
directory */
int p_Dir_St Col; /* Starting col of the Author
directory */
unsigned char p Exercise_Name[12]; /* Exercise name */

int p Set_Record_Type; /* Set so that Pscrtrap will set
R.T. = 3 */
int p_p_From_2_Flag; /* Recording indicator that
p_From_Ptr_Sel=2 */
int p_Set_Next p_From; /* Recording mode, set next
p_From_Ptr_Sel */
int p_Disable_Pscrtrap_SW EXTVAL3(FALSE);/* Skip saving
buffer in Pscrtrap,*/
/* if TRUE
*/

int p_Line_Speed; /* Choice of simulated line speed for
playback */
int p_Record Type; /* See pew4, 22 byte header desc.
*/
int p_Repeat Playback_SW; /* If set, repeat, continously,
Playback */-
int p_Throw_Away Typing;/* If set, throws away any typing,
till reset*/
int p_No_Full Int SW; /* If set(in Playback) will stop
Full */
/* of top two & bottom two rows
*/
int p_Equal_Flag; /* Equal sign in 25th row(repeat
Proceedure */
/* line for student
*/
int p_QSCR_4_SW; /* Display is QSCR 4 */
unsigned char p_QSCR_4_Option; /* Option selected from
QSCR 4 */
unsigned char p_Highlight Color; /* Automatic
playback, displayed block*/




: : . . ,, ,,:. ,. , ,:. :~ : '

WO91/00575
PCT/US90/0387
l: - 154 -

int p_Highlight_Time; j* ll */
int p_Select_Time; /* Selection time or code, see PEW3~c
writeup */
/* This time will have 1 sec. added to it */
int p_Select_Timel; /* p_Select_Time, minus 1
*/
int p_Save_p_Select_Time EXTVAL3(0); /* Save location for
p_Select_Time */
int p_Blk_Cnt; /* Block count within exercise */
int p_Blk_Cnt_a: /* Incremented when recording from MIS-
to make */
/* sure that p_Blk_Cnt gets incremented
*/
unsigned char p_F_Key_Set; /* Set to the table number
of the Fn. key*/
/* set to be used(from STx.PEW)
*/
int auto_demo_time EXTVAL3(2);

int p_Type Buff_Length;
int p_In_Type_Buff_Ptr;
int p_Out_Type_Buff_Ptr;
unsigned char p_Temp_Type_Char; /* Working storage by
char. routine */
int p_Typing_Save_Flag; /* Indicates area under error
message,saved*/
int p_First_Type_Loc; /* First screen buffer location
of any */
/* typed character
*/
int p_Last_Type_Loc; /* Last screen buffer location
of any */
/* typed character
*/
int p_Type_Start_Loc; /* Screen location of the first
typed char. */
int p_End_Of_Type_Blk; /* End of Typing block */




:. : : : ~ : , : : .:

~ :~; . - :,: , ; -: :, : .

WO9l/00575
PCT/US90/03878
- 155 -
2 ~
unsigned char p_Del_Typed_Chars[9]; /* Stores the
characters to be disregarded*/
/* in checking students typing(option 1
*/
unsigned char p_25th_Color; /* Color of Author message
in the 25th row */

int p_Play_Int Code, p_Play_Int;
int p_Int; /* Copy of p_Play_Int for local
use. */
int p_Raw_Page_Now EXTVAL3(FALSE); /*Indicates on basic
page, in Modify mode*/
unsigned char p_Modify_State; /* 'B' - Selection Error
state */
/* 'R' - Basic Page state
*/
/* 'E' - Extra Screen state
*/
/* 'T' - Typing Error state
*/
unsigned char p_Playback_State; /* State of Playback
program for re-entry */
int p_Stop_Each_Screen_SW;/* Modify mode, wait for fn.
key, each time*/
int p_Wait_Each_Char_SW; /* Modify mode, wait for time
between each */
: /* character on the screen */
int p Speed_Modify EXTVAL3(FALSE); /* Switch indicating ..
hurry in Modify mode*/
/* after pressing the End key
*/
int p_RC_Flag; /* Flag indicating Row & Column is
displayed in */
/* top row, Modify mode
*/
unsigned char p_RC_Nbrs[30]; /* Row & Col display field
*/




' "" .' ' .` , :' .~;

W09l/0057S PCT/US9o/038i8

- 156 -

unsigned char p_F2_Buffer[80]; /* Contains Top Row 15
cols message(sto.pew)*/
unsigned char p_F2_Buf_Save[80]; /* Save area for Top
row, 15 cols. */
unsigned char p_Err_Mess_Buf_Save[8*22*2]; /* Save area
*/
unsigned char p_Err_Mess_Bufl_Save[18*16*2]; /* Save area
*/
unsigned char p_Err_Mess_Init_Buf[5*40*2]; /* Error
10 message initial mess. */
unsigned char p_Third_Error_Buf[6*15*2]; /* Third sel.
error message */
unsigned char p_Third_Terr_Buf[6*15*2]; /* Third
typing error message */
15 unsigned char p_Typing_Sub_Buf[6*15*2]; /* Save area
for substit mess. */
unsigned char p_Typing_Sub Save[6*15*2]; /* Save area
for Typing 3rd er.*/
unsigned char p_Fl_Fn_Buffer[40*2*4]; /* Top row
20 mess.-Author menu */
unsigned char p_Fl_Fn_Save[40*2*4]; /* Save area
for Author menu */
unsigned char p_S2_Fn Buffer[40*2*10]; -
unsigned char p_S2_Fn_Save[40*2*10];
unsigned char p_Err_Mess_Err_Title_C[40*2]; /* Error
message Title, Instr. */
unsigned char p_Err_Mess_Err_Title_P[40*2]; /* Error
message Title, Proff. */
unsigned char p_Type_Err_Title_C[20*2]; /* Type
30 Err.Mess. Title, Instr */
unsigned char p_Type_Err_Title_P[20*2]; /* Type
Err.Mess. Title,Proff. */
unsigned char p_Save_File_Name[25]; /* Save area
for menu file name*/
35 unsigned char p_Page_No_Save[10]; /* Page
no.(top row) save */
unsigned char p_Top_Mes_E[30]; /* Top message - Extra
Page error mode */

WO91/00575
PCT/US90/03878
- 157 ~ 2 ~ al

unsigned char p_Top_Mes_Tt30]; ~* Top message - Typ.
error mode */
unsigned char p_Top_Mes_R[30]; /* Top message - Basic
Page mode */
unsigned char p Top_Mes_S[30]; /* Top message - Last
screen mode */
unsigned char p_Top_Mes_B[30]; /* Top message - Sel.
error mode */
ur.signed char p Top_Mes_M[30]; /* Top message -
Mulitple Edit */unsigned char p Top_Mes_Buf[50]; /* Save buffer */
unsigned char p Top_Mes_Bufl[30]; /* Save buffer */
unsigned char p_Type_Error_Buf[240]; /* Save buffer */
unsigned char p_Type_~rror_Blk[240]; /* Save buffer */
unsigned char p Type Expert Buf[330]; /* Save buffer */
unsigned char p Type Student Buf[330];/* Save buffer */
unsigned char p Dont Stop Char; /* If TRUE, dont wait
between typed chars */
unsigned char p Light_Pen_Row; /* Light pen row of
current selection */
unsigned char p Light_Pen_Col; /* Light pen column of
current~selection */-
int p Ptr_R_Save; /* Temporary saved light pen
row */
25 int p Ptr_C_Save; /* Temporary saved light pen
column */
int p Ptr_Save_Row; /* Saved row for inserting in
next screen */
int p_Ptr_Save_Col; /* Saved col. " */
30 int p Cursor_Save Row; /* Saved cursor for inserting in
header */
int p Cursor_Save_Col; /* " */
int p From_Ptr_Sel; /* Flag indicating previous screen had
light pen */
/* selection(see pew4 22 byte header desc. */
int p Save p_From_Modify_SW;/* Switch indicating saved
p From Ptr Sel */




: : . ~ . :. . .

WO91/00575 PCT/US90/03878

~ 158 -
i8~ ~
int p_Save p_From_Modify; /* Save p_From_Ptr Sel, for
Modify mode */
int p_SizeMinusl; /* See pew4, 22 byte header */

int p Save_G$0ffset_40; /* Save Screen position */
int p_Throw Away_Extra; /* Switch to throw away "Extra
Screens", */
/* until reset */
ir.' pdclctcf; /* If == 0, set ~o l. ~L 1 ~ dc
delete */
int p_Delete_Exercise_SW EXTVAL3(FALSE); /* If set FALSE,
warns user and */
/* sets TRUE. If TRUE, executes.
*/
int p_Delete_Screen_SW EXTVAL3(FALSE); /* If set FALSE,
warn~ user and */
/* sets TRUE. If TRUE, executes.
*/

int p_Err_Mess_Select;/* Authors menu is up~perhaps with
error mess. */
20 int p_Err_Mess_Exists; /* Error message is in the `
- exercise */
int p_Err_Mess_Waiting; /* The error message buffer is
staged */
int p_Err_Mess New; /* Sets up for new(first)
2S Student Error */
/* Message */
.int p QSCR_X_Exists; /* A QSCR X has been encountered
and stored*/ . -- .
int p_Err_Mess_Kill; /* Under no circumstances, use
Error Mess */
/* even if there is one
*/
int p Err Mess Now EXTVAL3(FALSE); /* Switch to indicate
an Error Message */
3S /* exists and is ready(staged */




:: , ;, ;., , : ~ : ., ,, ,: .

WO9~/00575
. PCTtUS90~03878
- - 159 - 2 0 ~ 0 8 9 1
int p Err_Mess Was; /* An error message was put up
last */
int p_Type_Err Mess EXTVAL3(FALSE); /* Indicates that it
is time to */
/* go into Typing error message
mode */ ,
int p Type Err_Mess_Is EXTVAL3(FALSE); /* Indi~ates that
there is a typing*/
/* error message(Exercise has been
10 */
/* modified)
*/
int p_Type_Error_New EXTVAL3(FALSE); /* Indicates a new
typing error */
/* message exists */

int p_Typing_Now EXTVAL3(FALSE); /* It is time to
process typing */
int p Typing_Exists EXTVAL3(FALSE); /* A typing buffer
exists for this */
/* Display screen */

int p Typing_Skip_One EXTVAL3(FALSE); /* Skip one typing
field, Training */
/* mode */
int p_16; /* No. of columns in error
window, set */
/* to 20 by Pstart
/
int p_16tp; /* Number of columns in author
menu */
/* error window(do not change from
*/
/* current set at 20
*/
int p_Fl_Rows; /* Number of rows in the author
menu */




.',',`i'" :: ,.,"'" i ,''',;, ' '.,

WO9l/00575 PCTiUS90~03878

- 160 -
~$~
int p_Error_Window; /* Switch that indicates that an
error */
- /* exists */
int p_24row_Block; /* This is flag to allow old,
5 recorded */
/* screens(24 rows) to be used.
:. */
int p_Save_25th: /* Switch indicating need to
~ave 25th row *~
10 int p_Make_QSCR; /* If != 0, and numeric or 'X'
is shell */
/* to be used for replace or insert
*/
int p_Cursor_Cnt; /* Position in the cursor table
of the */
/* typing cursor(author's menu).
*/ . ~ .
int p_Save_Old_Cursor; /* Saves cursor pos. when
putting up error */
/* window */
int p_Page_No_Exer; /* Modify mode page no.
*/
int p Page_No_Real; /* No. pages student-has seen
displayed */
/* during exercise */
int p_No_QSCR; /* If TRUE, No QSCR
*/
int p QSCR Kind: /* If != 0, is QSCR # (where #
is from a */
/* list described in pew4 file.
*/
int p Delete_Page_No; /* Page no. being deleted
*/
int p_Save_Ptr_For_Delete EXTVAL3(FALSE); /* Saved Light
Pen coordinates */
/* from a deleted screen
*/




,';

. ' . .' ' : '~

W091/00575 PCT/US90/038i8
~ - 161 - 2~8~

/* (to be added to next 22 bytè
*/
/* header).
*/
5 int p Word_Wrap_Flag; /* Switch that word wrap
occurred */
int~p_No_Time_Flag; /* A switch that allows 0 time
between ~ */
/* screens in automatic-p-layba~k m~
10 */
unsigned char p_Color_B; /* 3rd student error
highlight attribute */
/* from STO.PEW
*/
int p_Line_Length; /* Set to desired line length
for */
/* P_Search_For_Left routine */
int p_Ident_Line_ No EXTVAL3(19); /* Row no. of the student
identification */
/* field on the Registration page
*/
int p_Ident Good; /* Switch indicating that a good
*/
/* identification code was typed by
student*/
int p_G$0ffset; /* copy of G$0ffset_40(screen
buffer pos.) */

int p Teaching Mode_SW; /* Set after Instructional or
*/
/* Profficiency mode
selected on QSCR 4 */
int p_QSCR_l Mode_SW EXTVAL3(0); /* Exercise statement
now displayed */
int p_Teaching_Error_SW; /* Set when error made on
this */
/* selection or type-in.
*/

WO91/00575 .
PCT/US90/03878
- 162 -
2~
int p_Nbr_Errors_This_Sel; /* Number of such errors
*/
int p_Skip_Display_SW; /* Don't display this screen
*/
5 int p_Prof_Mode_SW; /* Profficiency mode
*/ , .
int p_Experts_Light_Pen_Row; /* Experts L.P. sel.- test
student with */
int p_Experts Light_Pen_Col; /* Experts L.P. sel.- test
10 student with */
int p_Timel; /* Time after displaying OK message
to */
/* student before displaying typing
*/
15 int p_Time2; /* Time after displaying typing to
*/
/* student before going on
*/

unsigned int p_Blk_Cnt_x; /* Big Block No.(60K
blocks) */
unsigned int p_Big_Block_Ptr; /* Pointer within big block
*/

int p_Back Up_Table_Nbr EXTVAL3(P_BACK_UP_TABLE_CNT); /*
Set to 50 */
/* Back-up tables(for documentation see P_Backup
writeup */
unsigned char p_Back_Up_Table[P BACK_UP_TABLE_CNT*4];/*4
Bytes for each entry*/
unsigned char p_Back_Up Tablel[P_BACK_UP_TABLE_CNT*4];
int p_Prdskx_Flag EXTVAL3(FALSE); /* TRUE after first
time(used by backup */
/* table update */
int p_Big_Block_Nbr; /* File pointer for each start
of buffer */
/* (in Big Block)
*/

WO9l/OOS75
; PCT/US90/03878
- 163 - ~

long int p_Save_Saveb; /* Current file pointer, saved,
for the */
/* new, Modified Exercise, for the
backup */
/* file. This sync point is used for
the */
/* table
*/
lo..g int p_~ave_Save~ Old; /* Previo~s file pointer(old
p_Save_Saveb)*/
long int p_sig_Block_cur_Nbr; /* Pointer in the Big Block
of last */
/* Block in the sig Block( at the end
*/
unsigned int p_Last_p_ Big_Block_ Ptr; /* Last Big Block
pointer */
unsigned int p_Real_Last_Ptr; /* added for multiple del
test */
unsigned int p_Save P-Big-Block-ptr: /* Previous to last
pointer */
unsigned int p_Save P_Big_Block_Ptr_a; /* Saved pointer in
sig slock*/
/* at last record in block */
unsigned int p Last_p Blk_Cnt x; /* Last Big Block
25 number */
unsigned int p_save_p slk_cnt_x; /* Previous to last
B.B. nbr */
unsigned int p_cur_p_slk_cnt_x; /* Big Block number
- current*/
30 int p Back_Up_Table_Ptr; /* Pointer of next
location in the */
/* backup table */

int p_First_Backup_Ready; /* Switch indicating start of
backup */
unsigned char p_Back_Up_Mess_Yes; /* Switch to cause
display of message */

WO91/00575 . PCT/US90/03878
~;
. ~ - 164 -
g~
/* at completion of backup
*/
unsigned char p_Back_Up_Save[40*3*2]; /* Save buffer for
message */




unsigned int p Virtual Offset; /* Offset into the
virtual buf */
int p Virtual_Read_Flag; /* Indicates for read
*/ :
10 int p Virtual_Save[30]; /* Saves pointers
*/
int p Virtual_Temp_Ptr; /* Pointer within 50
char.buff */
unsigned char p_Virtual_Temp_Buf[50]; /* Buffer
15 for blocking input */
int p_Auto_Err_Mess; /* Modify mode,
indicates to */
/* put up error message for
*/
/* selection or typing mode
. . */
int p_Save_Module_Vblk; /* Save Module Name
-virtual */
/* block no.
*/
int p Save Module_Line; /* Save Module Name
virtual */
/* line no. . */


int p B F Number; /* Page number to
stop on */
/* when printing */




,.
: :: . .
- . ~.. ~ , ~ , -

WO91/00575
PCT/US90/03878
r~
- - 165 -
2 ~
unsigned char p_Start_Page_Nbr; /* Starting page number
for printing */
unsigned char p_End_Page_Nbr; /* Ending page number for
printing */
unsigned char-p_Print_All; /* Switch set indicating to
print the Exercise */
int p_First_Print; /* First print action(used to set up
the printer*/
int p Dont_Print; /* Set FALSE, reset TRUE by PR40SUB
routine */
char p_Printer_Type; /* ASCII number for the printer
type */
int p_Page_Printed; /* Page no. of page just printed
*/
unsigned char p_Err_Mess_Print_Title[20]; /* Title for
Error Message */
/* (Printout). */
unsigned char p_Type_Print_Title[20]; /* Title for Typing
Error Message */
/* (Printout).
*/
unsigned char p_Print_Page_Heading[20]; /* Printout Page
-- Heading */ ;
unsigned char p_Print_Page[20]; /* Printout Page
25 No. Heading */
unsigned char p_Print_Date[14]; /* Printout Date
Heading */
unsigned char p_Print_Time[ll]; /* Printout Time
Heading */
30 unsigned char p_Module_Name[8]; /* Printout
Exercise Name Heading*/

#ifdef CBTMAIN else they are decleared here as external
unsigned char p_Pr_Narrl[] = ~ 0, OxlB, 'W', 'O',OxlB
,Ox12, 0, 0, 0, 0 );
unsigned char p_Pr_Narr2[] = ( 0, OxlB, '[' , '1' ,
'1', 'm', 0, 0, 0, 0 );

WO91/00575
PCr/USgO/03878
~,.` !
~ 166 - ~ . . .
2~608~;~
unsigned char p_Pr_Widel[] = ~ o, 0xlB, 'W', '1', 0, 0,
O, 0, O, O ~; ' '
unsigned char p_Pr_Wide2[] = ~ 0, 0, 0, 0, 0, 0, 0, 0,
O, 0~;
unsigned char p_Under_Onl ~]= ~ 0, 0xlB, 0x2D, 0x01, 0, 0,
O, O, O, O };
unsigned char p_Under_Offl[]= ~ 0, 0xlB, 0x2D, 0, 0, 0, 0,
O, O, O };
unsigned char p_Under_On2 []= ~ 0, 0xlB, 91, 52, 109, 0,
10 O, O, O, O );
unsigned char p_Under_Off2[]= ( 0, 0xlB, 91, 48, 109, 0,
O, O, O, O };

int p_QSCR_Screen; /* Thisis a QSCR, now displayed
*/
unsigned char p_Save_LP[3]; /* Saves Light Pen coord~
when deleting */

int p_Help_Page_Nbr; /* Number of the Help page(start
with 0) */
int p_G_Help_Page_Nbr; /* Number of the Generic Help page
*/ .,
int p_First_Help EXTVAL3(TRUE); /* First Help page yet to
be displayed */
unsigned char p_Save_Help_Fn_Char; /* See
P_Get_Help_Fn_Char */
int p_Save_Help_Fn_Nbr EXTVAL3(0); /* for complete
description, see */
unsigned char p_Save_Help_Fn_Attrl EXTVAL3(0x6F); /*
Phelp function */
unsigned char p_Save_Help_Fn_Attr2 EXTVAL3(0x67); /*
description. */
int p_Save_Help_Flag; /* Indicates that Top Line was */
/* "Displayed" when screen saved ...
35 */
/* for Help mode
*/




.. :. , . ~:

WO91/00575
~ PCT/US90/03878
~ - 167 - 2~

int p_Start_Help_Soon_SW EXTVAL3(FALSE); /* Requests the
interrupt routine */ .
/* to start Help mode
*/

5 int pp; /* universal for loop variable
*/
unsigned char pchar; /* CBT copy of G~key(char~
just typed */ - .
unsigned char ppchar; /* Temporary copy of pchar
10, */
unsigned char pchara; /* Another copy of pchar
*/
int p_PS2_SW EXTVAL3(FALSE); /* Indicates PS2
computer */
.int p_80col_SW EXTVAL3(FALSE); /* 80 or 40 cols.
switch */
int p_Cols EXTVAL3(40); /* Number of cols on
the screen(40 or 80)*/
unsigned char p 80col_cols EXTVAL3(40);/* Num of cols on
the scr(40 or 80)*/
int Mode_80_Column_SW EXTVAL3(FALSE); /* Switch,
indicating 80 cols,if-TRUE*/
unsigned char p_General_Mess[40*22]; /* Stores ST9.PEW
messages */
unsigned char p_General_Mess_A[22~; /* Stores ST9.PEW
attributes */
int p Temp_Size; /* Contains PSZE (2000)
*/
int p_Format SW EXTVAL3(FALSE); /* Switch indicating 80
cols. */
int p_MIS Start; /* First set when starting MIS(Student
or Author) */
int p Startup Flag EXTVAL3(FALSE); /* This indicates that
it is system */
/* startup
*/ ..



- . . .. . .... ~ , .. . .. . -

WO91/00575 PCT/US90io3878
.~", ' ~
- 168 -

int p_Stop_ MI5_ Temp_SW; /* Stops MIS from talking to the
Control Loop */
/* while on page 2 or Help mode
*/
int p_Save New_Cursor_Loc;/*Cursor pos. saved from
MIS(going to.p.2) */
unsigned char p_Save_Buf[480]; /* Working buffer
*/
unsigned char p_Color_Menu[100]; /* Displayed in 25th row
in Color Mode */
int p_Save_p_From; /* Save p_From_Ptr_Sel, for
recording */
unsigned char pnumbf[16]; /* Working buffer for Exercise
name, from screen */
15 #ifdef CBTMAIN
unsigned char pnames[] = " "; /* Edited, saved
Exercise name */
#else
extern unsigned char pnames[] ;
20 #endif -.
unsigned char p_Buf[160]; /* Working buffer
*/
unsigned char p_Extra_Buffer[24];. /* Working Buffer
.*/
25 unsigned char p_Working_Buf[80]; /* Working Buffer
*/
unsigned char p_Save[20]; /* Working Buffer
*/
unsigned char p_S 25th[80]; /* Buffer for saving 40
30 chars.in 25th row*/
unsigned char p_Save_25th_Sc_Del[80];/*Buff for saving 40
chars in 25th row*/
unsigned char p_Save_25th_Buffer[80];/*Buff for saving 40 r
chars in 25th row*/
35 unsigned char p_Insert_Save_Buffer[12]; /* Saves screen
for Insert message */
unsigned char p_Page_No_Chars[20]; /* Buffer for screen
page no. */




- - , : - .. . ,. ,: : :. : .

WO91/00575 PCTiUS9U/03878
~ - 169 -2~$~ ~

unsigned char p_Insert_Name[12]; /* Buffer for Insert
screen message */
int p Dir_Count; /* No directory entries */
unsigned char p_STO_Rl9_Err_Mess[50]; /* Error message on
STO.PEW, row 19 */
unsigned char p STO_R20 Err_Mess[50]; /* Error message on
STO.PEW, row 20 */
int p Error_Code; /* Error code for trouble shooting
disk problems */
int p_Error_Cnt_OK_SW;/* Allows Errors to be counted
*/
int p_CurLPCol; /* Copy of CurLPCol */
int p_Ptr_Adjustment; /* Adjustment for Light Pen
Cursor */
int p_Dir_Pointer_Ok; /* Ok to use LP on Page 1 */
int p_Dir_Scroll_Row EXTVAL3(0); /* Start on row 0 of
Directory, Page 1 */
int p_Only_STT; /* Switch to only allow display of
Default.pew */
/* (on page 4) */
unsigned char p_New_Name[] EXTVAL3(" "); /* New
name for RENAM~, etc */ - -
int ptrace; /* Debugging trace switch
*/
int pcolorl EXTVAL3(1); /* Flag to cause 25th line on "M"
series */
int p Insert Page_SW EXTVAL3(0); /* Modify mode, ready to
insert screen */
unsigned char pdisk EXTVAL3('B'); /* Recording &
Playback disk drive */
int p Dir_Ok EXTVAL3(FALSE); /* Allows display of
directory(Page 1 & la) */
int p Dont_Poke; /*-Flag for Pdispr indicating Don't
poke */
int p Only_Poke; /* Flag for Pdispr indicating Don't
copy */
/* to ptbuff[] */




~: '' ' - :: : : :

WO9lJ00575
. PCT/US90/03878

2~6~ 170 -
int p_First_Compare_Out; /* For future compression -
Unused */
int~p First_Compare_In; /* For future compression -
Unused */
REMOTE MODE
int p_Int_MIS_Remote_Flag EXTVAL3(FALSE); /* This Flag is
set TRUE only by */
/* the CBT Pmasterm, at initialization, after
first */
j* starting with MIS. When return from
subsequent */
/* sessions as MIS terminal, it is used to send
an */
/* interrupt to MIS each 30 secs. This is to
keep */
/* the RT1215 awake. It is checked in Ppewint20
*/
/* These are for timing p_Int_MIS_Remote_Flag
20 */
unsigned int p_Remote Off_Key Reset;
unsigned int p_Remote off Key_High;
unsigned-int p Remote_Off_Key_Low;
unsigned int p Remote Off Key_Intv;
unsigned int p Remote Int Intv;
unsigned int p MIS_Off_Xey_Reset; -
unsigned int p_MIS Off Xey High; ,
unsigned int p_MIS_Off_Key_Low;
unsigned int p MIS Int Intv;
i
/*--p Cursor_Table[] is the basic Cursor control for the
Error ------*/
/*--Selection Menu in Modify mode or page
4 */
/*--p_Cursor_Tablel[~ then is used to provide a modified
copy
/*--which depends on whether or not an error display is
used with----*/

WO91/00575 PCTiUS90/03878

- 171 -
2 ~ 9 ~
/*--the menu. Each pair of entries provides the first
location and---*/
/*--the last location of a
(screen)field.----------------------------*/
S /*======--================================================_
============*/
#ifdef CBTMAIN
int p_Cursor_Tablet] =
- 40*4+22, 40*4+37,
40*5+22, 40*5+37,
40*6+22, 40*6+37,
40*7+22, 40*7+37,
40*8+22, 40*8+37,
40*9+22, 40*9+37,
40*21+37, 40*21+39,
40*22+33, 40*22+35,
40*22+37, 40*22+39,
40*23+26, 40*23+26,
40*23+28, 40*23+35,
40*23+37, 40*23+39,
l\

_ ~
___ /
int p_Cursor_Tablel[~ = {
40*4+22, 40*4+37,
40*5+22, 40*5+37,
40*6+22, 40*6+37,
40*7+22, 40*7+37,
40*8+22, 40*8+37,
40*9+22, 40*9+37,
40*21+37, 40*21+39,
40*22+33, 40*22+35,
40*22+37, 40*22+39,
40*23+26, 40*23+26,
40*23+28, 40*23+35,
40*23+37, 40*23+39,
'\O'

W091/00575 PCT/US90/03878

- 172 -
,; , .
2~ }

#else
extern int p_Cursor_Table[] ;
extern int p_Cursor_Tablel[];
#endif

int fpin_SW , fpinl SW , fpin2_SW , fpin3_SW , fpin9_SW ;
int fpinx_SW , fpto_SW , fptol_SW , fpto2_SW , fpto3_SW ;
int fptox_SW , fptoy_SW ;
FILE *fpin, *fpinl, *fpto, *fptol;
FILE *fpin2, *fpto2;
FILE *fpinx, *fptox;

#ifdef CBTMAIN else extern unsigned char []
unsigned char p_File_Name mas[] = "MAS.PEW ";
unsigned char p_File_Name_masl~] = "MASl.PEW ";
unsigned char p_File_Name mat[] = "MAT.PEW ";
unsigned char p_File_Name_matl[] = "MATl.PEW ";
unsigned char p_File_Name_mar[] = "MAR.PEW ";
unsigned char p_File_Name_sys[] = "SYS.PEW ";
unsigned char p_File_Name_sysl[] = "SYSl.PEW ";
unsigned char p File_Name_syt[] = "SYT.PEW ";
unsigned char p_File_Name_sytl[] = "SYTl.PEW ";
unsigned char p_File_Name_syr[] = "SYR.PEW ";
unsigned char p_File_Name_rec[] = "REC.PEW ";
unsigned char p_File_Name_recl[] = "RECl.PEW "; -
unsigned char p_File_Name_spc[] = "SPC.PEW ";
unsigned char p_File_Name spcl[] = "SPCl.PEW ";
unsigned char p_File_Name_hlp[] = "HLP.OOO ";
unsigned char p_File_Name_sto[] = "sto.pew ";
unsigned char p_File_Name_stol[] = "stol.pew ";
unsigned char p_File_Name_st9[] = "st9.pew ";
unsigned char p_File_Name_st91[] = "st91.pew ";
unsigned char p_File_Name_stO[] = "stO.pew ";
unsigned char p_File_Name_stOl[] = "stOl.pew ";
unsigned char p_File_Name stl[] = "stl.pew ";



: .
,:: ' '. ' ~; , . ~ , '

.. . . . .. . .

WO 91/00575 PCr/US90/03878
~s - 173 - ~

unsigned char p_File_Name_err[] = "err.pew "; /* Stu >
errs allowed*/
unsigned char p_File_Name_lst[] = "lst.pew ";
unsigned char p_File_Name_doa[] = "doa.pew ";
5 unsigned char p_File_Name_ctr[] = "ctr.pew ";
unsigned char p_File_Name_asc[] = "asc.pew "; /* ASCII
& Color Window */
unsigned char p_File Name_lp[] = "lpw.pew "; /*
Pointer change window */
10 unsigned char p_File_Name_chp~] = "STR.HLP ";
unsigned char p_File_Name_dmo~] = "DEMO .000";
unsigned char p_File Name_fil[] = "fil.pew ";
unsigned char p_File_Name_fill~] = "fill.pew ";
unsigned char p_File_Name_tch[] = "B:tch.pew "; /*Disk
15 No. will be set=pdisk*/
unsigned char p_File_Name_exc[] = "B:exc.pew "; /*Disk
No. will be =pdisk */
unsigned char p_File_Name_file[]="B:xxxxxxxx.tut";/*Disk
No. will be=pdisk*/
20 unsigned char p_File_Name_r901[] = "CBTREGl.SCR"; /*Disk
No. will be set */
unsigned char p_File Name r900[] = "B:CBTREG.DAT"; /*Disk
No. will be set */
unsigned char p_File Name_d900[] = "B:CBTDIR.DAT"; /*Disk
25 No. will be set */
unsigned char p_File Name cdat[] = "B:CBTCRIT.DAT"; /*Disk
No. will be set */
unsigned char p File Name 4080[] = "XNEW.SCR"; /* Option
screen */
30 unsigned char p_File Name 801[] = "SPLIT.TDS"; /* Split
screen shell */
unsigned char p_File Name stt[] = "default.pew "; /*
Default display which*/
/* DEFAULTX.TDS or DEFAULTS.TDS are copied into
*/
unsigned char p_File_Name_d901[] = "CBTDIR.SCR"; /*Disk
No. will be default */




"' " ' '.1~ . :, . ' ..' ,:
; . . : ', ~., . ~. , : .

WO 9l/00S7~
PCr/lIS90/03878
174 -

unsigned char p_File_Name_s4x[~ = "CBTS4X.SCR"; /*Disk
No. will be default */
unsigned char p_File_Name_cscr[] = "CBTCRITl.SCR"; /*Disk
No. will be dfault*/
5 unsigned char p_File_Name_dir[] = "STP.PEW "; /*
Directory shell, page 1 */
unsigned char p_File_Name_dirl[] = "STD.PEW "; /*
Author's Directory shell */
unsigned char p_File_Name_shel[] = "STB.PEW "c /* Screer
10 shell for STD.PEW */
unsigned char p_System_Dir[] = "DIR A:*.O00>TEMPDIRP.$P$";

27. MESSAGES

unsigned char p_Wait_Mess[] = " Please wait a
moment ";
unsigned char p_Complete_Mess~] = " Complete ",

28. FILE NAME WORKING BUFFERS

unsigned char pd[l~];
unsigned char pdhelp[l6];
20 unsigned char prr[8];
unsigned char pdd[16];
unsigned char pdap[20~;
unsigned char pdapx[20];
unsigned char pdapxa[2o];
unsigned char p_FCB[260];
unsigned char p_FCB_Data[260];
unsigned char p_FCB Extra[260];

unsigned int pint;
30 unsigned int ptimerl, ptimer2;
unsigned int ptimerlf, ptimer2f;
long int pclock, pclocks, pclockt;
unsigned int pClock_High;
unsigned int pClock_Low;



:. :

.,
,

W091/00575
- - PCTtUS90/03878
.. - 175 ~ 2~89~ ~

unsigned int pDate_Reset;

int p Spec_Int_24H[2];
int p S aved_Int_23H[2];
int p Saved_Int 24H[2];
int p Seg Saved;
int p_Seg_Savedl;
int Error_24H_Code ft;

unsigned char p_Block_Mark_Name[12];
unsigned char p_Block_Move_Name[12];
int p_Block_Move_Enable EXTVAL3(FALSE);
int p_Insert_SW EXTVAL3(FALSE);
int p_Block_Move_Flag EXTVAL3(FALSE);
int p_Block_Move_Start EXTVAL3(FALSE);
int p_Block_Move_End EXTVAL3(FALSE);
int p_Save_Block_Start EXTVAL3(FALSE);
int p_Save_Block End EXTVAL3(FALSE);
int p Save_For_Insert EXTVAL3(FALSE);
unsigned char p_Save_Move_Char EXTVAL3(FALSE);
int p_Save Move Loc EXTVAL3(FALSE);
int p_Block S C EXTVAL3(0);
int p_Block S R EXTVAL3(0);
int p_Block_E_C EXTVAL3(0);
int p_Block_E R EXTVAL3(0);
int p_QSCR_W Disable SW; /* Disables special option for
QSCR W, */
/* temporarily. -*/

int p Save_Screen Type_D$;
int p_Save_Have_80 Columns;
int p Dont_Convert; /* Don't convert going from Control
Loop system */
int G$0ffset_40;/*This is always the current screen
buffer location*/
int Screen Type_D$ ;
int Backup_G~RowMap[26];

WO91/00575
PCT/US90/03878
176 -

ern char Color_Attributes[];
extern char Mono_Attributes[];

unsigned char far vbuf[32768] ; /* allocates memory for
5 vbuf */
unsigned char far course_dir[700][80]; /* allocates
stu.dir.mem */
unsigned char critique buffer[320]; /* critque buffer
memory */
unsigned char far vbuf2[65536]; /* vbuf2 memory allocation
*/
unsigned int vbuf_segment; /* poke/peek need segment and
offset */
unsigned int vbuf2_segment; /* find the seg/off */ r
15 unsigned int vbuf_offset; /* for each of these far
arrays */
unsigned int vbuf2_offset;

union REGS Inregs_ft;
20 union REGS Outregs_ft;
struct SREGS Segregs ft;
unsigned int Save Int_Seg_ft EXTVAL3(0);
unsigned int Save_Int_Loc_ft EXTVAL3(0);
int Error_24H_Code_ft EXTVAL3(0);
extern int INT_24H_PROG_FT;
extern int INT_23H_PROG;

30 int Ret_ft EXTVAL3(0);
char Paul_fttl0] EXTVAL3(~ 0




, ~ '' ':

~ .

WO 91/00575 PCr/US90/03878
~ - 177 - 2~

unlon
char byts [ 4 ];
int wrds [ 2];
int ( *ptr);
) Spec_Int_ 24H_ ft_s EXTVAL3(( 0 ~);

union
char byts [ 4];
int wrds [ 2];
1 0 int ( *ptr );
~ Saved_Int_ 24H_ ft_s EXTVAL3(~ 0 ));

unlon {
long byts;
int wrds [ 2];
int ( *ptr);
) Spec_Int_ 24H_ ft_p EXTVAL3({ 0 });

union {
long byts;
int wrdst2];
-- int: ( *ptr);
) Saved Int 24H ft p EXTVAL3({ 0 ));

union {
long byts;
int wrds [ 2];
int (*ptr);
} Spec_Int 23H p EXTVAL3({ 0 ~);
union {
long byts;
int wrds ~ 2];
int ( *ptr);
) Saved_Int_ 23H p EXTVAL3({ 0 });

union {
long byts;


, . . : : :, -: ... ..

. :, . :,,:, . ., . : ::: . .

WO91!o0s75 . PCT/US90/03878

178 - -

int wrds[2];
int t*ptr);
) Spec_Int_23H_s EXTVAL3(( 0 ));

5 union
long byts;
int wrds[2];
int (*ptr); ",.f
) Saved_Int_23H_s EXTVAL3(( 0 ));
' 10 '
unsigned char window_borders[5] ;
struct disp_window
unsigned char display[9];
~ *thestruct, *newstruct, display_array[500];
int filecnt EXTVAL3(0) ;
unsigned char window_line[80];
int window_count;
unsigned char p_Window_Background;
int Top_Of_Window ;
int Pos_In_Window;
COURSE DIR
int rec count; /* count of actual courses in directory */
int Window_Top; /* offset value in file of one now at top
*/
int Window_Pos; /* bar offset location in window */

unsigned char edit_mode EXTVAL3(0) ; /* (D)elete (I)nsert

(R)eplace (S)ave */
unsigned char multiple EXTVAL3(0); /* flag for whether
action is single screen (TDS) or multiple (000)
*/
unsigned int edit_mode_old_block_ptr EXTVAL3(0) ;
/* location in original file when edit mode
entered */
long int edit_mode_new_block_ptr EXTVAL3(0) ;
/* location in .100 mod file when edit mode
entered */


- ' . :,: ,' : ' -


. ~ , .
' : . '' ' .

WO91/00575 PCT/US90/03~78
..,
; - - 179 - 2~9~1

long int edit_mode_old_block_nbr EXTVAL3 ( O );
unsigned char reset_file_to_start EXTVAL3 (O) ;
/* for resetting multiple edits to start of file if
refused at pgl */
L. Global Variables Header File
The Management Interface (40) communicates with
the CBT through the use of standard ASCII files, thus
making it possible to provide customized management. The
files that provide this interface for khe current
embodiment are the course directory (36) and the critique
(38).
Currently, the management system is envisioned
as one that puts together exercises into course modules
and prepares diskettes with those courses linked together
by ASCII file that is the course directly. The format of
the file is listed in this document. When students use
the diskettes, they update the course directory which then
is imported back into the management system to update any
files on the courses and or students. The critique file
is attached to the same diskette as there is one per
course.
Defaults 70 and control file information could
also be handled by the management system.
How developed a management one may wish to
create depends upon one'$ needs. It is easy to develop
rosters, scheduling, and complete business-wide courses
modules for different user-types.

N. Generic Recorder Code

VI. SECOND PREFERRED EMBODIMENT
FIG. 2' describes a second preferred embodiment
having essentially the same functionality for CBT 12. The
second embodiment is substantially the same as the
embodiment shown in F~G. 2. However, the keyboard input
is localized within the functions. Also, there is a non-
linear exercise flow that is most noticeable in the
process of modifying an exercise.




.~. . ~ .. ' . ' . '.. ! . . ..

wo 9l/oos~ `
PCT/US90/03878
; - 180 -
Thus, as shown in FIG. 2', modify 46' has been
moved into a direct association with author Menu 20'.
Print 45' also moved because it too no longer requires a
linear flow. Both had been part of playback 22 in FIG. 2.
In addition, several of the features of modify 46'
are renamed to better describe the user options. The LPW
~7, selection error 48, and typing error 50 on Figure 2
are now embodied in cursor information 1303 in Figure 2',
the-second part of a screen's information 1301.
Defaults 70', while unchanged, is moved to visually
establish the optional link to the management interface
40'. A suggested implementation would allow users to
modify these defaults by changing the values on an input
screen and a logical place to do so would be within
management interface 40'.
Another difference is the addition of one new
playback mode called test playback 31. This form of
playback allows building a log of answers to be used for
item analysis, as is described in detail later. Most
changes in the second embodiment can be considered
improvements in implementation or improvements for ease
of maintenance, rather than a change in functionality.
For example, the original system uses QSCR modes to
identify the playback mode in which an exercise screen
would be available. This required entering the letters
QSCR in the upper left hand corner of a screen along with
a one-letter code. In the second embodiment, a window
allows the author to simply answer "Y" for yes or "N" for
no to determine whether the screen will be available in
any particular mode.
Another improvement is that additional feedback or
error messages can now be created for an individual
screen, allowing a better interaction with the user. This
includes branching the user to another screen based upon
their answer. However, the error process itself is
unchanged.
The first embodiment had 19 modules coded in
the "C" programming language, all named CBT xx with xx

~UBS~ UrE SHEET

- . `: .
; i . . .

WO91/00575
PCT/US90/03878
- 181 - ~ 0~
being the sequential number. The alternative approach
categorizes the functions and places them into modules
named for the category. Thus, the modules in the second
embodiment have the names modify.c, playback.c,
keyboard.c, help fns.c, etc.
Additionally, many variable names have been changed
to give a clearer description of their use. Other state
variables that were used to return users to the proper
place when the centralized key or pointer event occurs are
not necessary when the events are more local to the
function.

A. Non-linear Impacts
~ To allow users to follow a more random path
through an exercisej the second embodiment changes the
processing of exercises. Rather than accessing a large
block of the exercise at a time, only the desired screen
is accessed. Thus, the user decides what screen is wanted
next and that screen is found and displayed. To simplify
and speed up this process, the header information attached
to the screen has been expanded, and an index has been
attached to the start of the exercise. User selections
made from the index expedite locating a screen within the
exercise file. The processing of a screen in playback 22'
is, however, essentially the same once the proper screen
is found.
As before, all basic screens are compressed for
storage and decompressed when displayed. Data
compression and decompression algorithms remain the same
in both embodiments.
B. Exercise File Layout
The crux of the changes can be found in the
extended screen header, the new index, and the exercise
header located at the beginning of the exercise file. As
stated before, these changes are primarily to allow more
feedback/error messages to be saved for each screen and to
allow a more user friendly way of getting the same

5'.'BSTITLITE SHEET



- ~

W O 91/00575
P(~r/US90/03878
182 -
information (such as which modes as exercise scréen will
be displayed in where the value is now in the header and
index and not on the screen itself as the previous QSCR
example showed).
The exercise file 10' now begins with 16 bytes
called an exercise header, which can be used for any
specific needs. The second embodiment uses the first byte
to store the number of the screen that starts the exercise
and the second byte to identity the type of application
that was recorded or exercise created. The other 14 bytes
are reserved for future potential uses.
Following the exercise header is the index.
There is a 16-byte record for each basic page in the
exercise followed by a null record indicating the end.
The 16 bytes are broken down as follows:

0 ID of the screen
1-8 Name of the screen
9-12 Size of the block
13 Next Screen
20 14 Display Modes
Status :;
As exercises need-not be linear, the author can
quickly move to the intended screen by giving each screen
a unique identification number and, if desired, a name.
These are the first bytes in the index. The size of the
screen block (including error messages and other screens
attached to it) is kept in a four-byte long integer. The
next byte identifies the next screen to be retrieved.
Display modes is a byte that, based on its value,
identifies the modes in which the screen is visible. If
the index value shows the screen is not visible in the
current playback mode, the screen need not be retrieved
and decompressed. Instead, the display merely advances to
the next screen as specified in the index record. The
status byte is used to indicate the screen originally
stored has been changed. A "D" for deleted or "R" will
result in skipping that screen when the file is rewritten.

~s~lTl~!T- 5~EE ~`

W091t00575
2 ~ 6 ~ ~ 9 PCr/US90/0387~8
- 183 -
If the screen was replaced, the new screen with the same
ID is inserted in the modified file when the file is
rewritten. The status byte is only changed in modify 44,
and, once modified, the exercise will have a null in all
status bytes used for playback purposes.
The bytes in the index are also found in the
-individual screen headers. The size found in the index
covers the basic screen and all of its parts, including
any typing records, error or feedback messages, overlay
windows, or extra edit screens. Each of these screens has
its own header with its individual size included. The
total is-the block size -- the number of bytes to be read
to bring in the whole-basic page and its parts.
The individual screen header has been expanded
from 22 to 48 bytes to include five sets of answer-
feedback blocks instead of just one. These 48-byte
header records are as follows:

0 ID of the screen
1-8 Name of the screen
9-12 Size of the screen
13 Screen type
14 - Video type
Next screen
16 Display modes
17 Cursos row
18 Cursor column
18-22 A five-character array of rows
24-27 A five-character array of columns
29-33 A five-character array of correct flags
34-37 A five-character array of feedback ids
38-43 A five-character array of quadrants
44 A branched flag
A backup o.k. flag
46 Number of tries allowed
47 An exact flag
Screen type identifies the type of record being
read, which can be the seven allowed for the basic page

~;UBSTITUTE SHEE r

WO91/00575
PCT/US90/03878
L ; - 184 -

(Selection, Typing, Multiple Choice, Sequentialj Binary,
Any Key, or Timed) or a selection error, typing error,
extra edit screen, or an overlay window.
Video-type specifies a video mode for the
screen (40 for 40 column, 80 for 80 column, and 1'G" for
graphics).
Next screen and display modes are as duplicates
of the same values in the index. The cursor row and
column identify where the cursor would go on the screen
if a visible cursor is desired.
In the first embodiment, there is one row-
column combination to identify the proper selection to
leave a screen referred to as the 'action key.' Recall
that function keys use a row 25 designation and the key
value is then found in the column value. In the second
embodiment, up to five combinations are allowed to permit
the author to designate alternative selections. These
combinations can be anticipated errors, which can then
get a separate and more interactive feedback message.
Alternatively, some combinations may be used to
accommodate more than one right answer. The array of rows
and columns holds those alternatïve selections, the array
of feedback values holds the feedback message that goes
with the selection. The correct array indicates whether
the selection is correct or not for scoring purposes. The
quadrant array indicates where on the screen the message
will be displayed, although both embodiments currently use
the same default location.
Note that most of those screen header values
are found in the first embodiment, but in a format that is
more difficult to maintain. For example, in the first
embodiment, the video type is combined with the row value
of the selection and is deciphered; the screen type is
found in a numerical record type byte, and the size is
two-bytes (which may not be large enough for potential
future uses).
A further embellishment over the first
embodiment involves an extra use of the multiple feedback

SU~aST~T'~ S~E~

WO 91/0057~; PCI`/US90io3878

~- - 185 - 2~ ~ a ~F~
.
feature. This capability allows authors to indicate that
users should be branched to another screen based upon
their answers rather than based upon a feedback window.
By setting the value in the header called "branched" to
"yes," the feedback window array will be interpreted as a
screen to go to, rather than feedback window to display.
The backup block flag allows authors to make it
impossible for students to backup past this screen.
Number of tries overrides the default value for any
exercise on an individual screen. Exact is a code for
type-ins that indicates whether type-in answers should
exactly match the expert's type-in in order for the answer
to be judged correct. These are also not new values as
the original did use number of tries and had a flag in the
type-in error window to identify the exact match.
In summary, the file layouts were changed to
make CBT 12 easier to maintain and to make the most
efficient use of the non-linear approach to the files.

C. New Features
There are a few features added to the
functionality of the first embodiment. One such feature
involves the-use of overlay instructional windows. This
new screen type can be added to each screen block to allow
a window of information to be created and displayed over
the basic screen in playback 22. The student can then
toggle that window on and off. This new feature allows
authors to add instructional information without
destroying the basic underlying screen.
Another new feature is an item analysis test
exercise. This exercise requires students to answer all
questions and keeps a log of the answers. This-log can be
used to review the answers of students. The log also
provides authors with better summary information, e.a.,
how many students answered each question correctly, and
what were some of the common errors. This information is
to help authors tailor their exercises, to improve the



. . ~,

WO91/00575 PCTtUS90/03878
.~ . :..
~ `$~ - 186 - -

areas where errors occur most, or to tailor the test
questions themselves.
The code [provided in the Appendix] also
includes a suggested control program that has links to
S other applications. Control program acts as the parent
program. Issues such as security which could limit user
access can be handled here. Control Program can
selectively determine how'users connect to other programs
and other computers. Control program can also be used to
link to the management interface 40 or to connect to the
recorders. Such controls provide flexibility for
tailoring the system to meet each user's needs.

D. Playback
Reflecting the changed exercise file and the
non-linear flow allowed, the playback process illustrated
in FIGS. 22 and 23 is changed as shown in FIG. 22', which
uses the same numbers as 22 and 23 where relevant, except
that the apostrophe ""' is used as a suffix to distinguish
between the embodiments.
Figure 22' begins with open file 502', which is
now followed-by read'control file data 1230. The latter
step reads~the index for the exercise and the exercise
header information, as previously described.
The outside processing loop now begins with find
screen 1232. Find screen 1232 looks in the index for the
offset location of the screen desired (at the beginning of
the exercise, it is the start screen from the header).
The index record for that screen reveals which display
modes are specified. :Next screen display = playback mode
1234 checks whether the playback mode is allowed. If the
playback mode is not an allowed mode, the logic proceeds
to set next screen branch 1236. In the index record for
the current screen there is the value of the next screen
it will call. The desired screen is set to that number
and that screen is searched for in find screen 1232. This
1 ~n~ W; 11 stoo when a screen that has a mode that matches




.
. :: .,: -,
' : ; . ~, ,, ' ~ . ' " .:
- ~ -. ,

WO91/00575
PCT/US90/03878
~` - 187 -
If the screen is allowed for display, the logic
goes to read header bytes 530', which reads the actual
screen data stored in the header bytes. Next, in read
through 1238, there is a test to determine if the read is
successful. If not through reading, the logic gets the
size of the record from the header, in block 534'. The
logic reads that many bytes and decompress the data in
block 536'. The header bytes tell where to put certain
information. If the screen is a basic page 1239, the
block read moves to the screen 1241 and the logic returns
to read header bytes 530'. If not a basic page, the logic
checks if the screen is a selection error in block 508'
and, if so, the screen is moved to error buffer 510'.
Otherwise, the logic checks if the screen is a typing
record in block 514'. If it is, the screen is moved to a
typing buffer in block 516'. If instead the screen is a
tvping error, block 1240 would place the screen in typing
error buffer 1242. If the screen is an overlay window
record, from block 1244, the screen is sent to overlay
buffer 1246. If the record is the last record 524', the
exercise is complete and the system returns 526'. All of
the other options return to read header bytes 530' for the
next record until all bytes for that page block have been
read and read through 1238 gives a "yes."
At this point, if in automatic mode 546',
automatic playback 24' is called. If in manual mode 548',
manual playback 26' is called. If in instructional mode
550', the logic goes to instructional playback 28', and if
in proficiency mode 552', proficiency playback 30' is
called. If in test mode 1248, test playback 1250 would be
called. After processing the screen, the logic returns to
set next screen 1236 to retrieve the next screen.
As noted earlier, more than one error message
can be saved for each screen. The author can select up to
five anticipated answers for which a different message can
be displayed. Thus, FIG. 26, items 586 and 596, and
FIG. 27, items 614 and 628, Display Appropriate Error
Messages/++Errors would select the appropriate error

~UBSTITUT' SHEET

., .".,` ,`

., ., "

WO9~/00~75 ~ PCT/US90tO3878
! 188 -

message based upon the user selection. If the selection
matched one of the anticipated answers, the feedback
window attached to that answer would be the appropriate
one to display.

E. Print
With the addition of screen identification and
non-linear flow, the number of screen printouts that can
be helpful to the user grows. Thus, FIG. 28, which
described the printout of an exercise, has been extended
to FIG. 28', which provides four different reports. The
user can print a full exercise, which includes all
information about the screen, in either screen ID order,
or in exercise "flow" order (i.e., the start screen
followed by the screen that it calls, etc., essentially
building a linear exercise as in the first embodiment).
In addition, the user can print just the screens or just
the summary information. The print process, however,
remains the same for all four report options as shown in
FIG. 28'. That is, the logic must find out which screen
to get next (ID or flow) and which value(s) to print once
the screen has been retrieved.
In FIG. 28', printing begins by opening the file
in block 1252. Then get control information 12S4 examines
the index and sets the screen to the first screen. Once
that is accomplished, a main control loop begins.
The question ID order 1256, if answered yes,
will get the next ID in block 1258 before proceeding to
the end of file test in block 1260. If the question ID
order block 1256 is answered no, next screen 1262 will
find the next screen in the flow based upon the next
screen flag in the current screen header, before
performing an end of file test in block 1260.
If block 1260 finds that it is the end of the
file, at return 1264 the logic returns to the author menu
20. Otherwise, the logic proceeds to read in screen
information at block 1266. once the screen is found, if




. . -

: -....... : , ~ .. . .: , -
,. :: . .

WO9l/00575 PCT/US90io3878
189 ~

screen 1270 is called and the user is returned to the
print control loop. Otherwise, the print summary
information block 1272 is called. Once the summary
information is printed, if the report is summary only, as
tested in block 1274, the user returns to the print
control loop for the next screen. If the report is not
summary only, the logic will call print screen 1276 to
print the screen. Next, the logic will proceed to test
whether other information exists on the screen that should
be printed. If an error exists, i.e., if block 1278 is
yes, a print errors 1280 routine is called to print the
error message(s). Otherwise, the logic continues to test
for overlays. If an overlay exists at block 1282, the
overlay window is then printed at block 1284. After the
printing, or if no overlay existed, the logic returns to
the main control loop for another screen~

F. Modify 44'
Most of the changes in the way of the CBT 12'
works are implemented in modify 44' and are principally
concerned with making it easier for authors to build and
maintain a non-linear exercise.
However, it is more a change in location, size
and operation for ease of use and not a change in
functionality. The first embodiment has FIG. 2~, which
describes the modify overview; FIG. 30, which describes
the options menu; FIG. 31, which describes the selection
error; FIG. 32, which describes the typing mode; FIG. 33,
which describes the color/ASCII mode; and FIG. 34, which
describes the LPW. In the second embodiment, FIG. 31, 32
and 34 are incorporated into Screen Information FIG. 44
and Cursor Information FIG. 45.
In the second embodiment, the author is taken to
the basic screen desired, rather than being forced to
proceed in a linear fashion. Thus, users are on a page
and from that point can go to: the options menu 52'; the
color/graphics mode 54'; the screen information mode 1301
(the new screen representation identifying the type of


. . .:
., ~ ~ ::: : .

'::: : :'.': . ,: . , : : ":: ::'
' ' ~ '` ' '

;

WO91/005?5 PCT/US90/03878
... ~ ,.
190 -

screen and modes in which the screen is played back); the
cursor information screen 1303, where answers and feedback
messages are created or modified; the go to screen 1304,
from which the user can enter an ID for a screen to jump
to the screen; block mode 1296; overlay window mode 1299;
or a next screen page advancement mode 672'.
To better understand the functioning of modify
44', imagine the author on the first page of an exercise.
The author could jump to modify an overlay window by
hitting the F8 key and would, when finished, be returned
to the first page. The author might then choose the "go
to" function to advance to screen 8. There the author
might choose to amend an error message by selecting the
cursor information (F5).
The second embodiment provides a freer flow
through the exercise than the first embodiment, although
it should again be noted that the functionality is
essentially the same in building the screen.
Figure 29' shows the modify overview. The logic
begins with Open File 1286 followed by Get Control
Information 1288 and Set 1st Screen 1290 so that the
exercise file would then be-open, the index data read, and
the first screen ready to be displayed. The next step,
Get/Display Screen 1292, involves a control loop used when
the screen is to be changed or redisplayed. Once the
screen is displayed, the CBT 12' waits for input 652'.
This wait is another main control point for all modify
actions that do not require a change or redisplay of
screen.
The input returned can be one of 11 conditions.
The first group of activities return to the same screen
awaiting more input. The first test is for color/ASCII
toggle key 696', which calls color/ASCII mode 54' if yes.
The second test shows block mode key 1294 which, if yes,
35 calls block mode 1296. Overlay key? step 1298 calls
overlay Mode 1299 and Screen Information Key 13Q0 calls
screen information mode 1301. If yes, and cursor




' ~:; ' ~; . ' ' ' '. :

WO91~00575
PCT/US90/03878
- 191 2~

1303 if yes. All of these modes are called if their key
was found, as explained in greater detail below.
If it was none of those keys, the CBT 12' tests
if the escape key was pressed in block 698'. If yes, the
user is asked for a verification in block 700'. If
verified in block 702', the system quits at block 704'.
Otherwise, the logic goes back to wait for input at block
652'.
If it was not the escape key either, the next
test is for option menu toggle key 656' which, if
affirmative, calls option menu mode 52'. That choice will
return to Get or redisplay the screen 1292 when completed.
Note that the logic does not necessarily set the next
screen as this can now also be done in option menu mode
52.
Go to Key 1304 and page advance key 672' both
check if a Change Flag Set? 1306 If any changes were made
to the screen, a new block must be written in write new
block 1308. This new block is written to a second file
where modified screen blocks are housed. The index to the
original file marks the screen's record saying it has been
replaced. Whether a change was made or not, these options
would then need to get the next screen to be displayed.
In "go to" it would call set selected screen 1310 to get
the screen number entered, while in page advance 672'
would set to whatever the current page calls as its next
screen.
Mode advance key? 678' handles only the extra
edit screens that are created when a recording receives
screens from the application that were not triggered by a
user action. If an extra screen exists at block 1312, the
screen will be displayed and the logic will proceed back
to wait for input 652'. Otherwise, the logic acts like
page advance, proceeds to set to next screen 1314, and
35 then returns to get/display screen 1292. `-
The remaining test checks typed character 708'.
If a typing character is found, an echo character will be



. . ,:
: - :: :. . :~
-, .. : --
. . .
. . - - .:::, :. .- : . . ::::- :

:: -:: . ,

WO91/00575 PCT/US90/03878

192 -

Otherwise, or after the character has been echoed, users
are returned to wait for input 652' for the next action.
.
G. option Menu Mode 52'
While modifying an exercise, it is often
desirable to bring in additional screens, create new
screens, or delete screens. ~The options menu remains the
gateway to these changes as well as to the ability to
print a part of an exercise. '~
The more localized keyboard functions make
FIG. 30' simpler than FIG. 30 from the original
application. The list directory functions in FIG. 30 are
incorporated into the other functions in the get file name
1316 step. A file name input function provides a list
directory when-the Page Up key is pressed. The user may
then select the file from an acceptable list.
In FIG. 30', when in modify 44', the option menu
will be displayed if the user pressed F2. The CBT 12'
waits for the user to input a key and reads the key in
block 712'. If the key was the option mode toggle key
714', the menu is removed with turn off option mode 716'
and the-screen is reset in reset current screen 1318-
before returning to modify~44'.
If the key indicates a desire to insert a
blank 40-column screen from which the user will then
create a new screen in the exercise, an affirmative answer
to is blank 40-char screen key 750' calls insert blank 40-
column screen 752'. At this point, it is necessary to
reset screen pointers 1320. The screen that had been
displayed becomes the next screen for the new screen
inserted. The screen that had pointed to the old screen
is changed to point to the inserted screen. Now the logic
returns to read key 712'. Is blank 80-char screen key
1322 allows the exact same process as blank 40 but for an
80 character blank screen and calls insert blank 80-column
Screen 1324.
If the answers to the insert blank screen steps




: : . ,. :. ~ . , ~ - :,
: :: ' ' ~:: : .

WO91/00575
PCT/US90/03878
; - 193 - 2~

800'. If yes, the logic proceeds to set number of pages
802' and then to Print 802 to determine what pages to
print. This logic will then print the pages via block
1326. After printing, the system resets the current
screen to the original screen and returns block 718' to
modify 44'. A negative answer ~o is key print? 800' leads
to the next test.
If is key insert 780' is yes, the logic proceeds
to get file name 1316. If the name entered is a valid
single screen name 1328 the system will insert single
screen 1330, which acts like the insertion of blank
screens except that the screen now comes with data. The
logic then proceeds to reset current screen 1318 and
returns to modify 44'. If the screen name is not a single
screen but is an exercise, the system proceeds to insert
exercise 1332 and, after saving the new screens into the
current exercise, resets current screen 1318 and returns
block 718'.
If not the insert key, is save key? 768 checks
whether the key denotes an instruction to save a screen.
If yes, get file name 1334 gets the name of the screen to
save. If a valid single screen name is found in block
1336, the system will go to save single screen 774'. The
logic would then reset current screen 1318 and return 718.
If not a single screen name in block 1336, the logic sets
multiple mode save flag 776 and saves current pointers 776
before act on screen for multiple mode 1338, in this case
saving the screen to a file, and then get/display next
screen 1340 before going back to await a vàlid keystroke
at read key 712'. In a multiple save each screen is saved
as encountered until the Mark command in option menu 52'
is found as described below.
Delete 754' and Replace 760' act much the same
way in setting a mode, acting on the screen, and
displaying the next screen while awaiting a Mark command
to end the multiple action. Is ~elete Screen Key? 754'
calls set multiple mode delete flag - Save Current




:' : : . ' ,'' ~ : :. .

WO9~/00~75
PCT/US90/0387
194 -
multiple mode 1338 and get/display next screen 1340 and
then read key 712' to restart the process. A no in is
delete key 754' brings a test for is replace key? 760'.
Again, if yes, set multiple mode replace flag - save
current pointers 762'. However, when replacing a file, a
file name is needed, hence, the next step is get replace
file name 1342. The logic then progresses to act on
screen for multiple mode 1338, deleting the screen to be
replaced, and then to get/display next screen 1340,
followed by Read Key 712'.
Save, Replace, and Delete are all in multiple
mode if those keys were selected and they await the option
menu key mark as is key m~rk end key 744' to stop. If yes
at block 744, the system checks which option it is. If
multiple mode replace set 1344 is yes, the logic must now
insert new file 1346 and set delete flag on deleted
screens 1348 in the index file before resetting the
current screen and return 718' to modify 44'.
If not replace is multiple mode delete set 1350?
[as set in Step 756] If yes, set delete flag on deleted
screens 1348 and reset current screen 1318 and return 718'
to modify 44'.
If not delete is Multiple Mode Save Set? 1352
If so, close/write new file 1354 of saved screens and
reset current screen 1318 before return 718' to modify
44'.
The only remaining key option that is tested is
page advance key 1356. If not the key designating a page
advance, the key hit was invalid and users loop to read
key 712' for another key. If an advance key a test for
multiple mode set 1358 is required because only that mode
allows this key to be used. If not in multiple mode, page
advance would act as in modify 44'. If multiple mode, it
must take an action on the screen before leaving (in
delete or replace it must flag the screen as being deleted
and in save it must save a copy of the screen to the ne~
file). If multiple and page advanced are true, the system
will act on screen for multiple mode 1338 (save, replace,

~;UB5~T~'--.-- SH~

' : ... ` :

WO91~00575
PCT/US90/03878
- 195 - 2~0~
or delete) and proceed to get/display the next screen
1340. This continues until the mark key stops this chain
of events.

H. Screen Utility
~ The screen utility 56 creates, edits, and saves
single screens. These can be incorporated into exercises
as instructional screens, and are used by the system for
development some of its control files.
FIG. 35 outlines the new Screen Utility 56
processing which is the single screen processing/editing
function. To begin, the user must get file name 1347
which leads to the test valid single screen file name?
1349. If not a valid name the program will loop back to
allow another try. When a valid name has been entered
display screen 1351 will put it on the monitor and the
user input loop then begins at get user input 970'. If
the escape key? 972' the user is returned. If not, the
test is made on whether it is the color/ASCII toggle key
976'. If so, it calls the Process Color/ASCII 54' and on
return proceeds back to get user input 970'. If not
color/ASCII then is it block mode key? 1353. If so, Block
Mode 1355 is called and upon return the user loops back to
970'. If not Block Mode Key 1353 then is it option mode
toggle key 984'. If so, only the save display option is
allowed so display with save option only 1357 will show
the option menu with save highlighted and the only allowed
choice. The save file? 1026 if no loops back to 970', but
a yes tests for a valid file name 1028'. A valid filç
name calls save screen 1030' before remove option menu
1359 and returns to 970'. An invalid file name just calls
remove option menu xxx and returns to 970'. If the key
pressed was not the option menu toggle key, the next test
was for a valid keystrok 1002'. If not the loop returns
to 970' for another key. If yes, display key at cursor
location 1004' will put the key on the monitor and return
for more input at 970'.


SUBSTITU~E SHEE~
- ; ~ , . - ... -.. . - -~ ~- .
.. .. . . . . .. .

, ,- . : ..
... , ... ~ .

WO91/00575 s
PCT/US90/03878
- 196 - ~-
I. Screen Information 1301
Screen Information 1301 centrally houses the
information about the screen itself, including its name,
the location of the next screen in the exercise, the modes
it in which the screen may be displayed, and the type of
screen that it is. Much of the data found in the screen
header and index files for an exercise, the layout of
which was described earlier, is entered here.
At any point in the loop, if escape key pressed
1362 is yes, the logic will go via return 1364 to modify
44'. Otherwise, the first step is to create/modify
screen name 1366. This eight-character name must be
unique, so name already exists? 1368 will return for
another name if yes. Otherwise a no proceeds to
create/modify next screen information 1370. This step
also verifies the existence of the screen selected. In
this case, however, an affirmative answer to screen
exists? 1372 means it is okay to proceed to the next
question, whereas a negative means another screen name or
ID must be entered because a screen cannot be called if it
does not exist. (It should be noted that a screen called
the last screen always exists and can be used as the next
screen holder if the user has not yet decided what screen
should come next -- the user could then modify this at a
later time.
Two types of possible screens are timed
screens, screens displayed for a period of time before
automatically proceeding to the next screen, and any
screens which will advance a user when any key has been
pressed.
Input timed screen 1374 tests whether the screen
type is timed or not. If it is timed 1376 the system will
get time 1378 and skip to enter playback modes 1380 since
the other steps in FIG. 44' affect only screens that have
answers required. If the screen is not Timed, the ne~t
step after block 1374 is input any key screen 1382. An
any key screen 1384 will advance when the user hits any
key. If any key screen 1384 is yes the logic skips to

~UB51~E~ S~EET
,. . -. .. . .. ~... .
:. . . ~.; .. ..
. . . . . :.. : .
.: . ... . -
...
- ~ . :. - . ..

WO 91/00575
2 ~ b ~ PCI'/US90/03878
1 9 7 -- -

enter playback modes 1380. If not, the logic proceeds toinput branched l386 to determine if the screen is a-
branched screen or not. If branched? 1388 is yes, the
flag is set in set branch flags 1390, before going to
input number of tries allowed 1392. A no to branched goes
directly to input number of tries allowed 1392.
Which playback mode a screen will appear in is
handled by entering a Y if yes to each mode. All users
must enter into the enter playback modes allowed 1380
fields although answering no to all modes means the screen
will appear only in modify 44' and not in playback 22'
(this is useful for authors to keep notes). Next step is
to enter up help screen 1394 which is a yes or no prompt
that affects screen playback. This screen will come up
lS when the user asks for exercise-specific help. If any key
or timed screen 1396 are true, the logic loops back to
escape key pressed 1362 to finish the processing.
Otherwise, the logic goes to get screen type
1398. Selection, typing, multiple choice, sequential or
binary are the available types. Because a screen must
have one and only one type, zero or more than one type
with yes?-1400, if affirmative, will send users back to
get screen type 1398, whereas a no will Set Type 1402, as
one valid type was selected, and return.

J. Cursor Information - 1303
Cursor information 1303 is a second part of the
information about a particular screen. The Cursor
information 1303 is automatically brought up after
completion of screen information 1301, when in modify 44'.
Cursor information 1303 is separated from screen
information 1301 so that users can also go to it directly
without going through screen information 1301.
This information pertains to the answers users
make based upon the five screen types found here:
selection, typing, multiple choice, sequential, and
binary. Fundamentally, they are all the same. They all
set a cursor row and column if one is desired. They are

~iUBSTlTUTE 5HEE~

- .., , ;. , . ~ . .


~. . .. .

W 0 91tOOS75
~ P~r/US90/03878

2 set for up to r~ve possible answers with corresponding
flags for whether the answer is correct or not (it is
possible to have more than one correct answer). A
feedback window goes with each answer. The real
differences are in the types of allowable answers ( e., a
selection of an item or entry of some form of typing). In
all cases there is a loop of entry of answers until the
fields are all filled or an enter key is pressed, at which
point a default feedback window is processed. The default
feedback window-has a message that comes if the user
selected something not in the list of anticipated answers
for the screen.
Cursor information 1303 begins by checking
whether the screen is selection type screen? 1406 If so, - -
it does get/set cursor row and column 1408. A five choice
loop test begins with five choices or enter key? 1410. If
no, the logic begins with get answer row and column 1412,
which gets the anticipated answer. Next, get/set correct
flag 1414 is to determine whether the answer is correct or
not. Yes or No. Thereafter, get/set feedback window 1416
puts information into a feedback window for this choice.
More than one answer can have the same feedback window
because each of the up to five possible feedback windows
is identified by a number. The choice is incremented at
increment choice count 1418 then loops to five choices or
enter key 1410. If that is yes, the get/set default
message 1420 is called before a return 1422 to modify 44'.
Thus, each time information on an answer is entered, the
count is incremented until five because five is all that
are allowed.
If not selection screen type 1406, the question
is typing screen type 1424, a screen which expects a typed
message as its answer. If so, it does the same as
selection 1406, except that the answers are strings of
data in get answer typing 1426 as opposed to get answer
row and column 1412. If not typing is it multiple choice
type? 1428, awaiting one of a list of possible choices.
If yes, it is just like selection type screen 1406, except

~U~T~ SHEÇ~T

~' ' ` ' ~ ' ~ ' ' ' ' ` , ' .

W O 91/0057S
PC~r/US90/03878
~ - 199 - 2~

that the answer is stored with a row value of 26 in get
answer row and column 1430. Since 25 in the-row says it
is a function key, to store a letter as an answer, row 26
is used with the code for the letter stored in the column.
Nultiply choice answers tend to be A, B, C, D, etc.
If not multiple, is sequential type? 1432. This
accommodates a matching question and thus requires a row
and column for up to five possible values. Hence an extra
itenrat~the-sta~t-of the loop~, g~t~c~r~or row column for
answer 1434, tells wAere each of the answer fields are.
The answers use get answer typing 1436 because the answers
are like a typing field. Possible answers of matching
AEBCD is like a type in of AEBCD when comparisons are
made.
If not sequential, the remaining choice is
binary type 1438 which is distinguished from selection by
its binary or two-choice option. Thus after getting the
cursor row and column 1408d the choice loop is two choices
or enter key? 1440 as the test.
~0




.: :: ,: .
.. - . ,~. :', , .`. ,. '. : '



:. : ,. .: ~ ,.::: . .:

WO91/00~75
PCT/US90/03878
- 200 -
V 1 '
K. 3270 Recorder
The 3270 recorder 8c is a third embodiment of
the recording methodology. It combines the keyboard
interrupt facilities found in the Generic Recorder 8b with
the emulator-driven screen arrival processing found in
recording emulator 8a to create recordings. This is
useful where users can use an API (Application Programming
I 1~ L /~ o
Interface) to an emulator but cannot actually have access
to the c~.ulator code itself to create recording emulator
8a.
It is not possible to link CBT 12 and a recorder
8c into a single program, nor is it advantageous to link
CBT 12 with any recorder as one program. The memory
constraints of the computer 2 would require such a program
to lose basic functionality since all functions will not
fit in memory without a complicated overlay scheme. In
addition, when code must serve two different masters or
purposes, compromises in design and function must be madeO
The additional maintenance problems and the limits for
growth make a split between recorders and
playback/authoring systems a preferred embodiment.
Such a recorder as 8c is documented in the
following discussion and the related figures. It uses a
3270-emulator from NSA, a commercially available product
called Adapt SNA 3270, to allow recordings of anything the
emulator has access to such as CICS applications on an IBM
mainframe computer. The files created are in a format
readable for playback and modification within the CBT
system.
This embodiment of a recorder has three program
modules: one C module and two 8086 assembly modules. The
C module [~NSAMAGIC.C~] contains code which handles
initialization and setup procedures and also handles most
of the processing required for arriving screens. The
assembly module [(NSAINT.ASM)] contains a replacement
keyboard interrupt handler. This handler gathers
keystroke and cursor information into a buffer which will



. .. .
- - : ~ .-: . , . -. - . . :

- ::. ~ , . . :.

.

WO91/00575 PCT/US90/03878
.
~ - 201 - 2~
code. The third module [{IO.ASM}] contains functions used
in the creation and manipulation of file input and output
(I/O).
To use the API 1902, the user program is sent as a
parameter call to the emulator 1900 program which then knows
to set up the API interface. It sets up software interrupt
100 as the communication channel and messages will go back
and forth through that interrupt code. The user program sets
up how it intends to use the API 1902 by sending some startup
values. As the interrupt is executed, parameters are sent to
the API 1902 and return values may be examined by the C code
as well.
After the initialization and setup procedures have
been accomplished, control is given to the emulator 1900.
The emulator 1900 will remain in control except upon receipt
of a new screen, when control will be returned to the C code.
once the C code has finished processing the contents of the
typing buffer and the new screen, it will return control to
the emulator 1900.
Initialization consists of connecting to the 3270
API and reading and parsing the format table file (FTF) 14c.
An interrupt is executed giving ownership of the display to
the emulator 1900. The next interrupt executed establishes
the initial connection to the emulator 1900. Two additional
interrupts are executed in order to ensure the proper setup
of the emulator 1900.
At this time the FTF file 14c is opened and
parsing begins. If the FTF file 14c cannot be found,
execution of the recorder will be halted. The parsing
routine will try to match the key or token the user has
defined in the recorder's internal key table. If found, the
FTF file's definitions replace the recorder's definitions and
become part of the file the recorder uses to place values
into the exercise file. In this way, the FTF file 14c can
define the name and stored values for any key. The internal
recorder file uses a set of values for standard 3270 keys
that was arbitrarily designed in. Since the PC computer is
not a real 3270-keyboard, and since different emulators ;

~UBSTITU~ 5HEET
.. ... . . . .
- ., . , ~ ~, .- ; ~ . .

.... . .

~, .
. .. . .

WO91/0057S - PCTtUS90io3878
202 -
assign or map 3270-specific keys to different PC keys, the
FTF file is a logical way for the program to know what
value it should store when a key is pressed. For example,
one emulator may assign PA1 to CTRL-J on a PC and another
may use Fl. The FTF file 14c would tell the recorder
which key on the PC equates to PAl so that a PA1 notation
would be stored in the exercise file. (Note that CBT 12
playback needs an FTF file so that the student will hit
the right key for PA1 on his computer).
After the initialization process, a replacement
keyboard interrupt handler is installed. The original
handler address is saved for eventual restoration. The
interrupt handler examines each key and determines what
action to take. If a record key is pressed, the
appropriate flags (i.e., single flag for a single screen,
multiple flag if more than one screen) are set and a
prompt is displayed to ask the user to enter the file
name. Keystrokes defining the file name are placed in a
separate buffer.
The interrupt handler copies the screen data
into a global buffer and a C routine is called to process
either the multiple screen record or the single screen
record.- A multiple screen C routine merely initializes
some variables and returns to the handler. The single
screen C routine initializes variables, compresses the
screen data, stores the data in the large ring buffer
storage area, and writes the contents of the ring buffer
to disk. If the defined file name is a duplicate, the
data is written to a temporary file and, upon exiting the
program, the user is notified of the file via the monitor.
As each new screen arrives the logic is repeated.
After a recording has begun, the handler will
place each keystroke in a typing buffer along with the
cursor location. When a screen arrives and the emulator
gives control to the user program, typing buffer will be
parsed by the C code.


8~1~STrrUTE SH''~

-. : .. ' . .; ~ ... - ;

W091/00575 -
PCT/US90/03878
- 203 - ~ ~ ~ 9 ~

When control is returned to the C code upon
receipt of a new screen, a file name check is made to
determlne that the file has not been opened previously.
If the file name is a duplicate, the user will be asked
5 via the monitor for permission to overwrite the existing
file. If permission is not given, the user is instructed
to restart the recording and assi~n a new file name.
After checking for duplicate files, the screen
is compressed and the screen header elements are definedO
lO A flag is set to indicate that a compressed screen is
ready to be stored.
The typing buffer will be parsed to see if
there are keystrokes to process. A local typing buffer
will be created containing displayable characters. The
15 backspace and left arrow keys are processed only if a
local typing buffer for non-recording uses has been
opened. This is primarily when monitoring user
information such as the file name for the recording. In
all other instances, arrow keys are ignored in the
20 recording procedure. The location of each character is
checked as the Iocal typing buffer. is created. If a
character is pressed that does not display on the screen,
or displays at a location more than one space from the
previous character, this will constitute an automatic exit
25 condition. The activity performed when this condition is
encountered is described in the next paragraph.
While 3270 applications tend to be page driven,
the recorder and CBT 12 are set-up to-allow a more O
detailed `field by field playback and evaluation. Thus,
30 any time the 3270 screen advances to the next field or a
function key that does not display on the screen is
pressed, the recorder will trigger a new screen record.
In this way it can save all of the desired information and
create the tools for authors to tailor the simulation to
35 their needs. They can then give feedback on each entry if
they prefer this to the 'page' nature of 3270, or modify
~h~ ~cordina to allow Daqe processina.



., ,,.." ~, " ,, . 1 ,, ~,


. . .. .
,: ~ .,

W091/00575 PCT/U590tO3878
. ,, ~.
204 ~
As the 3270 emulator 1900 lets the user code -
know a screen has arrived, the typing, buffer will hold
all keys hit since the last 'official' screen change. If,
in evaluating the typing buffer the recorder 1904
discovers a change in location (a new field) or a function
key, it will record the original screen with the changes
to that point and save the screen and the proper header
information in the ring buffer. If typed characters
preceded the record trigger it would write those out in
the typing record, with its header, to the ring buffer. A
default error would also be stored. Thus, it is possible
to have several recorded screens where only one 'real'
screen change has occurred. Again, this provides a way to
maintain an option to do field by field evaluation in CBT
12 and places the recording into line with other recorded
applications for CBT 12.
To save space and match the CBT 12 file layout,
the screen data is then compressed and the screen header
is updated to reflect the number of bytes it requires in a
compressed state.
If the ring buffer is full or the finish flag
has been set after all keystrokes have been processed, the
contents of the ring buffer will be written to the disk.
If the ring buffer was full and the finish flag was not
set, a temporary file is opened to store the contents of
ring buffer to handle this overrun condition. The ring
buffer is written to the file and then cleared for the new
data to come. Because the format of the disk file
requires an index to be stored before any of the
individual screen data, a temporary file is used. The
index is created at the end and the ring buffer and
temporary file are then merged.
When the finish flag is set, a wait message is
displayed on monitor. If multiple screens were recorded,
an exercise header is defined and written. The exercise
screen ID array is updated and written. The last record
index element and a NULL index element are added and the
exercise index is written. A null branch record is

SUBSTITUTE SHEET
, - - , . :
.. .. . .. .... .

; ~ ;` ` "
. ,, - , ~ . ~

WO91/00575
PCT/US90/03878
` - 205 - ~ 8~ -
written and the last screen header is setup and stored in
ring buffer. If a temporary file was used, the data from
that file is written to a defined file. The contents of
ring buffer are then written to the file. All files are
then closed. A "wait" message is removed from the monitor
and a "record complete" message is displayed for a few
seconds. If a single screen was recorded, just the
contents of the ring buffer (i.e., the screen header and
compressed screen data xxx) are written to the file. All
applicable flags are then reset to initialize the
recorder again.
When the user finally exits the recorder 1904
control loop the original keyboard handler is restored.
The user is notified, via a message on the monitor, of any
lS duplicate single screen files. The user must decide to
overwrite or define new file names. The new file names
are also checked for existence and the recorder program
loops until a unique file name is defined.
It should be noted that a more advanced API 1902
might allow users to get keyboard values through API calls
and bypass having to takeover the actual keyboard
interrupt, but the basic operations to achieve a recording
would remain the same.
FIG. 46 outlines the basic steps in the 3270
recorder 8c. The process begins with initialize recorder
2000 which handles the emulator connection and the FTF
file 14c. This leads to Install KB Interrupt 2002 which
replaces the computer keyboard interrupt with replacement
code to allow the recorder to get the first shot at
keyboard entries. The third step in FIG. 46, monitor
keyboard interrupt 2004, is actually something that
happens from this point on outside of the normal flow.
This process is called whenever a key is pressed
regardless of what else may be happening at that moment.
The interrupt watches for hot keys to start and stop a
recording, to enter filenames, and to keep track of keys
pressed between screens when a recording is being made.
Process screens 2006 is the next linear step in the

SUBSTITUTE ~;HEET



.:. : . ~ . - . .

WO91/00575 ! ... , . PCTtUS90io387~ '
2~ 9 1 - 206 - ~`
process. This routine is notified by the emulator
whenever a screen arrives and, if recording, processes the
screen and keys buffered by the keyboard interrupt. If
not recording, the routine just returns control back to
the emulator. When the user has completed the desired
processing and indicates a desire to exit, the step reset
interrupts 2008 is called to put the computer back into a
normal operating state. This is followed by process
duplicate single file names 2010 which cleans up any
conflicts with names entered for single screens -- a
necessity because of the complications of doing disk
input/output operations while in the middle of interrupts.
FIG. 47 details the initialize recorder 2000
step. This begins with setup/connect to emulator 2014.
The emulator API 1902 requires that the name of the
recorder program be passed as a parameter to establish
the link to an interrupt that will be used to communicate
between the recorder and the emulator. Once this is
completed, the recorder checks for an FTF file 2016. If
the answer to ~TF file 14c exists 2018 is no, the recorder
will quit 2020 as an FTF file 14c is required. If the FTF
file 14c exists, the FTF file l4c must be interpreted and
the recorder set to use its information. Thus step parse
key table 2022 handles this translation and is detailed in
Figure 53. Once the parse is complete the recorder
returns step 2024 to install the keyboard interrupt.
FIG. 48 indicates the original keyboard
interrupt is saved in save original handler 2026 as it
will be called during keyboard processing and restored at
the recorder's completion. Then install replacement
interrupt 2028 puts the recorder's keyboard logic routine
into the address the computer calls whenever a key is
pressed. Thereafter, there is return 2030.
FIG. 49 discusses the monitor keyboard
interrupt 2004. If a key pressed? 2032 is no it simply
returns 2034, but if yes, the computer calls the keyboard
interrupt 2036 which is detailed in FIG. 55. The last
step in FIG.

~iUBSTITUTE SHEET

; , ,, ., :.; . . , . ~ . .,

. ~ ; . . . - .

.. .... .. .

WO91/00575 2 ~ & ~ 878
- 207 -
FIG. 50 process screen 2006 handles the steps
taken once the emulator 8c is active and uses an API
interrupt to notify the recorder 2038 a screen has
arrived. This stops the emulator 1900 processing while
; 5 awaiting action by the recorder. If a screen arrived
from Emulator 1900 the recorder handles the screen in
screen arrived 2040 which is detailed in FIG. 57. When a
screen arrives a test for the finish flag set? 2042
indicates whether write to file 2044 must be called to
write out and close the recording exercise file being
built. The write to file 2044 is detailed in FIG. 61.
Otherwise, there is a return 2046.
FIG. 51 further explains FIG. 48 and sets the
keyboard interrupts. Reset interrupts 2008 will reinstall
original interrupt 2048 so that when the recorder leaves
the computer is left in a proper state of operation at
return 2050.
FIG. 52, another overview figure, handles the
process duplicate single filename 2010 by first checking
if there are any files to process 2052, which would only
be the case if the single screen record names entered were
duplicates of file names already on the disk. If there
are files to process, one of two conditions arises. The
file existed? 2054, if yes, calls display existing file
25 message 2056 to tell users of the conflict. If no, the ;
users are told of an error condition in display file
creation error message 2058. Both yes and no branch to
define new file name? 2060 which allows users to choose to
rename the file in question. A yes will go to get new
file name 2062 and if that name is in conflict again, the
file exists? 2064 step will catch it. A yes at file
exists 2064 will return users to the top of the processing
loop at any files to process 2052 to redo the steps
already described. A no to file exists 2064 will rename
the file that was temporarily stored under a system-
defined name in rename temporary file 2066. If the define
new file name 2060 step was no, the user is allowed a
choice to overwrite file? 2068 which will overwrite the

SUBSTITUTE SHFEl

:. . . .. .. :: . . `

WO 91/0057~ - - PCl'iUS9o/03878 '
- 208 -
e whose name was a duplicate with the new file. Yes to
overwrite file calls rename temporary file 2066 and a no
restarts looping again at any files to process? 2052.
When there are no more files to process the function
returns to complete the exit from the recorder.
FIG. 53 outlines the steps involved in parsing
the FTF file 2070 required for the recorder 2022 to
properly configure the user's keyboard. The first step is
to see if there is a Token to Process? 2072 and if none
the program simply has a return at step 2074. If there is
a token, the first test is whether the
Token=BEGIN_KEY_TABLE 2076. This is the beginning of the
keystroke part of an FTF file 14c which would follow any
configuration information. If that token is found, the
routine read key table 2078 is called (as detailed in
Figure 54). If no, the next test looks to see if
Token=KEY WORD 2080 and if yes calls setup scan code and
shift state for key word 2082, which identifies the new
values for the key word that the recorder 1904 will use.
If the token is not a key word, a message display unknown
token message 2084 alerts the user to FTF file 14c
deficiencies and the user is returned to Token to Process?
2072 until no more tokens exist.
FIG. 54 is the key table loop 2078 that fills
the key table the recorder will be using in its operations
and begins with get token 2088. Next comes the get key
value from key table 2090 that attempts to find the key in
the table or recorder 1904. If not key value found? 2092
a message display unknown key message 2094 is given to the
user, but if found, setup scan code/shift state for key
2096. The test equivalent available name in 3270 2098
checks if the key defined has an equivalent in the 3270
keystroke definitions. If not, an error condition
exists at display error-message 2100 which then returns
at step 2102. The information on the user's desired
recorder row and column definition for the 3270 key is
then tested to see if the row and column values are
available. Row number available 2104 is the first test

SUE-TITUTE SHEE'r
.. . . ....
. ; - `

WO91/00575 ~ PCTtUS90/03878
- - 209 -
and if successful there is an assign row number 2106.
Column number available? 2108 j, if affirmative, will lead
to assign column number 2110. Both tests row number
available 2104 and column number available 2108 call
display error message 2100 and return at step if negativeO
The increment key count 2112 adds the key to the list and
a test is made to see if key count < maximum? 2114. If
so, the recorder returns for another token at get Token
2088. Otherwise display error message 2100 is called and
the program returns. The recorder builds key tables to
get the row-column value that tells what key was pressed
and gets the name the user wishes displayed when that key
is pressed. (An application may use keys named PAl of
PFl, or it may use other names for the standard keys and
the FTF file xxx allows entering the desired name.)
FIG. 55 outlines the keyboard interrupt 2118
which is Assembly language code that replaces the
computer's own keyboard interrupt routine and is called in
its place whenever a key is pressed. The interrupt begins
by get input value from keyboard port 2120 -- the actual
interrupt call. The recorder allows the normal keyboard
interrupt to be called to do its processing in call old
keyboard handler 2122 but only after saving the location
in the keyboard ring buffer of the operating system where
- 25 a key would be placed. In this way, the recorder 1904
- can, if it decides "eat" the key under certain conditions
(such as when a file name for the recording is entered).
Eating the koy keeps the emulator 1900, and hence the
target application, from seeing it. On return from the
old interrupt the test is was key a release key? 2124 The
keyboard sends a scan code when you depress the key and
another when you release it, and releases can be ignored
so a yes will just return step 2126 out of the interrupt.
A no will test was key written by old handler? 2128 as
some keys will be eaten by the old keyboard routine as
well. A no leads to return 2126 to return the program
from the interrupt. A yes requires the recorder to get


S1~8STITUTE SHEET
. .
,,, ;. ; ~ . .

WO91/00575- ~ ~ PCT/US90/03878
2~?~ 210
shift state 2130 which gets the state of shifted toggle
keys like the Alt and Control keys. A test is then made
to see if the finish flag on? 2132 condition is on and, if
so, the return at step 2126 is made as the user has
indicated an end to the recording. If not, the question
is creating file name? 2134. If a file name is created
for special processing, keystrokes are handled and put on
the screen without letting the emulator 1900 or target
program 4 know. The routine process file name 2136
handles this. If not creating a file name is the
recording flag on? 2138. If it is already on the test for
stop key pressed? 2140 is made to see if we are to stop
recording. If not process key 2141 (FIG. 56) is called to
handle the keystroke. If stop 2140 is yes the finish flag
set 2142 process is started, the flag that places an "r"
in the lower corner of the screen to let users know they
are recording is reset to remove recording flag from
screen 2144, the operating system keybaord buffer is reset
to eat the stop key in reset keyboard tail pointer, and
the program returns (later the finish flag will be read
and the code will close out the recording). If the answer
; to recording-flag on?--2138 was no a test is made to see if
the key is single-screen key pressed? 2146. If yes, the
set single flag 2143 notes it and set recording flag 2150
prepares for recording with a start of display file name
prompt 2152. If not single, is multiple screen key
pressed? 2154. If yes, the set recording flag 2150
operation is performed and display file name prompt 2152
before a return at step 2126. The single flag being set
is what differentiates a single screen recording from a
multiple. In any case the next keystroke will reenter
this interrupt with different flags set so that the file
name will now be processed.
FIG. 56 is the process key 2141 routine that is
called whenever recording and a valid key has been pressed
to process. The first step is to save the key 2160. The
test will then be made on new screen flag set? 2162. This
is because when a new screen arrives the recorder will not

SUBSTITUTE 5HFET
.. ..
.. . .. ...
. . . . .. .
~`. .` . .
.; . . ` ~ . .
. , . . ;, ,
. .
,

W O 91/0057S ` ~ ~ ~ PC~r/US90/03878
~ 211 - 2~
. . .;. .
get a chance to see that screen until after it has been put
up in order to record it. Thus once the screen arrives
condition has been met the old keyboard buffer
is cleared out and this flag set so that on the first
key entered after the screen is put up the recorder will
record the untouched screen before processing that
keystroke and allowing the emulator to put it on the
screen. If the new screen flag set? 2162 was yes, the call
is to clear new screen flag 2164 from where copy screen into
Data Buffer Last_CRT 2166 will put the screen into memory
and the restore saved key 2168 routine puts the key back
into play (the save is a protection in case the input/output
processing of saving the file creates a condition where the
key is lost). If there is no new screen the key is
retrieved in get key from keyboard buffer 2170 and then
place key into local buffer 2172 puts it into the keyboard ;
buffer being saved by the recorder -- all keystrokes between
screens arriving that will later be procssed by the
recorder. It will then update pointer to next location 2174
moving the buffer pointer to the next available spot. Is
this spot end of buffer? 2176. If yes, the buffer is
resituated in reset buffer pointer top start 2177 before
joining the no track at get cursor information - put into
local buffer 2178. The local typing buffer keeps the key
2 5 and the row and column of the cursor when the key was
pressed. These are used for autoexit tests described in
FIGS. 58-60. The program will now update buffer pointer to
next location 2180 and again test end of buffer? 2176A with
a reset buffer pointer to start 2182 if yes. The program
has now processed the key and returns at step 2184.
FIG. 57 describes what happens when a screen
arrived 2140 condition occurs. The first step is cleanup
which places the "r" in the corner of the screen to let
users know they are recording -- place record flag in
corner 2186. The first real test is input file open? 2188.
If not it is at the start of a recording and must call
check file exist 2190 to open the file. If file opened
successfully 2192 is answered no the program returns at step

~iUBSTITUTE S~EFF
.


., .
~. ` ` - :

WO91/OOS75 ~ PCT/US90/03878
- 212 - r

2~ 2~94, but if yes, there is a check if the compress flag is
on? 2196. If so, record screen 2198 is called to place
the screen into the ring buffer. If not, the loop begins
to process the keyboard buffer that has been accumulated
since the last screen arrived. Keystrokes to process?
2200 does the test. If yes, the first test-is is the
current key a function key? 2202 If yes, process function
key 2204 is called (detailed in FIG. 59). If not is this
a displayable key? 2206, i.e., one that would or should
show up on the screen. If so process displayable key 2208
is called (detailed in FIG. 58 to follow). If not a
displayable key is the typing flag on? 2210. If no, the
system returns to keystrokes to process 2200 for the next
key, and if yes but backspace or left arrow is no it also
returns to keystrokes to process 2200. However, backspace
and left arrow are keys 2212 that act to erase the last
key hit and as such are corrections which the local typing
buffer uses to simply backup in its processing to erase
the key and so it will modify local typing buffer 2214 and
update cursor position/ get row-col data 2215 to reset the
typing buffer before returning to keystrokes to process?
2200. When all keystrokes have been processed the test
for ring buffer full? 2216 checks whether the need arises
to write out the buffer to avoid overrun problems. If
yes, it calls write new file 2218 (see FIG. 61), and if no
calls finish flag set? 2220 which also calls write to file
2218 if yes. If no, the routine falls to set new screen
flag 2222 as they keys are all processed and a new screen
is about to be put up that will be recorded when the first
keystroke is pressed. After that the routine will pass
control back to the emulator in return to emulator 2224.
FIG. 58 handles the processing of keys that can
normally be displayed on the monitor and handles
evaluating whether the location of the key indicates an
autoexit record is required. These tests presume that a
normal type-in indicates one character will follow the
next on the screen and if the cursor position is not that,
or if the character pressed did not show up on the screen

fiUBSTlTUTE SHEET
. ; : , .
. . ., ~, ' ,, .

- . . . . .. ..
- . - .' -,, ~,.. ::; :. : :.:
~ , ,: :,, ':
~:.~. ~- : :

WO91/00575 2 ~ ~ ~ $ ~ ~ PCTiUS9o/0387~
~ 213 -
~............................................................ .
at all, an autoexit condition is triggered which will
close the first type-in and record the screen. The
beginning tests if row-col data is available? 2226 because
this will be used to get the expected screen location with
calculate screen offset 2228. The next test is to see if
typing flag on? 2230 and if not the call is to record key
2232 (this will open a typing record and set the flag on
when the flag is not on). If the flag is on, and typing
has already commenced, is the cursor at last position ~ 1
2234 where it would be expected. If so and if cursor at
last location 2236 and if did char display at offset? 2238
then update offset 2240 and record key 2232 before update
cursor position 2242 and return 2244. If the cursor at
last location was yes but did char display at offset i5
no, an autoexit is required and the branch is to autoexit
screen record 2246. If not at the last position + 1, did
the character display at calculated offset? 2248 If not,
did character display at calc'd offset 2248 will update
offset 2250 and call record key 2232 and update cursor
location 2242 before a return 2244. Autoexit would now
be required if did char display after previous one? 2252
is yes, another keystroke to process? xxx is no, keystroke
displayable? 2256 is no, row-col available 2258 is no, and
did char display before this one? 2260 is no. Otherwise
the chain falls into update cursor location and offset
2262 to get things righted again before the call to
autoexit screen record 2246. Once the screen is
recorded, the key is now processed in record key 2232 to
open a new typing buffer, and the cursor is updated in
update cursor location and there is a return 2244.
FIG. 59 process function key 2204 handles the
key processing when the key found was a function key and
not an alphanumeric or displayable key. The start checks
if row-col data is available 2266 and if so it calculates
actual row, column 2268 when the key is pressed. A
function key can come in the middle of a typing buffer
being processed if it has not triggered a new screen from
the emulator xxx so a test is made more keystrokes to

SUBSTITU T E C~EET

,
,
~ .
, . : . .

WO91/00575 ~ PCT/US90/03878
- 214 - f `:

process? 2270 If yes, there are two checks: the typing
flag on 2272 and (if not) an arrow key? 2274. If typing
flag 2272 was on and the key was not backspace or left
arrow? 2274, there is a test for arrow key? 2276 If not
the arrow key the next call is to record this screen as an
autoexit screen record 2246 since there was no triggering
of a new screen. Next there is return 2278 to the screen
arrived xxx routine. Arrow keys are ignored and backspace
and left arrow used to reposition a typing buffer, erasing
a mistake, so these function keys do not trigger the
automatic record if backspace or left arrow was yes,
update the local typing buffer 2294 to reflect the
'erasure' and return. If there were no more keystrokes to
process? 2270 this is the last key in the buffer which
triggers the new screen. If the screen store flag on?
2280 there is a return 2282. If on, the test typing flag
on? 2284 will indicate whether a typing record must also
be written along with the screen and error messages. If
yes to typing the call is to store screen 2286 and then
process typing record 2288 which incorporates the
additional error screen writes. If typing was not on, the
store screen and error data 2290 routine is called.~ In
all cases the final routine is clear screen store flag
2292 before return 2282.
FIG. 60 autoexit screen record 2246 handles the
processing when a condition has been encountered where an
additional screen must be recorded between actual screens
from notification by the emulator. If the typing flag on?
2296 is yes it means typing was done before this call
and the screen to be recorded at this point must reflect
those characters on the screen. Thus the original screen
recorded when it first arrived is amended with put typing
buffer data in screen buffer 2298. If no typing, store
screen flag on? 2300 tests and, if no, the routine falls
down to record screen 2302. Then there is a reset last
cursor position 2304 before return 2306. A yes on store
screen flag on? 2300 will update key value and row col in
header 2308 followed by a store screen in ring buffer

SUBSTITUTE SHEET

` ~; ~ ,

.. ... . ............ . .
. . ~

WO91/00575 , ~ ~ PCTiUS9o/03878
2 ~

2310, both of which update the information on the screen
to record and place it for recording. If typing flag on?
2312 yes, process typing record 2314 sets up the
typingrecords and stores them in the ring buffer.
Otherwise there is setup header and error screen 2316,
increment index,to include error 2318, and store error
message in ring buffer 2320, all of which essentially
place~the,information on the screen in the buffer for
eventual writing. The clear store screen Flag 2322 is
then reset and the record screen 2302 does the compression
of the screen and sets the store flag for the next go
around.
FIG. 61 write to file 2218 is concerned with
writing on two conditions. When the recording is to be
finished it will write the final version of the file.
Otherwise it is called when the ring buffer is fulI. To
avoid an overrun, the buffer is written to file xxx to
allow more screens to then be recorded in the now
- initialized ring buffer. Write to file 2218 tests if
finish flag set? 2326 and if so, process final write 2327
(FIG. 63) is called. Otherwise process temporary file
(FIG,.,62) is called before return xxx.
- -, FIG. 62 is a flowchart for process temporary
write 2328. If a temporary file open? 2332 A call is made
directly to write ring buffer to temp file 2334 before a
return 2336. If not open, a file must be created and
creation successful? 2338 tests for this condition. A
successful opening calls set temp file open switch 2340
(used in the evaluation at temporary file open 2332)
before the write ring buffer to temp file 2334 and retun
2336. If the creation successful? 2338 step fails, a
display error message 2342 process occurs and the exercise
is at risk.
FIG. 63 gives a picture of how the final file
looks as well as handling the process final write 2344
step. The initial steps fall in order starting with
remove record flag from screen 2346 because recording is
over. Then comes setup/write exercise header 2348, the 16


SUBSTITUTE S~tEE-r
, ' ': ' `, ` :


,
' '~
`. i,

WO91/00575`` PCT/US90/03878
216 -

- bytes that begin an exercise file by identifying the first
screen to display and the type of exercise recorded.
Setup/write ID Array 2350 writes a 256-byte array which
has values set to 1 if the value of the offset in the
array has been used for a screen ID in-the exercise (in
other words, if a screen with ID 8 exists, this-array at
offset 8 will have a value of 1). Next comes the index
with~setup/write index array 2352 (the 16-bytes blocks
that speed up processing -- see the exercise file layout
for the second embodiment two). Finally a record is
written that CBT 12 uses for keeping branched screen
information 2353. The first test is is temporary file
open? 2354. If one has been opened, the file must be
processed first as it holds the beginning screens and the
ring buffer the latest ones. Close file/clear temp file
open switch 2356 is followed by open temporary file 2358.
Thereafter a test for end of file? 2360 is called in a
loop with a no calling read/write up to lK of data from
temp file 2362. This process writes out the temp file
until end of file? 2360 is yes. Then close temporary file
2364 is called. At this point, a no to temporary file
open? 2354 would also lead to setup-header/write last
entry to ring:buffer 2368 which is now called to complete
the exercise. Then the ring buffer is added to any
previous written scree`ns, if any, in write ring buffer to
exercise file 2370. The screen header for the last screen
recorded must now be changed to reflect that the next
screen in playback is the last screen or end of exercise
record.--This is handled in seek last screen header and
flag for last record 2372. The file is then closed in
close file 2374, and the user is told that the recording
is done in display complete message and clear flags 2376.
The routine then returns at step 2378.




fi~l~3STi~UT 5~EEl'
.. ~ ,. . . .
- - ::
.... . ..
~ . .. .

WO91/00575 ~ PCT/US90/03878
~ 217 - 2~
Gene~ eco~der
1989 TDS ~iealthea~d ~ystem~ co~poratlon
. . All ~lght~ ~eserved
/~ initialization C code fo~ ~A~1C
~/ '.
#include cstdlo.h>
#include <stddef.h>
#include "magic.h"
#deflne HEXtoi(c) (c > ~9î ~ c - (IA~ + lO) : c - 70~)
~define toupper (c) ((c ~- ~a') ~ (c <= ~z') ? c & ox20 o
c)
#define isspace(c) (((c<=~ I) (c==13) (c==lO) (c==g)) ?
1: O)
~define isxdiglt(c~ (((c>=10~)6h(c~=I9~))
((c>=lAI)~(c<=l~)) ((c>=~ a~ (c<=~ f'))?l:O)
#define isdigit(c) (((c>=lo~Jhk(cc=Igl))?l:o)
int open_file(char fa~ ~$
int creat file(cha~ fa~
int close file(lnt): ..
int get_fIlec(int, char fat ~)S '
int wrlte flle(int ,ch~ fa~ ~ char far ~):
int seek eof(lnt)
int message(char far ~ lht)t
int cmp screen():
lnt move_screen(char f~
int last_crt,
last chat under,
display_page,
video col ,
video len~
char lnGetText
#ifdef DEBUG
struct ~e~ control ~m~ 5 fa~ f~ t
struct ~es_cont~ol_pnm _~ fit ~f~P = ~fvS
Nelse
int fv:
struct res control P~ms ~ fa~ ~fvp = ~ULL:
~endif
/* key work table ~/
this table is searched wlth a binary search whenever a
keywork token ls fo~hd ln th~ P~. The table defines the


.
-: , . .. . . . .......... .

:. - . ;

. . - . ,, . .
:. : . . .

WO 9l/oo57s PCr/U590/03878
%~5~ - 218 -
token constant and the token as the index into the table
that has the pointer that points to a null terminated
string that has the reference token. The numbers are
placed literally because a #define #undef #define #undef
sequence that would take generate the numbers
automatically... maybe latter.
New entries must be in ALPHA order!
*/ ..
/***** NOTE: this is the first piece of transient data it
is overwritten */
char *key work table[]
., ( ,
I' ", /* no token 0 */
''APPLICATION_NAME'I,
#define APPLICATION_NAME
"AUTOEXIT_CODE",
#define AUTOEXIT_CODE 2
IIFUNCTION HOLDOFF'I~
#define FUNCTION HOLDOFF 3
"IGNORE_ATTRIBUTES'I,
#define IGNORE_ATTRIBUTES 4
"IGNORE CASE",
#define IGNORE CASE 5
"IGNORE XEYPAD",
#define IGNORE XEYPAD 6
"IGNORE REGION40",
#define IGNORE_REGION40 7
"IGNORE REGION80",
#define IGNORE REGION80 8
"NO KBD ROM",
#define NO KBD_ROM 9
"PAGE",
#define PAGE 10
"RECORD_HOI-DOFF",
#define RECORD HOLDOFF 11
"RECORD_PAINT",
define RECORD PAINT 12
"RECORD SCREEN",
#define RECORD SCREEN 13
"RECORD SCROLL",




:, : ' ' ' . . :-`:
' -' ' ' :` :

WO 91/0057~ PCliUS9o/03878 ,`
l ! ~ i 2 ~

#define RECORD SCROLL 14
"RECORD_SOUND",
#define RECORD_SOUND 15
"SAMPLE_RATEII,
#define SAMPLE RATE 16
"SCROLL_LINEI',
#define SCROLL LINE 17
"SETTLE_TIME_MAX",-
#define SETTLE_TIME_MAX 18
"SETTLE_TIME_MIN",
#define SETTLE_TIME_MIN 19
"START_RECORD",
#define START_RECORD 20
"STOP_RECORD",
#define STOP RECORD 21
"TYPE_IN_POSITIONI~,
#define TYPE IN POSITION 22
"ZDUMMY'I
#define DUMMY . 23
) ;
#define MAX KEY WORD 23
/* shift control flags from bios */
#define INS SHIFT Ox80
#define CAPS SHIFT 0x40
#define NUM SHIFT Ox20
#define SCROLL SHIFT Ox10
#define ALT SHIFT Ox08
#define CTL SHIFT Ox04
#define LEFT SHIFT 0x02
#define RIGHT SHIFT 0x01
#define LR SHIFT Ox03
/*
*/
/* variables used just within this module */
static int err count; /* compile error count */
static int file; /* DOS file handle */
static int res key index; /* index into resident key tahle
*/
/*



.~ ' ' -: -


Wo 91/00575 - Pcr/us90/03878
.. ~
-- 220 --
2~ *,
/* key table */
/*
This is the master tab~e for interpreting key strokes
from the target machine's BIOS. Due to the vast
differences between machine's keyboards the BIOS key-
board interrupt routine is called by the CBT recorder
key board interrupt routine and the resulting
keystrokes in the BIOS maintained ring buffer are
examined. The scan codes are the same across all
series of IBM machines both PS2's and PC's. The
startup sequences, however, must be decoded for each
variety of machine. Machine recognition code is
provided with a variable that contains the machine type
and therefor the keyboard type for direct key number
decoding for the turn on and turn off key sequences.

*/
struct key_table_s
char *name, /* asscii name in the FTF file
*/
scan_code, /* BIOS returned scan code for the key
*/
char_code, /* BIOS returned ASCII code for the key
*/
shift_flags; /* map of the shift keys for the key
*/
key_table[] = /* table is in ascending order for
binary search */
{ "BKSPACE", 0x0E, 0, 0 3, ~ "DEL", 0x53, O,
O },
( "DOWN", 0x50, 0, 0 ~, ( "END", Ox4F, 0,
O ),
( "ENTER",OxlC, 0, 0 ), ( "ESCAPE",Oxl,
O, O )
~ "Fl", Ox3B, O, O ), ( ~'Fl-~", Ox68, O, O )~ "Fl-C",
Ox5E, 0, 0 ),( "Fl-S", Ox54, 0, 0 ),
( "F10", Ox44, 0, 0 ), ( "F10-A", 0x71, O, 0),( "F10-
C", Ox67, O, 0 ),( "F10-S", 0x5D, 0, 0 ),
"Fll", 0x86, O, O ),
( "F12", Ox85, o, o ),
~ "F2", Ox3C, 0, 0 ), ( "F2-A", 0x69, 0, 0 ),( 'IF2-C",
Ox5F, O, 0 ),( "F2-S", 0x55, 0, 0 ),
"F3", Ox3D, O, 0 ), ( "F3-A", 0x6A, o, 0 )~l "F3-C",
Ox60, O, O ),( "F3-S", 0x56, O, O ),
( "F4", Ox3E, O, O ), ( "F4-A", Ox6B, o, o ),( "F4-C",
Ox61, 0, 0 3,( "F4-S", 0x57, 0, 0 ),




~ . , . . :, .
:~ . ~, . ., ; , .;


.. . . .

WO 91/00575. PCI/US90/03878
~; - 221 2~0
"F5", Ox3F, 0, 0 ), ( llF5-A'l, Ox6C~ O, O ),( "F5-C",
Ox62, O, O ),( "F5-S", Ox58, 0, 0 ),
"F6~, Ox40, O, O ), ~ l~F6-A", Ox6D, O, O ),~ "F6-C",
Ox63, O, O ),( "F6-S", Ox59, O, O ),
( "F7", Ox41, O, O }, ~ "F7-A", Ox6E, O, O ),( "F7-C",
Ox64, O, O ),~ "F7-S", Ox5A, O, O ),
~ "F8", Ox42, O, O ), ( IlF8-All, Ox6F, O, O ),( "F8-C",
Ox65, O, O },~ "F8-S", Ox5B, 0, 0 ),
I "F9", Ox43, O, O ), ( I'F9-A'I, Ox70, O, O ),~ "F9-C",
Ox66, 0, 0 ),( "F9-S", Ox5C, O, O),
'INSI', Ox52, 0, 0 ), ( I'HOME"r Ox47, O, O
I'KEY!", Ox02, l!l, I~R_SHIFT ),
"KEY\'l",Ox2B, '/l, O ), ~ "KEY#", Ox()4,
'#', LR_SHIFT ),
( "KEY$'1, Ox05, '$', LR SHIFT ), ~ "KEY%", Ox06, '%',
LR_SHIFT ~,
~ "KEY&", Ox08, '&', LR_SHIFT ), ( "KEY"', Ox28, '\'',
o 3l
( "KEY(I', OxOA, I(I, LR_SHIFT ), ~ I'ÆY)", OxOB, ')',
LR SHIFT ),
( "KEY*", OxO9, l*l, LR_SHIFT ), ( "ÆY+", OxOD, l+l,
LR_SHIFT ),
"KEY,I', Ox33, l,l, O ), ~ "KEY-", OxOC,
1--l, O ),
"ÆY.", Ox34, ~.l, O ), { "KEY/", Ox2B,
'/', O ),
"KEYO", OxOB, lol, O ), ( "KEYO-A", Ox81,
0', O ),
"KEYl", Ox02, lll, O ), ( "KEYl-A", Ox78,
l', O ),
( "KEY2", Ox03, 121, 0 ), ( llKEY2-All, Ox79,
'21, 0 ),
"KEY3", 0.04, 131, 0 ), ( "KEY3-A", Ox7A,
'3', 0 ),
KEY4", OX05, 14~ o 3, ( "KEY4-A", Ox7B,
4', 0 ),
( 'IKEY51', Ox06, 151, 0 ), ( llKEY5-All, Ox7C,
51, 0 ),
"KEY6", Ox07, 161, 0 ), ( "ÆY6-A", Ox7D,
61, 0 ~,
~ "ÆY7", Ox08, 171, 0 ), 1 "ÆY7-A", Ox7E,
'71, 0 )~
( "KEY8", OXO9, '81, 0 ), ( ~ÆY8-A", Ox7F,
'81, 0 ),
"ÆY9", OxOA, lgl~ O ), ( "ÆY9-A", Ox80,
91, 0 )~
"XEY:", OX27, 1:', LR SHIFT ), 1 9'KEY;", Ox27, ';', O
( IlKEY<ll, OxOD, l<l, LR_SHIFT ), ( "KEY=", OxOA, l=l, O
) ~
IlÆY>ll, Ox34, 1~I, LR_SHIFT ), ( 'IÆY?ll, Ox35, ~?',
LR_SHIFT ),



. - .


.

WO 91/00575 Pcr~uS9O/03878
C~`'
-- 222 --
2~'ÆY~', OxO~, 'Q~ R SHIFT )~ ( I'KEYA", OxlE! 'A', 0
l "KEYB", Ox30, ~B"~ 0 ), ( "KEYC", Ox2E,
'C~, o ),
"KEYD", Ox20, ID~ 0 ), ~ "KEYE", Ox12,
'E', 0 )~
~ "KEYF", Ox21, 'F~, 0 ), ( "REYG", Ox22,
'G', 0 }~
1 ~KEYH~, Ox23, ~H~ )~ ( "KEYI", Ox17,
'I', 0 )~ .
( "KEYJ", Ox24, ~J", 0 ), ( "KEYK", Ox25,
K', O ),
( ~KEYL", Ox26, ~L~ 0 ), ( "KEYM", Ox32,
'M', 0 ),
( "KEYN", Ox31, ~N~, 0 ~, ( "KEYO", Ox18,
~O', O )~ .
"KEYP~, Oxl9, ~p~ 0 ), ( ~KEYQ", OxlO,
~Q', 0 ),
"KEYR", Ox13, ~R~ 0 ), ( "KEYS", OxlF,
'S', O )~
"KEYT", Ox14, ~T~ 0 )~ ( "KEYU", Ox16,
'U', O )~
( "KEYV", Ox2F, 'V~, 0 )~ ( "KEYW", Oxll,
'W', O )~
( "KEYX", Ox2D, ~X~, 0 )~ ( "KEYY", Ox15,
'Y', o )~ .
( "KEYZ", Ox2C, 'Z', 0 )~ ( "KEY[", Ox2C,
~t', 0 ),
( ~KEY\\", Ox2C, ~ 0 ), ( "KEY]", Ox2C, '];, 0
) ,
( "KEY ", Ox2C, ~ ~, 0 )~ ( "KEY ", Ox2C,
O ),
( "KEY`'I, Ox2C, ' ~, 0 )~ ( "KEY(", Ox2C,
'( ', O ),
( "KEY ", Ox2C, ' ~, 0 ), . ( "XEY)", Ox2C,
')', ),
( ~OEY-", Ox2C, ~ ~, 0 ~, ( "LEFT", Ox4B,
O, O ),
I'PGDN", Ox51, 0, 0 )~
( I'PGUP", Ox49, 0, 0 ), ( "RIGHT", Ox4D,
O, O ),
IISPACEII, Ox39, 0, 0 ), ~ "TAB", OxOF, 0,
o )~ ,.
{ "UP~', Ox48, 0, 0
#define LAST_~rABLE_ENTRY 150
) ;
int *next char_in, *next char out~
int typed chars[100~;
int Ticks;
/* prototypes */




. ~ .''".,.'.;. '~'' ~ ''` ' ,. '

WO91/00575 PCT/US90/03878



struct key_table_s *get_key_entry(char *~o~en~,
unsigned char get_shift_states(char *ptr);
struct key_table_s *search_key_table(char *token);
read file(char *)i
struct res_control_prms_s far *get_fv();
/* main program */
main(int ac, char *av[])
(




if (fvp == NULL)print~ DS Magic Screen Recorder
Configuration\n");
else printf ("TDS Magic_Screen Recorder Configuration
Checker\n");
if (fvp == NULL) && Imagic Present() )

fprintf~stderr, " This program requires the magic
TSR/n");
exit(l);
)




if (fvp == NULL) fvp = get_fv();

fvp->function_holdoff = l;
fvp->record_holdoff = l;
fvp->sample_rate = 2;
fvp->scroll_line = 0;
fvp->settle time min = 2;
fvp->settle_time_max = 5;
fvp->display page = 0;
fvp->ignore case = 0;
fvp-~ignore_keypad = 0;
fvp->record_paint = 0;
fvp->record sound = 0;
fvp->start_key = 0;
fvp->start_shifts = 0;
fvp->stop Xey = 0;
fvp->stop shifts = 0;
fvp->single rec_key = 0;
fvp->single rec_shifts = 0;
fvp->typein_pos_flag = 0;
fvp->kb_rom flag = 0;
fvp->typein auto keya = 0;
fvp->typein_auto_keyb = 0;
fvp->application name[0] = 0;
fvp->res key table[O].scan_code = 0;
fvp->ig80.flag = 0;
fvp->ig40.flag = 0;




," '-
: . .

:

WO91/00575 !' PCT/US90/0~878
f~'
9!1 - 224 -

read_file(av[l~;
)
~: /*
C library routi~es - W~e must define them here to get
proper alignment

char *strchr(char *s, char c)
while(*s)
if (*s == c)return(s);
else s++;
return (NULL);

stricmp(char *sl, char *s2)
while(*sl && *s2)
if (toupper(*sl) I = toupper(*s2))break;
else sl++, s2++;
return(*sl - *s2);

strcmp(char *sl, char *s2
while (~sl && *2s)
if (*sl l= *s2)break;
else sl++, s2++;
return(*sl - *s2);

strncmp(char *sl, char ~s2, int n)
while(*sl && *s2 && n--)
if (*sl l= *s2)break;
else sl++, s2++;
return(*sl - *s2);
',

strcpy(char *sl, char *s2)
while (*s2)*sl++ = ~s2++;
*Sl = O;
)




strcat(char *sl, char *s2)
while(*sl)sl++;




. ~ ~, .,; -, ., - ,
-:

WO91/00575 PCT/US90/03B78
~ - 225 - 2~
while (*s2)*sl++ = *s2~+;
*sl = O;

strien(char *s)
register int i = O;
while(*s++)l++;
return(i);
atoi(char *s)
register int i = O;
while(*s) i = (i * 10) + (~s++ - ~O');
GetKBDRomFlag () ( retur~(0); )
/*
/********************~**~***~*****************
/*
This routine returns true if the string is just numbers
in it
*/
./*************************~*******************~
is number(char *s)
while(*s)
if (!isdigit(*s))return(0);
else s~+;
return(l);
/***********************~*~**********************
/*
get key entry - this ~outine searches the key table above
and returns a pointer to the entry having the same name
as the given token. The search is performed in binary
fashion, starting from the middle of the table and
searching the half of the alpha ordered table in the
direction indicated by the cmpstr return. A word on not
finding the entry. To simplify the ~inary search
algorythm we just place a limit on the number of
iterations that the search can be performed. At first
glance this may seem wasteful of clocks in the case of
failure. Well, it is, but the rest of the system will
not run unless the FTF is read in without any errors so
the error path is only taken in the development of the
FTF file. Once the FTF exists then the search will
always succeed quickly.



. . i ,-.;,, , : . - ., -, .
:: ~ - - ., .; . , .

.. , . . ...... :, , .. , . i ,.. . .
- . . .,. - : ,: . . . , -
! . .: . .
: .::, .:: : ' '. . :~

WO91/00575 PCT/US90/03878
~$~ 226 -

/*********************~**.*.************************
sruct key_table_s *search_key_table(char *token)
int incr = sizeof(key_table) / sizeof(struct
key table_s) / 2;
lnt limit = sizeof(key table) / sizeof(struct
key_table s);
struct key table_s *entry = &key table[incr];
register int tmp;
char *ptr;
do
tmp = strcmp(token~ entry->name),
i f ( tmp == O)return(entry);
if (incr !=l)incr /= 2;
if (tmp > O)entry += incr;
else entry -= incr;
if ( (entry < &key table[0]) (entry >
&key table(LAST_KTABLE ENTRY]))
return(NULL);
while(limit--);
return(NULL);
)




struct key table s *get key entry(char *token)

struct key table_s *entry;
char *hyphen;
.. . ..
if ( (entry = search_key table(token)) !=
NULL)return(entry);
hyphen = strchr(token, '-');
if (hyphen && *(hyphen+l) == '-')hyphen++; /* handle
the REY--x case */
if (hyphen && *(hyphen ~l) l = 0) hyphen = 0;
else return(NULL);
entry = search_key_table(token);
*hyphen = ~-';
return(entry);
/*******************************
/*
This procedure scans the FTF given token looking for the
shift state modifers -L -R -S -A or C. It then returns
a shift state character indicating which states are set.
*/
/*************************************************



,. - : . . ,. :: , , -
. :-. . ,
., , . . - . . : :: , ,

, - ;:: ~ : : -

WO 91/0057~ PCliUS9o/03878
1~.
- 227 ~ 2
unsigned char get shi~t_states(char *prt)
register unsigned char retval = O;
while ~(ptr ~ strchr(ptr, '-')) != NULL)
ptr++;
switch(*ptr~
case 'S~; retval = LR SHIFT;break;
case ~ Rl: retval = RIGHT SHIFT; break;
case 'L': retval = LEFT SHIFT;~reak O
ca~L'A!; ~etval ~-ALT_SK~FT;break;
case 'C': retval = CTL_SHIFT;break;
return (retval);
)




/*
*/
/******************~******************************
*/
/**********************~**************************/
/*
get_token - read a token f~om the FTF file
This routine parses out all.spaces in the FTF file
returning each token in the file in a provided buffer.
A token is defined as a sequence of ASCII characters
surrounded by white space. White space includes space
CR, LF and TAB. The token parser recognizes double
quotes and returns the entire text found in the quotes
as a single token. The parser also filters out
comments which are a white space followed by a semi-
colon. When this sequence is found everything till the
end of the line is ignored and the token parser is
restarted.
.

*/
/*************************~*****************~*****/
int get token(char *token)
char inp = ' ', /* input character */
inquote = O, /* flag indicates processing a quoted
string */
*ptr; /* work pointer for filling in token
*/
int ret = l; /* return value > 1 if a string was
parsed */
top: /* for restarti~g the parse */



, . . .; . - . , . . . - ,



- .. : .. ,

W091/00575 PCT/US90/038
228 - ~`
t~,r;~'- token;
while (isspace(inp)) /*skip
spaces */
if (get_filec(file, &inp) == 0) return (0); /* at eof
*/
if (inp == ';').
comment field? */
wbile (inp l= ~\n')
if (get_filec(file, &inp) == 0) return (O);
goto top; /* past
comment look again */
)




do
if (isspace(inp) && li~quote) break; /* end of token
*/
if (inp == ~\"')inquote = ~inquote, ret++;
else *ptr++ = inp;
if (ptr - token > ~AX TO~EN_SIZE-l) /* check for
limit */
message("maximum token length exceeded\r\n", 31);
goto top;
.,) ~ '
while(get_filec(file, &inp));
*ptr = O; /* null
terminate */
if (ptr == token) retur~ (0); /* eof */

/*************************************************/
/*
bool_token - decide if a token indicates true or false
This routine looks at the token and provides an error
message if the token is not a bollean indicator.
*/
/*************************************************/
char bool tok(char *ptr)
if (stricmp(ptr, "YES") == O) return (l);
if (stricmp(ptr, "TRUE") == O) return (l);
if (stricmp(ptr, "NO") == O) return (O);
if (stricmp(ptr, "FALSE") == 0) return (O);



- . .-.:. .. : :
,.. , ,- : .:

. . .. ~ ,, : .

WO91/00575 PCT/US90/03878
2 ~
message ("Expected a bollean indicator\r\n", 30);
return (o);

/*************************************************/
/*
key word - look up a token in the key word table
This routine binaryly searches the key word table for the
given token.
*/
/******************-****************************** A/
int key word(char *token)

register int i = MAX_KEY WO~D / 2;
register int j = i;
. int tmp;
int limit = MAX_KEY WORD;
while (limit--)




if ((tmp = stricmp (token, key_word table[i])~ == O)
return(i);
if ((i == l) :: (i > MAX_KEY WORD))return (o~;
if (j != l)j /=2;
if (tmp < o) i -=j;
else i +=j;
return (O);
)

* ** * *********************/ t
/*
set key_word - perform the actions for a key word in a
file
This routine performs the work for each of the key words
in the FTF.
*/
/*************************************************/
set_key_word (int key)
register int i;
char token tMAX_TOKEN_SIZ~];
struct key_table s *key_ref;
int a, b, c, d;
switch (key)
(




,, ,, ~. , . , . .. : . .
- . ~, . : , . .
, ~. : . - : .,: .... . : , :. : ,

WO91/00575 PCT/US90/03878

- . - 230
.L case APPLICATION_NAME;

get_token(token);
for (i =o; i < 80; i++)
if (token [i])
fvp~>application_name[i] = token[i];
else ~reak;
break;
case AUTOEXIT CO~E;
get_token (token);
fvp->type in a~to ke~a = atoi (toke~);
get_token (token);
fvp->type in auto_keyb = atoi (token);
break;
case FUNCTION_HOLDOFF;
get_token (token);
fvp->function_holdoff = atoi (token);
break;
case RECORD_HOLDOFF;
get_token (toke~);
fvp->record holdoff =~atoi (token);
break;
case SAMPLE_RATE:
get_token (token);
fvp->sample_rate z atoi (token);
break;
case SCROLL_LINE;
- get_token (token);
fvp->scroll_line = atoi (token);
break;
case PAGE: .

get_token (token);
fvp->display Page = atoi (token);
break;
case SETTLE_TIME_MIN:

get token (token);
fvp->settle time min = atoi (token);
if (fvp->settle time max <= fvp-
>settle_time_min)
fprintf(stderr, I'SETTLE TIME MAX less then
SETTLE TIME_MIN\n");




. - , . ,., .:. - :. , : . : ::~ ; :
:, . . ~: :: . ;. . , - :

wo91/oos75 PCT/U590/03878
~ .
r ~ 2 3 1
break;
case SETTLE_TIME_MAX;

get_token (token);
fvp->settle time max = atoi (token);
if (fvp->settle= ime_max <= fvp-
>settle_time_min)fprintf(stderr, "SETTLE_TIME_MAX less then
SETTLE_TIME_MIN\n");
break;
case-NO_~BD_ROM;
get token (token);
fvp->kb rom flag = bool_tok (token);
break;
case TYPE IN_POSITIO~;
get_token (token);
fvp->typein pos_fla~ = bool_tok (token);
break;
case IGNORE CASE;
get token (token);
fvp->ignore case - bool_tok (token);
break;
case IGNORE REYPAD;
get_token (token);
fvp->ignore keypad = bool_tok (token);
break;
case IGNORE ATTRIBUTES:
get token (token);
fvp->ignore attr = bool tok (token);
break;
case IGNORE_REGIO~40:
get token (token);
a - atoi (token);
get_token (token);
b = atoi (token);
get token (token);
. c - atoi (token);
get token (token);
d - atoi (token);
fvp->ig40.flag = l;
fvp->ig40.min = (a * 40 + b) * 2;




:- ~ :............. . :: . : :: .: . :
::: :~
- - ,

WO91/00575 PCT/US90/0~8~1~
.,
232 -
` fvp->ig40.max = (c * 40 + d) * 2;
fvp->ig40.xmin = b;
fvp->ig40.xmax = d;
if (fvp-~ig40.max <= fvp->ig40.min :: fvp-
>ig40.xmax <= fvp->ig40.xmin)
fprintf(stderr, "IGNORE 40 with bad
coordinates\n");
get_token ~token)i
a = atoi (token);
get_token (token);
b = atoi (token);
fvp->ig40.qualpos = (a * 40 + b) * 2
get_token (token);
for (i = 0; i < 40; i++)
if (token[i])
fvp->ig40.string[i~ = token
else break;
fvp->ig40.qlen = i;
if (token[0]) f~p->ig40.flag = 2;
break;
case IGNORE_REGI0~80;
get_token (token);
a = atoi (token);
get token (token);
b = atoi (token);
get_token (token);
c = atoi (token);
get_token (token);
d = atoi (token);
fvp->ig80.flag = 1;
fvp->ig80.min = (a * 80 + b) * 2;
fvp->ig80.max = (c * 80 + d) * 2;
fvp->ig80.xmin = b * 2;
fvp->ig80.xmax = d * 2;
if (fvp->ig80.max <= fvp->ig80.min :: fvp-
>ig80.xmax <= fvp->ig80.xmin)
fprintf(stderr, "IGNORE 80 with bad
coordinates\n");
get token (token);
a = atoi (token);
get_token (token);`
b = atoi (token);
fvp->ig80.qualpos = (a * 80 + b) * 2;
get token (token);
for (i = 0; i < 80; i++)
if (token[i~)
fvp->ig80.stringti] = token ti];
else break;
fvp->ig80.qlen = i;
if (token~0]) fvp->ig80.flag = 2;




; : .. ::: . :: - ,:; . . :
, ~ . . ..

WO91J00575 PCT/US90/0387X

233 ~ 2~ 3

break;
case RECORD_PAINT;

get_token (tokenj;
fvp->record Paint = bool_tok (token);
break;
case RECORD SouND;

get token (token);
fvp->record sound = bool tok (token);
break;
case START RECORD;
get_token (token);
if ((key_ref = get_key_entry (token)) == NULL)
message ("Unknown Start Key specifier", 30)o
message (token, strlen (token));
message ("\r\n", 2);
break;
if (*token == 'F' && ~*(token + 2) == '-' .:
*(token + 3) == "-")) while (strchr(key ref->name, '-') 1=
NULL)key_ref--;
fvp->start key = key_ref->scan code;
fvp->start shifts = key ref->shift flags;
fvp->start_shifts := get_shift states (token~,
break;
case STOP RECORD;
get_token (token);
if ((key ref = get_key_entry (token)) == NULL)
(




message ("Unknown Start Key specifier", 30);
message (token, strlen (token));
message ("\r\n", 2);
break;
if (*token == 'F' && (*(token + 2) == '-' ::
*(token + 3) == '-')) while (strchr (key_ref->name, '-')
!=NULL)key ref--;
fvp->stop key = key ref->scan code;
fvp->stop shifts = key ref->shift flags;
fvp->stop shifts := get_shift states (token);
break;
case RECORD SCREEN;

get token (token);
if ((key ref = get_key entry (token)) == NULL)


:
~, . , ' ! . '
'` ` " '~ "~ ` '. " ''' ' :`
'' ' ~ ' . ~.'
' ~ " ' ',
~' ' ~' ' , " " '` " ''
. ' ' . ' .' , '

WO91/00575 PCT/US90/03878
,..................................................... ~
- 234 -

message ("Unknown Start Xey specifier", 30);
m~ssage (token, strlen (token));
message ("\r\n", 2);
break;
if (*token == ~F~ && (*(token + 2) == '~
*(token + 3) == '-~)) while (strchr (key_ref->name, '-')
!=NULL)key ref--;
fvp->single rec_key = key_ref->scan_code;
fvp->single rec shifts = key ref->shift_flags;
fvp->single rec_shifts := get_shift states
(token);
break;

)




/*********************************************~***/
/*
This procedure scans the FTF token by token compiling
the resident key table. The parse is data driven with
each new token dictating w~at the ensuing token(s)
should be. Premature ending of the FTF is accounted
for along with unrecognized key words.
*/
/*************************************************/
read key table()
int num keys = 0;
int tmp,
- char token[MAX_TOXEN_SIZE];
char *ptr;
struct key table_s *ref;
struct res key_table_s far *entry = &fvp-
>res_key_table[0];
while (get_token(token))

ref = get_key_entry (token);
if (ref == NULL)
if ((strncmp(token, "HEX", 3) == 0) &&
isxdigit (token[3]) && isxdigit
(token[4]))
memset(entry, 0, size of (struct
res_key table s ));
entry->scan code = HEXtoi (token[3]) * 16;
entry->scan code += HEXtoi (token[4]);
else
message ("U~known Xey identifier", 23);



. . ; . .: .. .
-; , .
. . . " - .
. - . ~ : - . ~ .:; ,:
:, :. .
~ ~ .

W091/00575 . . .
PCT/US90/03878
- 235 -
message (token, stxl ~ o~e~ );
message ("\r\n", 2);
continue;
else
entry->scan_code = ref->scan_code;
entry->shift flags = ref-~shift_flags;

/* scan for shift state modifiers */
entry->shift flags ;= get_shift_states (token);
/* get the expected ascii code */
entry->ascii code = ref->char code;
/* modify to shift state */
if (entry->shift flags & ALT_SHIFT)
entry->ascii code = 0;
else if (entry->shift flags & CTL SHIFT)
: entry->ascii code -= 0x40;
. /* expect to get the type declaration for the
key */
if (! (tmp = get_token (token)))
message ("Unexpected end of file\n\r", 24);
break; :
}
if (tmp > l &~ ! (tmp = get_(token))) /* skip-
by optional name */
message ("Unexpected end of file\n\r", 24);
break;
)




if (stricmp (token, ~'FUNCTION") == 0) entry-
>ctl type = FUNCTION KEY;
else if (stricmp (token, "IGNORE") == 0)
entry->ctl type =IGNORE KEY;
else if (stricmp (token, "TYPED") == 0)
entry->ctl type =TYPED KEY;
else
message ("Unknown Key type specifier", 25);
message (token, strlen (token));
message ("\r\n", 2);
break;
if (entry->ctl_type -= FUNCTION KEY)

if (~get_token (token))




, , :: .: .:
: ~ ::::: . . ,. :

Wosl/00575. PCT/US90/0387


- 236 -


message ("Unexpected end of file\n\r", 24J;
break;
if (lis_number (token))
message ("Function Key requires a row
number\n\r", 36);
continue;
entry->row = atoi (token);
if (Iget_token (token)~

message ("Unexpected end of
file\n\r", 24);
break;
}




if (lis_number (token))

message ("Function Key reguires a
column number\r\n", 39);
continue;

)




entry->col = atoi (token);




entryt+; .
if (+~num_keys == MAX_TSR KEYTAB)
(
-entry--;
entry->scan_code = 0;
message("Fatal error number of keys exceeds
maximum\n\r", 45);
ab_exit(l);
memset (entry, 0, size of (struct
res_key_table_s )); `
)




/*********************~**,*.*t~********~*************/
/*
read_file - read the FTF file and set the key table flags
and values
This routine is called once upon entry into the cbt
recorder the text is located in the discarded text
segment and the data is in the discarded region also.
This routine and the rest of the c routines in this file
are used only to read the FTF in and set the tables for
the keys, values for the parameters and the state of the
control flags.




, : - . . .

: .

WO91/00575 2 ~ PCT/US90/0387~
,..
- 237 -
Some assembly routines are req~lired for screen and file
IO. These routines are in the assembly initialization
file and are also discarded after use. The C stdlib io
package is not used because it would be near impossible
to seperate out the components when it comes time to
discard the code and data. It also reduces the size of
the module because most of the C code error checking and
buffering is not required.
*/
/*************************************************/
read-file(char *name)
int kw;
char token[l80];
strcpy(token, name);
if (strchr(name, '.') == NULL) /* setup extension if
necessary */
strcat(token, ".FTF");
file = open_file(token);
if (!file)
message ("Cannot find FTF file\r\n", 22);
ab-exit(l);
while (get_token(token))
if (stricmp(token, I'BEGIN KEY TABLE") == O)
read key_table();
else if ((kw = key_word(token)) I= O)
set_key_word(kw);
else




err count++;
message ("Unknown Token in file - ", 25);
message (token, strlen(token));
message ("\n\r", 2);
)




close file (file);
/*
transient_init - called from assembly code entrance
*/
extern int InstallTSR ();
transient init (char far *farargline)



::
,. . ., . ~ .,.

-.; . ~, . .

WO9l/005?5 PCTiUS90/03878
~$~q~ - 238 -

char arg[80~;
char *argline = arg;
int i;
for (i = O; i < 80; i~+~a~[i] = *farargline++;
while(isspace(*argline))
if (*argline == ~\r')
~, (
message ("Usage: magic file <.ftf>\n\r", 25);
ab exit(l);
)




else argline++;
tmp = strchr(argline, ~\r~);
if (tmp)*tmp = O;
tmp = strchr(argline, ~
if (tmp == NULL)strcat(argline, ".FTF");
read_file(argline);
message ("FTF file read\r\n", 15);
return((DEFAULT RING_SIZE + (2*(BUF_SIZE))) /16 +1);
)




/*
MAGIC.C - C routines ~or the CBT recorder
*/
/*
*============================= ==================
* P R O P R I E T A R Y N O T I C E
*




* THIS DOCUMENT DESCRIBES A PROPRIETARY SOFTWARE PRODUCT
OF TDS
* HEALTHCARE SYSTEMS CORPORATION (TDS), CONTAINS TRADE
SECRET
* AND PROPRIETARY INFORMATION, IS AND SHALL REMAIN AN
UNPUB-
* LISHED WORK PROTECTED BY COMMON LAW COPYRIGHT, IS
LOANED FOR
* LIMITED PURPOSES ONLY, REMAINS THE PROPERTy OF TDS, AND
IS TO
* 8E RETURNED UPON REQUEST OR COMPLETION OF THE PURPOSE
OF THE
* LOAN, WHICHEVER IS SOONER. ACCEPTANCE OR RECEIPT OF
THIS
* DOCUMENT BY THE AGENT AND/OR PRINCIPLE TO WHOM IT IS
LOANED IS
* AN ACKNOWLEDGEMENT THEREBY THAT IT IS BEING RECEIVED IN
CONFI-
* DENCE AND THAT IN CONSIDERATION FOR THE LOAN, NEITHER
IT NOR
* ANY OF THE INFORMATION IT CoNTAINs WILL BE REPRODUCED,
USED,



.
;,., ; ,:
.. . , . ~ . ..

. ~ .. . . .

WO91/00S75 PCT/US90/03878
~' - 239 - 2 ~

* OR DISCLOSED, IN WHOLE OR IN PART, BY OR TO ANYONE NOT
HAVING
* A NEED-TO-KNOW CONSISTENT WIT~I THE PURPOSE OF THE LOAN
OR ANY-
* ONE NOT EMPLOYED BY SAID AGENT AND/OR PRINCIPAL WITHOUT
THE
* WRITTEN CONSENT OF TDS. THE PROPRIETARY SOFTWARE
PRODUCT
* DESCRIBED BY THIS DOCUME~T SHALL NOT BE USED,
REPRODUCED, OR
* DISCLOSED, IN WHOLE OR IN PART, WITHOUT THE WRITTEN
CONSENT
* OF TDS.
*




~=================================================*
Author Gerard J. Cerchio - a
contractor
* Written July 1989
* Version l.00
*=================================== =

#include <stddef.h.>
#include "magic.h"
#define TRUE
#define FALSE O
#define RING_WRITE_TRIGGE~ 3
int display_page = O;
void show_text (char far *, int);
void get_text (char far *, char far *, int);
void msg(char far *);
int move_screen (char far *);
int cmp_screen (char far *);
int open_file (char far *);
int creat_file (char far *);
int write_file (int, char far *, int);
int P_Compress_Gen (char *, char *, char *, int);
int memcpy (char far *, char far *, int);
int ringstore (unsigned char *, unsigned int);
int Compress (char *, char *);
char *do_compress (char *, char *, int);
/* data used throughout the record system */
extern struct res_control_prms_s fv;
extern int *next_char_in, ~next_char_out;
extern int typed_chars[l00];
struct res_key_table s *last_function_keys = NULL; /*
last key press */



. . - ~- .
- . . .
. .': ~ . .
.. .. .

.
.

WO91/00575
PCT/US90/03878
,,
240 -
int Ticks =0; /* counter bumped by clock
interrupt */
int video cols =0; /* number of colums on
display */
int video len =O; /* size of reg buffer */
int typein_size =0;
int single flag =0;
int lost key =o;
int got file name =0;
unsigned int last_function_key=0; /* number of last
function key */
unsigned int major_buf_num=O, /* write block number
*/
unsigned int minor_buf_num=0; /* record number */
char file name[l8]; /* storage for file
name */
char single_prompt[] = "Single File Name: ";
char multi-prompt[] = "Recording File Name: ";
/* ring buffer management pointers */
the screen and type in data for the recorder is placed in
a ring buffer which is allocated at the end of the
resident sections of code and data overwriting the
initialization sections and usually extending out into
the MS DOS memory. When the program TSR's this buffer
space is preserved as part af the resident task. The
beginning and end of the ring pointers are therefore set
as part of initialization. The begin_ring and end_ring
define these points. The write_ring defines the point
which data goes into the ring. The begin ring_write and
end_ring_write define the area of the ring last written
to the file
*/
int acrtused;
char ring[DEFAULT_RING_SIZE]; /* screen
buffer ring */
char *end ring = &ringtDEFAULT_RING_SIZE - 1~; /* last
byte in ring */
char *being ring = ring; /* pointer to start of
ring */
char *being ring write = ring; /* current write place
on ring */
char *end ring write = ring; /* end of last write from
ring */ -
char *write ring ptr = ring; /* start of write into ring
int num_ring writes = O; /* number of wring
buffer writes */
/* buffers */



~:
- : ; ; -.


, -:

W09l/00575
PCT/US90/03878
- 241 -

char last_crt[OxlO04]; /* storage for reference
screen */
/* Special type in data */
/*
A type in buffer is built through multiple entries into
the keyboard section of tbe code. This requires that
some state information be held in about the status of the
current type in buffer. The flag tells if a typein is in
progress. The sizel and size2 pointer point to the size
of the typein buffer. These bytes are updated every time
a key is record~ in~Q th~ ~u~fe~.
*/
char recording_typein = O; /* flag for typein in
process */
char *typein sizel; /* pointer to size 1st byte
*/
char *typein_size2; /* pointer to second size
byte */
/* work area for compression */
char tmp buf[BUF SIZE];
int accumulated_ticks = o; /* counter for sample
rate */
int waiting_for_record = O; /* counter for record
trigger */
int waiting for_settle = 0, /* flag for settle
trigger */
char did lastw flag = O; /* flag for indicating
last write to buffer */
char write_ring_flag = O; /* flag for indicating
write of buffer */
char HotFlag = O; /* hot flag */
char in_write ring = O; /* file being written
flag */
char chk_exist_flag = O; /* first time file is
written */
char FinFlag = 0; /* Finished record
flag */
char *last_curpos = NULL; /* last position of
curpos data in typein */
char last scr char~l0]; /* last single char
change on screen */
int last_scr_pos[lO]; /* position of
last scr_char */
int last scr in = 0; /* index for charater
typin ring */
int last scr_out = 0; /* index for charater
typin ring */
int last typein_pos = -1; /* last typein char
position */

. .


. ~ ~: ., .. --: ~ ,-.... .

, , : . . .:: : :
:: : , : :,: ,. . .

WO91/00575 PCTJVS90/03878
~ I'
~,i$~ 242 -
int last_char_under = O;/* last single char
under a ~yped char */
char over_run = 0;
/*************************************************/
/*
GetKBDRomFlag - Dumm routine needed to return the state
of the fv.kb_rom flag because the io.asm cannot declare
an extrn structure which is what the fv area is so that
the init routine can place the data into the TSR routine
in a reasonably organized structure.
*/

GetKBDRomFlag() ( return (FinFlag ? O : fv.kb_rom_flag);

/*************************************************/
/*
Clock interrupt - this routine is called when the
recorder is active and the clock interrupt happened. The
routine calls the screen compare if it is time to and
record the screen if necessary. This routine returns 0
if all work is done. If the ring buffer needs to be
written to disk then this routine returns l. The
assembly code then performs the checks necessary to clear
for disk IO. If the checks work out then the write_ring
routine is invoked. Otherwise the buffer will not be
written till a subsequent clock tick.
*/
-- /*************************************************/:,
int Clock_tick()
register int file;
/*msg("Clock_tick");*/
if (Igot file name :: over run ;; in_write_ring :: FinFlag
:: chk_exist flag ;:
single_flag )
{ . .~
if (over_ N n)
FinFlag = l;
recording typein = got_file_name = O;
write_ring_flag = l;
return;
)




if (in_write_ring) return ();
if (FinFlag && Idid_lastw flag)
record_screen~l);



. . .
. . -,

' ~ ` .

WO91/00575
2 ~ g ~cr/usgo/03878
f .. ` - .
- 243 -
did lastw_flag = 1;
if (FinFlag) return(l);
if (chk exist_flag == 2)

get_text ("File exists, Append, Overwrite, or
Escape? <A,O,Esc>", &chk exist flag, l);
if (chk_exist flaq == OxlB)
write ring_flag = FinFlag = got_file name =
chk exist flag = HotFlag = O;
return;
)




if (single_flag) return(single_screen());
if (!got file name)

get text(multi-prompt, file name, O);
if (*file_name == 0)
(
HotFlag = O;
return(O);
)




last function keys = NULL;
begin_ring write = end_ring_write = write rinq Ptr =
begin ring;
write_ring flag = l;
ma;or buf num = minor buf num = O;
next char in - next char out = typed_chars;
chk exist flag = 1;
got file name = TRUE;
record screen(l);
)
)




if (waiting_for record) /* waiting for record hold
off time? */
(




if ((waiting_for settle == 2) && Iscreen different())

waiting for record = l;
waiting_for_settle = 0;


if (--wiating_for record) return(O); /* keep waiting */
if (waiting_for settle == 1)

(




waiting for record = fv.settle time max -
fv.settle_time_min;
waiting_for_settle = 2;




., . - ~ ,....

.. .... . .

WO91/00~75
244 - PCT/US90/0387

return (0);

/* finished waiting do the screen record */
)




else /* inbetween sample times */
if (++accumlated ticks < fv.sample_rate) /* don~t do
anything */
return (write_ring_flag);
if (Iscreen_different~)) /* screen not differentOO.
done */
accumlated_ticks = 0;
return (write_ring_flag);
if (fv.record_holdoff) /* screen differentOOO
wait?? */
waiting_for_record = fv.record_holdoff;
return (0);

if (fv settle_time_min)
waiting_for_record = fv.settle_time min;
waiting_for_settle = 1,
return (0);
)




/* detected a change do-record there is no hold off time

/* time to record the screen */
waiting_for_settle = accumlated_ticks = 0; /* reset
counter & flag */
record_screen(l);
if (num_ring_writes > RING_WRITE_TRIGGER) write_ring flag
= TRUE;
return (write_ring_flag);

snap_header()
register int i;
for (i = 0; i < 4; i++)ringstorec (0);
ringstorec (Ox36);
ringstorec (0);
ringstorec (0);
ringstorec (Ox83);
ringstorec (0);



.. - ,,

- . ; - . . . ., - -, . -.
..

.

WO91/00575
.. PCT/US90/03878

- 245 _ 2Q~ J~
ringstorec (0);
if (video_cols == 80)
ringstorec (Ox99);
ringstorec (Ox64);
else
ringstorec (0);
ringstorec (0);.
for (i = 0; i 10; i++1ringstorec (o);

single screen()
register int unsigned i;
if (write_ring_flag) return (write_ring_flag);

get text(single_prompt, file_name, 0);
if (*file_name == 0) return (HotFlag = single_flag = 0);
move_screen(last_crt);
- snap header();
i = Compress (last crt, tmp_buf);
ringstore (tmp_buf, i+l); .
if (video cols == 80)
: ringstorec (0);.
-; ringstorec (0);
ringstorec (Ox8F);
ringstorec (OxF8);
ringstorec (Ox87);

: snap-header ();
i = Compress (&last_crt[2000], tmp_buf);
ringstore(tmp_buf, i+l);
for(i = l; i < 6; i++) ringstorec(i);

end ring_write = write ring_ptr;
return (write_ring_flag = TRUE):
/*************************************************/
/*
screen different - see if the screen is significantly
different
ThiS routine is called after every sample time is
elapsed. The routine calls an assembly routine which
compares the screen to see if any difference is on it



, .: ., .......... . , -
. : : . ~ . :, :. . .. , - . . .:

WO91/00575 PCT/US90/03878
..
246 -
since the last sample was taken. If there is only one
difference lt is taken as a single typed character. If
the type-in position flag is set the character & its
position is recorded in the small ring buffers.
If there is a d~fference and ignore region areas are
active this routine calls first the ignore region
qualifying routine to see if it is necessary to further
look at the screen. If the screen qualifies for ignore
region then scrdifig is called with the proper paramters
and the screen is compared without considering the
IGNORE_40 or 80 section of the screen as is appropriate
to current screen di~play mQd~.
*/
/*************************************************/
screen_different ()
register int tmp;
char buf[80];
/*msg("screen_different");~/
tmp = cmp_screen (last_crt); /* striaght off
compare */
/* if tmp == -1 then there is more then one difference if
it is 0 then none if tmp is some number that is the
position of the single diffe~ence */
if (tmp ! = o) /* any difference found? */
if (video cols == 80 && fv.ig80.flag && qual80())
/* IGNORE 80? */
tmp = scrdifig(tmp, 160, fv.ig80.max, fv.ig80.min,
fv.ig80.xmax, fv.ig80.xmin);
else if (video_cols == 40 && fv.ig40.flag && qual40())
/* IGNORE 40? */
tmp - scrdifig(tmp, 80, fv.ig40.max, fv.ig40.min,
fv.ig40.xmax, fv.ig40.xmin);
move screen(last crt); /* new reference */
if (fv.typein_pos flag && (tmp > 0)) /* process typein
pos? */
last scr char[last_scr_in] = last crt~tmp];
last_scr_pos[last_scr_in++] = tmp;
if (last_scr_ln == 10) last_scr_in = 0;
)




return (tmp == -1 ? 1 ; 0);



' . ' ,," `

W091/00575 PCT/US90/03878
~; 2 ~
' ' '! - 247

/ * * * * * * * */
scrdifig - do a screen compare ignore some regions
/*************************************************/
scrdifig (register int tmp, int colsw, int max, int min,
int xmax, int xmin)
register int ndiff = -l;
int hold_diff = 0;
if (tmp == -l)tmp = cmp_screenl (tmp, last_crt~;
o
if ((tmp > max) ;; (tmp < min) :: (tmp % colsw <
xmin):;(tmp % colsw > xmax))
if (++ndiff) return (-l);
else hold_diff = tmp;
tmp += 2;
tmp = cmp screenl(tmp, last_crt);
while (tmp);
return (hold_diff);

/ * * * * * */
qual 80 & 40 - if a quali$ying sting is provided check
for it
/*************************************************/
qual80()
if (fv.ig80.flag == l) return (l);
return (crtcmp (fv.ig80.qualpos, fv.ig80.string,
fv.ig80.qlen));

qual40()
if (fv.ig40.flag == l) return (l);
return (crtcmp (fv.ig40.qualpos, fv.ig40Ostring,
fv.ig40.qlen));

/*******************************~*****************/
ring buffer management




,: , , " .

Wosl/0057s
PCT/US90/03878

- 248 -


Most of the memory used by the resident portion of the
recorder is contained within the recorder's ring bufferO
Several pointers are maintained within this structure.
The first pointer is the beqin of the next write to diskO
This is the data at risk. The system begins the write to
the disk file at this mark. The next is of course the
next write into buf pointer. This pointer is the last
valid information in the buffer and the end of the write
to disk area. The next pointer points at the last type
character buffer in the ring.
*/
/*************************************************/
do_ring_write()
- register int file, i;
/*msg("do_ring write"); */

lost_key = 0;
in write_ring = TRUE;
if (chk_exist_flag && (file = open_file (file_name)) I=
o

if (chk_exist_flag == ~0' :: chk_exist_flag == 'o~
/* overwrite */

close_file(file);
file - creat_file (file_name);
)
else if (chk_exist flag == ~A' :: chk_exist_flag ==
'a' seek file (file, 39); /* append */
else

close file(file);
chk_exist_flag = 2;
in_write_ring = FALSE;
return;
)
else if (single_flag)file = creat_file(file name);
else if ((file = open file(file_name)) !=
O)seek_eof(file);
else file = creat file(file_name);
chk_exist_flag = 0;
if (begin_ring_write l= end ring write~ write_it(file);
if (FinFlag)
store_ascii (major buf_num++);



., '~ ~ . ' .
.

WO91/00~75
PCT/US90/03878

ringstore (0); - 249 ~ 3 ~-
ringstore (OxlE);
ringstore (3);
for (i = 0; i< 33; i++)ringstorec (0);
ringstorec(3);
for (i = O; i <33; i++) ringstorec (O);
end_ring_write = write ring Ptr;
write_it (file);
FinFlag = single_flag = HotFlag = did_lastw flag = O;
if (over_run)
show text ("Buffer oVerrun, stopping record~
34);
over_run = 0;
)




else show_text ("Recording complete...", 26);
)




if (FinFlag I I single_flag) FinFlag - single_flag =
HotFlag = 0;
write_ring flag = FALSE;
close file (file);
if (lost key_)blip();
in write ring = FALSE;
/*msg("end_ring_write");*/
/***************************'*.*********************/
/*
write_it - does the write to the file and adjusts ring
pointers
*/
/*************************************************/
write it(int file)
if (begin ring write < end ring write)
write file(file, begin ring write, end ring write
begin ring_write);
else
wrlte file(file, begin ri~g write, end ring -
begin ring_write);
write file(file, begin ring, end ring_write -
begin ring);
begin ring write - end ring write;
numn_ring writes = 0;
)




/*************************************************/
/*
XB interrupt - This routine fields the keyboard interrupt
after the resident rom bios routine is called during a



..
. , ~ ,: -

~: , ,:: :. . .. ::
- , . : .. .: :. : :
.

wosl/oo~75 PCT/U590/03878

2 ~ ~ clock. The scan character lS sitting on the stack as the
keyboard character
/*************************************************/
void K~ interrupt() -

register struct res_key_table s *rkeytab =&fv.res key tab[0];
register char ascii;
unsigned int typein code;
unsigned char scan_code;
while(next char in I = nèxt char out)
typein_code = *next char out++;
if (next_char_out == &typed charsts9]) next_char_out
= &typed charst0];
ascii - typein_code & OxFF;
scan code - typein code >> 8;
while (rkeytab->scan code && (rkeytab->scan code ! =
scan_code))
rkeytab++;
if (rkeytab->scan code && (rkeytab->ascii_code ==
ascii))

if (rkeytab->ctl type == IGNORE KEY) co`ntinue;
if (rkeytab->ctl type -- FUNCTION KEY)
if (fv.function_holdoff) waiting for record
= fv.function holdoff;
else if (fv.settle_time_min)
waiting for record = fv.settle time min;
waiting_for_settle = l;
else waiting for record = l;
last function keys - rkeytab;
if (fv.typein_pos_flag)
last scr_out = last_scr_in = 0;
continue;
)




if (fv.typein pos_flag)
while (last scr in I - last_scr out)
record key(last_scr char[last_scr out]);
else if (ascii &&



.
.' ' ' :''
,

W091/00575 PCTiUS9o/03878
,~; 2 Q ~
- 251 - ;
((ascii >= ~ ~) && (ascii <= ~~~)) I I '
(rkeytab->ctl_type == TYPED KEY) ) )
record_key(ascii);
)
/***************~*********************************/
/*
record_key - record the given character into type in
buffer
*/
/*************************************************/
record key (char asc code)
register unsigned int tmp = last_scr_pos[last_scr out],
sav;
/********************** autoexit KLUDGE
************************/
: /******~*************** autoexit KLUDGE
/
struct res key table s rkeytab, *savkeytab;
if ((last typein-pos I = -1 ) && fv.typein_pos_flag &~
` fv.typein auto keya &&
((last_typein pos < t~p - 2) ¦¦ (last typein Pos i


- savekeyt~b = last function keys;-
: last_function keys - &rkeytab;
last_function keys->scab code = l;
last function keys-.row - fv.typein auto_keya;
last function keys->col = fv.typein auto keytab;
last_crt[tmp] = last char_under;
sav = fv.typein auto_keya;
fv.typein auto keya - O;
: if (--last_scr-out < O) last_scr_out = g;
record screen(O);
if (++last scr_out -- lO) last_scr out = O;
fv.typein auto keya = sav;
last crt[tmp] = asc code;
last typein pos = - l;
last function keys = savekeytab ;
/********************** autoexit KLUDGE
************************/
/********************** autoexit XLUDGE
************************/
if (recording_typein --O)




.. . . , -. ~. .. .

: . . . - ,- ::.
. :: ~

wo9l/oos7s PCT/US90/03878
- ., ' :: `
j* now setup the type in header */
store ascii(major bUf num++);
typein sizel = write_ring_ptr;
ringstorec(o);
typein size2 = write_ring_ptr;
ringstorec(0);
ringstorec(1);
typein_size = 3;
/* set the flag for type in record and proceed as
normal*/ .
recording typein = 1;
last_typein pos = -1;
last_curpos = ~ULL;

/* two zeros then the ascii code */
ringstorec (o);
ringstorec (o);
ringstorec (asc code);
/* now put the current cursor position in */
if (fv.typein_pos flag)
tmp = last scr pos[last scr out++];
if (last scr out == 10) last_scr_out = o;
)




else
tmp = get_cursor ();
if (video cols == 80) tmp = (tmp >> 8) * 160 + ((tmp
OxFF) *2);
else tmp - (tmp >> 8) * 80 + ((tmp & OxFF) *2) ?
tmp -= 2; - -

last typein_pos = tmp;ringstorec ~tmp / 100);
ringstorec ~tmp % 100);
/* finally set the syze bytes in this one's header */
typein size += 5;
*typein_sizel = typein si,ze / 100;
*typein size2 = typein_size % 100;
return;

-/***********************~*************************/
/*
do_typein_trailer - finish a typein record
This routine is necessary ~ecause the 22 byte header
really isn't. (22 bytes) turns out there is a ascii
number a the record size tacked onto the end of every
record in the system. This routine provides this
essential data before writing the next record.




. , , ~; ,

WO91/00575 PCT/US90/03878
2 ~
- 253 -
*/
/***********~*************~***********************/
do_typein_trailer ()
/* finish up the typein ~uffer with minor buff number
then size*/
/********************** autoeXit RLUDGE
************************/
/********************** autoexit KLUDGE
************************/
register unsigned int tmp -
last_scr pos[last_scr_out], sav; r
struct res_key_table s rkeytab, *savkeytab;
if ((last_scr_in l= last_scr_out) &&
fv.typein_pos_flag && fv.typein_auto_keya)
save - fv.typein auto_keya;
fv.typein_auto-keya = 0;
record_key (last_scr_chartlast scr out]);
fv.typein_auto_keya = sav;

/********************** autoexit KLUDGE
************************~ .
/********************** autoexit KLUDGE
.~ ************************~ .
; recording typein =
- ringstorec (Ox20);
store ascii ~minor_buf num++);
ringstorec (*typein_sizel);
ringstorec (*typein_size2);
num_ring_writes++;
end ring_write = write ring_ptr;
last_typein_pos = -1;
}




/*************************************************/
/*
record_screen - record a screen
This routine is called whenever the recorder wishes to
create a screen record in the ring buffer.
*/
/*************************************************/
record-screen (int move)
(




char *hdr_ptr;
register unsigned int i;
unsigned int ~;



: .. . . . .
.. ; . . ..

WO91/00575 PCT/US90/03878

254 -

/*msg ("record_screen") i*/
if (recording_typein) do_typein_trailer (); , ;
store_ascii (major_buf_num++);hdr ptr = write_ring_ptr;
setup_hdr ();
if (move) move_screen (last crt);
i = Compress (last_crt, tmp buf);
ringstore (tmp_buf, i + l);
i += 27;
*hdr_ptr = i /lO0;
*(hdr_ptr +l) = i ~lO0;
store_ascii (minor_buf_num++);
ringstorec (*hdr_ptr~+);
ringstorec (*hdr_ptr);
if (video_cols == 80)
store_ascii (major buf_num);
hdr_ptr = write_ring_ptr;
setup hdr (0);
i = Compress(&last_crt[2000], tmp buf);
ringstore (tmp_buf, i + l);
i += 22;
*hdr_ptr = i /lO0;
*(hdr ptr +l) = i ~lO0;
store ascii (minor buf num++);
ringstorec (*hdr ptr++);
ringstorec (*hdr_ptr);
end ring write = write_ring_prt;

/*************************************************/
/*
setup hdr - setup a recorded screen header
This routine sets up the 22 byte header for each recorded
screen. For now I robbed this from the previous
incarnation of the recorder. This was done for security
in knowing that it already works. This routine is to be
expanded before the finished product to allow for 40 col
screens
/*************************************************/



,
: .

WO9l/00575 . . PCT/US90/03878
.
~ 255 - 2~
setup_hdr ()
register int tmp, i;
/*msg ("setup_hdr");*/

for (i = 0; i < 7; i++) ringstorec (0); /* [0] to
t6] */
ringstorec (Ox83); /* pfrom
[7] */
/* next handel the function key if there is one */

if (last_function_keys && last_function_keys-
>scan code)
ringstorec(last_function_keys->row); /* [8] and
t9] */
ringstorec(last_function_keys->col);
else
ringstorec (24); /* L 8] and
[9] */
; ringstorec (133~;
3 . .
/* set the cursor position *~.

tmp = get_cursor ();
if (video cols == 80)
tmp = (tmp >> 8) * 160 + ((tmp & OxFF~ * 2);
i = (tmp / 100 1 Ox80;
else
tmp = (tmp ~> 8) * 80 + ((tmp & OxFF) * 2);
i = tmp / 100;
ringstorec (i); /* tlO] and
[11] */
ringstorec ttmp % 100);

ringstorec (0); ~ . /* [12] */
for (i = 13; i < 22; i++) ringstorec (0); /* [13] to
[21] */
/*************************************************/
store ascii - place an ascii number into the ring
buffer




: ",, .: , ., : - . .
. ,: . :
: .:: . . ; : .
- : , - :

Wos1/00s7s PCT/US90/~3878
~$`~ 256 - ~ `
This routine converts the interger argument into 3 ASCII
digits then places each of the digits into the ring
buffer
*/
/************************************************/
store_ascii (int i)
ringstorec ((i / lO0) + '0~);
ringstorec ((i % lO0 /lO) + '0');
ringstorec ((i % lO) + '0');

/******************~*****~*******~*************~**/
/*
ringstorec - move a single byte into the ring buffer
This routine performs an efficient storage of a single
byte into the ring buffer adjusting the write pointer as
necessary
*/
/****************~********************************/
ringstorec (char c)
register char *tmp = write_ring Ptr;
*tmp++ = c;
if (tmp == end ring) tmp = begin ring;
if (over_run 1 T tmp == begin ring write)
over run = l;
write ring ptr = end_ring_write;
return;
write_ring_ptr = tmp;
)




/*************************************************/
/*
ringstore - store a bloc of memory into the ring buffer
~his routine moves a block of memory into the ring buffer
adjusting the write ring ptr as necessary. The move is
broken up into to memcpy's if necessary
/*************************************************/
ringstore (register unsigned char *cptr, register unsigned
int size)
/*msg ("ringstore");*/




,,,: . - ; : , ~: ,

WO 91/005?5 Pcr/usgo/03X7~ ` ' ' '

257 - 2

while (size--_
ringstorec (*cptr++~; r
; num_ring_writes ++;
: ' /*================================================ */
**************************************************
* Routine compress (pbufin, pbufout, pbufw,
psize);
* Purpose Compresses the display in pbufinL03
on.
* First, the characters and attributes
are
* separated into bottom and top of
buffer (into
* pbufout [] and pbufw), then each
group of 3
* or more "like" bytes are changed to
"OxFF,
byte, nbr", where nbr is the number
of bytes
* in the "like" string. If 1 or 2
oxFFls are
* encountered in the input, they are
changed to
* a "OxFF, Ox~F, nbr" series.
* If nbr is > 249, the series is:
* "OxFF, byte, nbr/256+249, nbr%256"
*




* Note 1 The output buffer will be used (all
psize
* bytes) for working storage before
being used
* as the output buffer (pbufout t]).
* Note 2 The input buffer may be used as the
output
* buffer, if desired.
* Note 3 Each buffer must be at least psize in
size.
*




* Parameters none
*
* Note: Don't change this routine - it works and is very
* efficient.
*




***********************************************,t**
*/
,


- - ,- - .- ~ - - .-. . .

- ~ .

. , ,
:.: : .. . . ...

WO91tO0575.. j PCT/US90/03878
~a~9~- - 258 -
int Compress ~char *src, char *dst)
register int i;
char *tmp;
/*msg ("Compress");*/
tmp = do_compress (src, dst, video_cols == 80 ? lOoO
1000);
i = tmp - dst;
dst = tmp;
tmp = do compress (src + 1, dst, video cols == 80 ?
1000: 1000);
i += tmp - dst;
return (i -1);

char *do compress (register char *src, register char *dst,
int len)
int i, j;
unsigned char dup;
/*msg ("do compress");*/
for (i = 0; i < len; i++)
if (*src == *(src +2) && *src == *(src +4))
(




*dst++ = OxFF; /* need to
compress */
dup = *dst++ = *src;
. ~ src +=~2;
for (j = l; j < len - i; j++) /* count the
dups */
if (dup l= *src) break;
else src += 2;
if (j < 250) *dst++ = j; /* over 249? */
else
*dst++ = j / 250 + 249;
*dst++ = ~ % 250;
) /* adjust count
/
i += j - l;
else if (*src I = OxFF) *dst++ = *src, src += 2; /* no
compress */
else
*dst++ = OxFF; /* handle OxFF
in data



.

,

WO91/0057~ PCT/US9~/~3878
~ - 259 - 2~

stream */
*dst++ = OxFF;
*dst++ = l;
src += 2;
if (*src = OxFF && i < 999)
*dst - 1) = 2;
src += 2;
i++;
)




return (dst);

#ifdef DEBUG
char bufl[4000];
char buf2[4000];
main ()

move_screen (bufl);
Compress (bufl, buf2);

#endif
/* not sure this will ever ~rk but save it any wayO.0O
if (last crt[tmp] I= *last_curpos)
if (last crt~tmp -2] -= *last_curpos) tmp -=2;
. . else if (last crt[tmp +2] == *last_curpos) tmp
+=2;
if (last_crt[tmp] == ~last_curpos)
(




last curpos++;
*last_curpos++ = tmp / 100;
*last curpos++ = tmp % 100;
last_curpos++;
last curpos++;

buf[0] = last crt[tmp]/100 + 'o'
buf[l] = last crt[tmp]/lO) ~ 10 + 'o';
buf[2] = last crt[tmp]~10 + '0';
buf[3] = ' ';
buf[4] = ' ';
buf[5] = tmp /1000 + '0';
buf[6] = (tmp /100) % 10 + '0';
buf[7] = (tmp /10) % 10 + 'o';
buf[8] = tmp ~ 10 + '0';
buf[9] = 0;
show text (buf, 32);


, .. -- - ~


: . - : :: : . . : : :
:,~ .:: :: :, . : ~ .,:,.:.

, . ,

WO91/00S75
- PCr/~JS9010387x
` - 260 -

~/
Title Inthndlr
page 44, 132
;==============================================,==
P R O P R I E T A R Y N O T I C E
; THIS DOCUMENT DESCRIBES A PROPRIETARY SOFTWARE PRODUCT
OF TDS
; HEALTHCARE SYSTEMS CORPORATION (TDS), CONTAINS TRADE
; SECRET AND PROPRIETARY INFORMATION, IS AND SHALL REMAIN
AN
; UNPUBLISHED WORK PROTECTED BY COMMON LAW COPYRIG~T, IS
LOANED
; FOR LIMITED PURPOSES ONLY, REMAINS THE PROPERTY OF TDS,
AND IS
; TO BE RETURNED UPON REQUEST OR COMPLETION OF THE PURPOSE
OF THE
; LOAN, WHICHEVER IS SOONER. ACCEPTANCE OR RECEIPT OF
THIS
; DOCUMENT BY THE AGENT AND/OR PRINCIPAL TO WHOM IT IS
LOANED IS
; AN ACKNOWLEDGEMENT THEREBY THAT IT IS BEING RECEIVED IN
; CONFIDENCE AND THAT IN CONSIDERATION FOR THE LOAN
NEITHER IT
; NOR ANY OF THE INFORMATION IT CONTAINS WILL BE
REPRODUCED,
; USED, OR DISCLOSED, IN WHOLE OR IN PART, BY OR TO ANYONE
NOT
; HAVING A NEED-TO-KNOW CONSISTENT WITH THE PURPOSE OF THE
LOAN
; OR ANYONE NOT EMPOLOYED BY SAID AGENT-AND/OR PRIN~IPLE
WITHOUT
; THE WRITTEN CONSENT OF TDS. THE PROPRIETARY SOFTWARE
PRODUCT
; DESCRIBED BY THIS DOCUMENT SHALL NOT BE USED,
REPRODUCED, OR
; DISCLOSED, IN WHOLE OR IN PART, WITHOUT THE WRITTEN
CONSENT OF
; TDS.
;




;=================================================
, Name: inthndlr.asm
; Description: Routines to handle the interrupts- for the
MAGIC
; recorder
;




; This is the section of assembly code that contains all
of the
; entry points for the Magic recorder. The code is
modified from
; an article in the MS DOS encyclopedia and is modified to


- -. . ~; , -

. .:

: .. '.,; :,
- ' -',.,, ' ;, , ~ , :

W091/OOS75 . PCT/US90/03878
f- - 261 _ 2~
; perform the recorder. Most of this code setups up thè
inter-
; rupt structure in the machine so that the following
interrupt
; pass through the recorder for the following reasons:
; ISR 5 Print Screen Non re-entrent uses stack
; ISR 8 Hardware interrupt for clock we make our
own chain
; ISR 9 Hardware interrupt for keyboard
; ISR 10 Video BIOS non-reenternatk uses stack
; ISR 13 DASD BIOS non-reenternat uses stack
; ISR 23 Control break from the BIOS
; ISR 24 DOS critical error may be called duri~g
our
; . disk ID
; ISR 28 DOS idle interrupt lets us work when DOS
is
; . waiting on the KB
; ISR 2F DOS multiplex interrupt we identify
ourselves
; in this chain
ISR 21 DOS comma~d request monitors DOS activi*y
, Perhaps a little overkill may be in here especially with
print
; screen but it gives us an extra margin of safety for
working
; with a number of different DOS applications.
;




MultiplexID EQU 08Ah ; unique INT 2FH ID value
TSRStackSize EQU 250h ; resident stack size in bytes
XB FLAG EQU 17h ; offset of shift-key status
flag in
KB TAIL EQU lCh ; offset of KB tail buffer
pointer
; ROM BIOS keyboard data area
KBIns EQU 80h ; bit masks for KB_FLAG
KBCaps EQU 4Oh
KBNum EQU 2Oh
KBScroll EQU lOh
KBAlt EQU 8
KBCtl EQU 4
KBLeft EQU 2
KBRight EQU
JustShifts EQU KBAlt OR ~BCtl OR KBLeft OR KBRight
SCEnter EQU lCh
CR EQU ODh




, .::.. ' , ,;'. ` :, , ,. ~. . ::' '

' ' ~ ~ ' ' , . i ' ' . . I
,:, ~ . ' , ~". ' . . .
'.... ': , :

WO 91/00575
, PCT/US90/03878
~ ' ' (~ I
-- 262 --
EQU OAh
TRUE EQU -1
FALSE EQU 0 , .
PAGE
.________________
________________________________________.
_____ _
; RAM-resident routines
;




_______________
_______
.MODEL SMALL
.CODE
extrn _Clock_tick;near ; resident C code
extrn do_ring_write:near ; resident C code
extrn _KB_interrupt:near ; ditto
extrn _record_key:near ; ditto
.DATA
INCLUDE MAGIC.INC
extrn _single flag:byte
extrn _FinFlag:byte
extrn write_ring_flag;byte
extrn got_file_name;byte
extrn HotFlag:byte
extrn noshift xlat:byte
extrn shift xlat:byte
extrn ctrl) xlat:byte
extrn capsl xlat:byte
extrn _alt xlat:byte
extrn _Ticks:word
public inGetText
_inGetText db O

public _fv
_fv res_control_prms ~ <>
public _typed chars
typed chars dw 100 dup (0)
public next char in, next char out
_next char in dw offset typed chars
_next_char_out dw offset typed_chars
.CODE
____________________
_______
; System verification routines read the state of the
interrupt




. ',, . ',... .., ,.~: ~ ' .
:: ~ .::. : .
. .

WO9l/00575. PCT/US90/03878

- 263 -
; routines 2 ~ ~ ~ J
;

public VerifyDOSState
VerifyDOSState PROC near ; Returns: carry
flag
; set if MS-DOS
is busy
push ds ; preserve these
; registers
push bX
push ax
xor al, al
cmp al, cs;InISR21 ; in DOS?
pop ax ; restore
registers
pOp bx
pop ds
ret
VerifyDOSState ENDP
VerifyIntState PROC near ; Returns: carry
flag
; set if hardware
or ROM
. ;BIOS unstable
push ax ; preserve AX
; Verify hardware interrupt status by interrogating Intel
8259A
; Programmable
; Interrupt Controller
mov ax,OOOOlOllb ; AH = O
; AL = OCW3 for Intel
cli ; 8259A (RR=l,
out 20h,al ; request 8259A's in-
; service register
jmp short ~10 ; wait a few
cycles
s L10: in al,20h ; AL = hardware
inter-
; rupts
currently
cmp ah,al
jc Lll ; exit if any
hardware
; interrupts
still
; being serviced


- .:.. .... .. .

- ;.. .. , : ",

:. '. :, , :
: . ~.: . :
: .. ~ -

~ ` :

WO91/00575 PCT/US90/0387

264 -

; Verify status of ROM BIOS interrupt handlers
xor al,al ; AL = OOH
cmp al,cs:InISR5
jc L11 . ; exit if
currently in
; INT 05H handler
cmp al,cs;InISR9
jc L11 ; exit if
currently in
; INT 09H
handler
cmp al,cs;InISR13 ; set carry flag
if
; currently in
INT 13H
; handler
Lll: pop ax ; restore AX and
return
L20: ret
VeryfiyIntState ENDP
VerifyTSRState PROC near t Returns: carry
flag set
; if TSR inactive
call VerifyDOSState~
jc L20 ; exit if MS-DOS
unstable
call VerifyIntState ; set carry flag if hard-
; ware or BIOS
ret
VerifyTSRState ENDP
PAGE
------_______________
_______
; System monitor routines
----__________________
_ _____
ISR5 PROC far ; INT 05H handler
; (ROM BIOS print
; screen)
inc cs;InISR5 ; increment status flag




.: - .: ~
..

WO9l/OOS7~ PCT/US90/03878
~ `: 2 ~
.. - 265 -
mov cs:InISR21,0 ; decrement status flag
popf
sti
ret 2
ISR21 ENDP
____________~__ ____
_ __ _ _ _ _
; Timer Tick
__________________
__ ____
public ISR8
ISR* PROC far ; INT 08H handler (timer
; tick, IRQO)
pushf
call cs:PrevISR8 ; chain to previous
; handler
push ds
mov ds, cs:TSRDS
inc ds: Ticks ; bumb our ticker
cmp ds;_HotFlag, TRUE ; turned on?
jne L31 ; no
cmp cs:InISR8,0
jne L31 ; exit if already in
; this handler
inc cs:InISR8 ; increment status flag
sti ; interrupts are ok
call Tick
cli
cmp ds:_write_ring flag, O
je L30
cmp cs:doingwrite, O
jne L30
call VerifyTSRState
jc L30
inc cs:doingwrite
sti
call TSRwrite
dec cs:doingwrite
- L30: dec cs:InISR8
L31; pop ds
iret
ISR8 END~




. . ~
- .. i, : . ::
- , ., - .. .
, .. .: .. ,,., : . -
- . ~: ~ . ,- , ..
~ , .. , . .: - , ~ .
, . . ..

WO91/00~ ~ j PCT/US90/03878
2 ~ v , t
- 266 -

____________________
_______
; Keyboard interrupt
_____________
_______
ASSUME cs:_TEXT,ds; DATA
public ISR9
ISR9 PROC far ; INT 09H handler
; (keyboard interrupt
; IRQl)d
push ds ;preserve these registers
push es
push ax
push bx
mov ds,cs;TSRDS ; point to res data
mov bx,4Oh
mov es,bx ; ES-> ROM BIOS data area
mov bx, ex;[KB TAIL]; BX -> Key buffer
in al,60h ; AL = current scan code
pushf ; simulate an INT
cli
call cs:PrevISR9 ; let previous handler
; execute
. cli
test al,80H ; break? .
-- .~ . jnz- L43 ; yes out.of here
cmp inGetText, O ; dumping chars?
je nodmp ~; no
cmp _fv.no_kb_rom_flag,O ; rom code in use?
je nodmp ; using rom code
mov es:[KB TAIL],bx ; pull back the pointer
nodmp: cmp cs:InISR9, 0 ; if already in this
; handler
jnz L43
inc cs:InISR9 ; increment status flag
sti ; now interrupts are ok
; get shift state
mov ah,es:[KB FLAG] ; AH = ROM BIOS shift-key
; flags
and ah, JustShifts ; clear out extraneous
; info
;




, ah = shift state al - scan code
cmp _FinFlag,O ; going off?


~. . . ~ .
: - , . . ~, , : ,
, - ., . .:, . . . .
, . : :, - ;,: : :
:; . .: :.; :- : , : ~ .

;
" -

wo 91!00s75 2 ~ ~ ~ Q9 ~CT/US90/03878

- 267 -
pushf
cli
call cs;PrevISR5 , chain to previous INT
; 05H handler
dec cs;InISR5 ; decrement status flag
iret

ISR5 ENDP
________________
_______
; System 21 intr routines
____________
_______
ISR21 PROC far ; INT 21~ handler
pushf
dir21: sti
cmp ah, 4Bh ; exec?
jne noex ; no
popf
jmp cs:PrevISR21 ; direct
noex: or ah, ah ; zero?
jne noz ; no
mov ah, 4Ch ; quick change
noz: mov cs:InISR21,1 ; status-flag
mov cs:DosCmd, ah ; set command
popf
pushf
call cs:PrevISR21 ; chain to previous INT21
pushf
cli
cmp cs:doingwrite, O
jnz nowt
push ds
mov ds, cs:TSRDS
cmp ds: write ring_flag, O ; need a write?
pop ds
je nowt ; no
inc cs:doingwrite
sti
; call TSRwrite
dec cs:doingwrite
nowt: sti


, ., ..
- . :~
,:,: .- - . . , :
. . :,: :. : - . . ,., :.
.. . ~ . . . . . -


- :., , ,.,:,

Wo91/00575 , PCT/US90/03878

~ .i3 j L42 ; nothing to do
cmp _HotFlag,O ; on?
jne got_key ; jump C key routine
cmp al, fv.start_key ; are we starting up?
je L40 ; yes, check it out
cmp al, _fv.single_rec_key ; single screen?
jne L42 ; no chance
, single screen record possible
cmp ah, _fv.single_rec_shifts ; proper
; shifts?
jne L42 ; no
mov _single_flag, TRUE ; mark it
mov _HotFlag, TRUE ; turn it on
jmp L42 ; all done
; get shift-key state
L40: cmp ah, _fv.start_shifts ; proper shifts?
jne L42 ; no
; Set flag when hot key is found
mov byte pt~ HotFlag, TRUE ;;; turn it on
L42: dec cs.InISR9 ; decrement status flag
L42: dec cs:InISR9; decrement
status flag
L43: pop bx; restore registers and
exit
pop ax
pop es
pop ds
iret
; this code is executed when the recorder is on and we are
recording keystrokes

got key: cmp single flag, TRUE;
recording a single?
je L42; yes ignore key
cmp al, fv.stop_key; maybe
done?
jne reckey; no




. . : . -.. . . :

WO91/00575 2 ~ ~ ~ 8 9 ~CT/~S90/0387~

.. - 269 -
cmp ah, fv.stop shifts;
really the key?
jne reckey; no, just
record.....
mov _FinFlag, TRUE;
. mov _write ring flag; TRUE;
need a write
mov _got_file_name, O; can
file name
cli
cmp cs;doingwrite,
~ne L42
call VerifyTSRState
jc . L42
inc cs:doingwrite
stl
; call TSRwrite
dec cs;doingwrite
jmp L42; finished

; we are recording a path of screens and keys store in a
ring buffer
reckey: mov _last scan_code, al,
store the code away
cmp fv.no kb rom_flagrO~
doing our own rom xlat?
jne romnogood; yes
~mp romgood; just go
; due.to the:IRMA intircacacies redo rom code
romnogood:mov ah, es:[KB FLAG~; get the
shift states
and ah, JustShifts; just the
shift states
test ah, KBAlt; alt shifts?
jnz altshift; yes
test ah, KBCtl; clt shifts?
jnz cltshift; yes
lea bx, _capsl xlat; normal
caps lock
test ah, KBCaps
jZ no capsl
test ah, KBLeft OR KBRight
jz getscan
lea bx, _noshift_xlat; no
shifts
jmp getscan




.: ~" . : . ~ :. . ..

- ~ . , . . .-
- : ~ . : - - : :: , , . : . . - . .
: .
..:

WO 91/00575 ` PCI / U59~1iO3878

270-
nocapsl: lea bx, _noshift_xlat; no
shifts
cmp ah, O
je getscan
lea ~x, _shift_xlat; shift?
: test ah, KBLeft OR KBRight
jnz getscan
altshift: mov bl, al
xor bh, bh .
xor al, al; bottom is zero
mov ah, (bx + alt xlat]; get
the code
jmp storekring
ctlshift: lea bx, _ctrl_xlat; control
getscan: xor ah, ah; clear the shift
status
add bx, ax; offset into the
table
mov ah, al; scan code on top
mov al, tbx]; xlat in the low
test . al, 80h; special key?
jnz storekring; no, just
store
cmp al, -1; shift key?
je toL42; yes, ignore
cmp al, -2; lock key?
je toL42; yes, ignore
;~ cmp al, -4; ignore key?
je toL42; yes, ignore
cmp al, -3; special key?
jne spclshft; no, check more
xor al, al; no ascii code
jmp storekring
spclshft: cmp al, -5; shift special
key?
jne spclctrl; no, check more
xor al, al; no ascii code
add ah, l9h
jmp storekring
spclctrl: cmp al, -6; ctrl special key?
jne storekring; no check more
xor al, al; no ascii code
add ah, 23h
jmp storekring
romgood: mov ax, es:[bx]; get last
typed key



.. .: : . ~: .: : ; ~ ,, : .

- :; . , . :,
: :' ~ . - . , ... ,. ~ ~ , : . . , '

WOgl/0057~
PCT/US90/03878
- 271 -
storekring:mov bx, _next char in; get
the in pointer
mov [bx], ax; store it
add bx, 2; bump pointer
cmp ~x, offset _typed_chars +
jb notcadj; no adjust
mov bx, offset _ typed chars
notcadj: mov cli _next char in, bx; save
cmp cs:doingwrite, O
~ne toL42
cmp ds:_write_ring_flag, O
je toL42
call VerifyTSRState
jc toL42
inc cs:doingwrite
sti
; call TSRwrite
dec cs:doingwrite
toL42: jmp L42; finished
ISR9 ENDP
__________________ ,
; Video Bios
__________________
ASSUME cs:-TEXT,ds:nothing
ISRlO PROC far; INT lOH handler (ROM
BIOS video I/O)
inc cs:InISRlO; increment
status flag
pushf
cli
call cs:PrevISRlO; chain to
previous IN~ lOH handler
dec cs:InISRlO; decrement
status flag
iret
ISRlO ENDP
__ _______________
; Disk Bios
________________
ISR13 PROC far; INT 13H handler
; (RO~ BIOS fixed disk
I/O)




. - . ~ . .

. : . . : .

WO91/OOS75
PCT/US90/03878
- 272 -
inc cs:InISR13; increment
~g~ ~ tus flag
pushf
cli
call cs;PrevISR13; chain to
previous INT 13H handler
pushf ; preserve returned fla~s ~ i
dec cs:InISR13; decrement
status flag
popf ; restore flags register
sti ; enable interrupts
ret 2; simulate IRET without
popping flags
ISR13 ENDP
ISRlB PP.OC far; INT lBH trip (ROM
BIOS Ctrl-Break)
mov byte ptr cs:TraplB,TRUE
iret
ISRlB ENDP
_ _ _ _ _ _ _ _ _ _ _ _
; Ctrl C trap
_ _ _ _ _ _ _ _ _ _ _ _
ISR23 PROC far; INT 23H trap (MS DOS
Ctrl-C)
mov byte ptr cs: Trap23,TRUE
lret
ISR23 ENDP
_______________
; DOS critical error during our disk IO
______ ______________________ _________________________
ISR24 PROC far; INT 24H trap (MS-DOS
criti~al error)
mov byte ptr cs:Trap24,TRUE
xor al,al; AL = OOH (MS-DOS
2.x):
; ignore the error
cmp cs:Ma;orVersion,2
je L50
mov al,3; AL = 03H (MS-DOS
3.x):




.. . . .. . .
.. ... . . , . -
... . :: .. . ..
, - :.
. . . .~ . . . . ..
, . . .

WO91/00575
PCT/US90/03878
~ - 273 - 2~ Q~
; fail the MS-DOS call in
which ; the critical error;~;
occurred
L50: iret
ISR24 ENDP
--------------------------------------_____________________ !
. ; DOS idle
_____________
ISR28 PROC far; INT 28H handler
; (MS-DOS idle interrupt~
pushf
cli
call cs:PrevISR28; chain to
previous INT 28H handler
iret
inc cs:InISR28; increment
status flag
push ds
mov ds, cs:TSRDS
cmp ds:_write ring_flag, O; .
need a write?
PP ds
~e L60; no
sti
call TSRwrite
L60: dec cs:InISR28; decrement
status flag
. , .
L61: iret
ISR28 ENDP
_________________
; Multi plex for ID
_ _ _ _ _ _ _ _ _ _ _ _ _
ISR2F PROC . far; INT 2FH handler
; (MS-DOS multiplex
interrupt)
; Caller: AH = handler
ID
; AL = function number
; Returns for function 0:
AL = OFFH
; for all other
functions: nothing
cmp ah,MultiplexID
je L70; jump if this handler
is requested



- ., . . ~. .

WO91/00~75 PCT/US90/03878

274 _ r~r

jmp cs:PrevISR2F; chain to
previous INT 2FH handler
L70: test al,al
jne Getaddr
; Function O: get installed state
mov al,OFFh; AL = OFFh (this
handler is installed)
jmp MultiplexIRET
; Functionl; get data area
Getaddr: cmp al, 1; return addr?
jne MultiplexIRET
mov ax, offset _fv; structure
offset
mov dx, cs:TSRDS; and data
seg
MultiplexIRET: iret ; return from interrupt
ISR2F ENDP
PAGE
_ _ _ _ _ _ _ _ _ _ _
; AuxInt21--sets ErrorMode while executing INT 21h to .-
force.use ; ; of the AuxStack instead of the IOStack.
------______________
;




PAGE
----------__________
; RAM-resident application
--------____________
Tick PROC near
; assume ds:DATA, cs: TEXT
; Set up a safe stack
push ds; save previous DS on
previous stack
mov ds,cs:TSRDS
mov cs:PrevSPT,sp; save
previous SS:SP
mov cs:PrevSST,ss
mov ss;cs:TSRDS; SS:SP ->
RESIDENT STACK




r
,

WO91/00575
. PCT/US90/03878
~. - 275 - 2~ ;9~
mov sp,cs:TSRSPT
push es; preserve reamining
registers
push ax
push bx
push cx.
push dx
push si
push di
push bp


mov ax, next_char out
cmp ax, _next_char_in
~e tlC; no
call _KB interrupt ; go do it
tic: call _Clock_tick; tick it
pop bp
PP di
pop si
PP dx
pop cx
pop bx
. . pop ax
PP es
mov ss,cs:PrevSST; SS:SP ->
previous stack
mov sp,cs:PrevSPT .
pop ds; restore previous DS
; Finally, reset status flag and return

ret
Tick ENDP
TSRwrite PROC near
assume ds: DATA, cs: TEXT
; Set up a safe stack
push ds; save previous DS on
previous stack
mov ds,cs:TSRDS
mov cs:PrevSP,sp; save
previous SS:SP




:
:: . : .

WO91/0057S PCTiUS90io3878 r
.. '"' ' ' ~ -,~
2~8~ - 276 -
mov cs:PrevSS,ss
- mov ss,cs:TSRDS; SS:SP ->
RES I DENT STACK
mov sp, cs: TSRSP
push es; preserve remaining
registers
push ax ,
push bx
push cx
push dx .
push si
push di
push bp
; Set break and critical error traps
do_write: mov cx,cs:NTrap
mov si,offset
cs:StartTrapList
push cs
pop ds
L90: lodsb ; AL = interrupt number
; DS;SI -> byte past
interrupt number
mov . byte ptr cs:[si],FALSE;
zero the trap flag
push ax; preserve AX
moV ah,35h; INT 21~ fu~ction
35H
; (get interrupt vector)
int 2lh; ES:BX = previous
interrupt vector
mov cs:[si+l],bx;save offset
and segment
mov cs;~si+3],es;... of
previous handler
pop ax; AL = int~rrupt num~er
mov dx,cs:[si+5]; DS:DX ->
this TRS's trap
. mov ah,25h; INT 21H function
25H
int 2lh; (set interrupt
vector)
add si,7; DS:SI -> next in
list
loop L90
mov ds,cs:TSRDS




. . ..... .

- - :- '. :.: .~ . . ''. :; .' ~, . :
:: :. : ,. ; :.: - . -... .
..... . . . : . : . .. ~: .
:., :, . . : : . . : . -

WO91/0057S
- PCT~US90/03878
- 277 _ 2~ q;~.
; Disable MS-DOS break checking during disk I/O
mov ax,3300h; AH = INT 21H
function number
; AL = OOH (request
current break state)
int 2lh; DL = current break
state
mov cs:PrevBreak,dl; preserve
current state
xor dl,dl; DL = OOH (disable
disk I/O break
; checking)
mov ax,3301h; AL = OlH (set
break state)
int 2lh
; Preserve previous extended error information

sti
call do ring write; do the
write

; Restore previous ~S-DOS ~reak checking
L95: mov dl,cs:PrevBreak; DL =
previous state
mov ax,3301h
int 21h
: Restore prevlous break a~d critical error traps
mov cx,cs:NTrap
mov si,offset StartTrapList
push ds; preserve DS
L96: lods byte ptr cs:[si]; AL =
interrupt number
; ES:SI -> byte past
interrupt number
lds dx,cs:[si+l];DS:DX ->
previous handler
mov ah,25h; INT 21H function
25H
int 21h; (set interrupt
vector)
add si,7; DS:SI -> next in ;
list
loop L96
pop ds; restore DS




.. :.. .. :- . . . . ~ , ., ~

.. .. . . . . . ..

WO91/00575
PCT/US90/0387
- 278 -
2 ~ f
; Restore all registers
no_write:
pOp ~p
pop di
pop s i -
pop dx
pop cx
PP bx
pop ax
pop es
mov ss,cs:PrevSS; SS:SP ->
previous stack
mov sp,cs:PrevSP
pop ds; restore previous DS
; Finally, reset status flag and return
ret
TSRwrite ENDP
doingwrite db O
ErrorModeAddr DD ?; address of MS-DOS
ErrorMode flag
InDOSAddr DD ?; address of MS-DOS
InDOS flag
NISR DW (EndISRList-
StartISRList)/8; number of installed ISRs
StartISRList DB 05h; INT number
InISR5 DB FALSE ; flag
PrevISR5 DD ? ; address of previous
handler
DW offset ISR5
DB 08h
public InISR8
InISR8 DB FALSE
PrevISR8 DD ?
DW offset ISR8
DB O9h
public InISR9
InISR9 DB FALSE
PrevISR9 DD ?
DW offset ISR9
DB 10h
public InISR10




" ', .: : . ' :. : ' : ' '.:.

WO9l/00575
PCT/US90/03878
- 279 _ 2~
InISR10 DB FALSE
PrevISR10 DD ?
DW offset ISR10
DB 13h
public InISR13
InISR13 DB FALSE
PrevISR13 DD ?
. DW offset ISR13
DB 28h
InISR28 DB FALS~ ~
PrevISR28 DD 7 t
DW offset ISR28
DB 2Fh
InISR2F DB FALSE
PrevISR2F DD ?
. DW offset ISR2F
DB2lh
InISR21 DB FALSE
PrevISR21 DD ?
D~ offset ISR21
EndISRList LABEL BYTE
TSRPSP DW ? ; resident PSP
PrevPSP DW ? ; previous PSP
PrevSPT DW ? ; previous SS:SP
PrevSP DW ? ; previous SS:SP
PrevSST DW ?
PrevSS DW ?
TSRSPT DW offset tstack + TSRStackSize
TSRSP DW offset rstack + TSRStackSize
public TSRDS
TSRDS DW seg _DATA
HotKBFlag DB - KBAlt; hot value of ROM
DIOS KB_FLAG
HotKBMask DB (KBIns OR KBCaps OR KBNum
OR KBScroll) XOR Offh
: The following data is used by the TSR application:
NTrap DW (EndTrapList-StartTrapList) /8; number of
traps
StartTrapList DB lBh
TraplB DB FALSE
PrevISRlB DD ?
DW offset ISRlB




. .
.. . :.,

.. ...

. ~. -
- :-:

WO91/OOS75
, ~. PCT/U~9~/~3~78 ~~

` - 280 - ~ '-
DB 23h
Trap23 DB FALSE
PrevISR23 DD- ?
DWoffset ISR23
DB 24h
Trap24 DB FALSE
PrevISR24 DD ?
. DW offset ISR24
EndTrapList LABEL BYTE
PrevBreak DB ?; previous break~
checking flag
DosCmd DB ? ; previous break-checking
flag
PrevDTA LABEL DWORD ; previous DTA address
PrevDTAoffs DW ?
PrevDTAseg DW ?
PrevExtErrInfo LABEL BYTE; previous extended
error information
PrevExtErrAX DW ?
PrevExtErrBX DW ?
PrevExtErrCX DW ?
PrevExtErrDX DW ?
PrevExtErrSI DW ?
PrevExtErrDI DW ?
PrevExtErrDS DW ?
PrevExtErrES DW ?
DW3 dup(O)

.DATA
public last key
last key dw O
public last scan code
last scan code db O
public ActiveTSR
ActiveTSR DBFALSE
DOSVersion LABEL WORD
D~?; minor version number
MajorVersion DB ?; major version number
rstack DB TSRStackSize + 2 dup(?)
tstack DB TSRStackSize + 2 dup(?)
. .
.STACK 400




- .. . .. , ~ ~ . ~. . . .

WO91!00575 . PCT/US90~03878
~ - 281 _ 2~08~ L

PAGE
_________________ ,
; Transient installation routines . -

.CODE
buffer_size dw O t
public InstallTSR
InstallTSR PROC far; At entry: CS:IP ->
InstallTSR
;SS:SP -> stack
;DS,ES -> PSP
; Save PSP segment
mov ax,seg _DATA
mov ds,ax; DS ->
RESIDENT_DATA
mov ss,TSRDS; SS:SP ->
RESIDENT_STACK
mov sp,TSRSP

mov TSRPSP,es; save PSP
segment
.
mov ax,81H; addr of args
push es
push ax
; call transient_init; c code
init
add sp, 4
mov buffer_size, ax ; returns
the buffer size-in para
; Check the MS-DOS version
... . .
call GetDOSVersion; AH = major
.' version number
; AL = minor version
~` number
; Verify that this TSR is not already installed
;




; Before executing INT 2Fh in MS-DOS versions 2.x,
test ; ; ; whether INT 2FH vector is in use. If so,
abort if PRINT.
; COM is using it.




. ;. ~ . . ... , . ......... .~,

:: . .. . : , :. .. . :

WO91/00575 PCT/US90/03878`
.
~ 282 -

; (Thus, in MS-DOS 2.x, if both this program and
PRINT.COM
; are used, this program should be made resident
before PRINT.
; COM.)
cmp ah,2
ja L101; jump if version 3.0
or later
mov ax,352Fh; AH = INT 21H
function number
; AL = interrupt number
int 21h; ES:BX = INT 2FH
vector
mov ax,es
or ax,bx; jump if current
INT 2FH vector..
jnz L100; ... is nonzero
push ds
mov ax,252Fh; AH = INT 21H
function number
; AL = interrupt number
mov dx,seg TEXT
mov ds,dx
mov dx,offset Multiplex IRET
int 21h; point INT 2FH vector
to IRET
pop ds
- jmp short L103; jump to
install this TSR
L100: mov ax,OFFOOh; look for
PRINT.COM:
int 2Fh; if resident, AH =
print queue length;
; otherwise, AH is
unchanged
cmp ah,OFFh; if PRINT.COM is
not resident
je L101; ... use multiplex
interrupt
mov al,l
call FatalError; abort if
PRINT.COM already installed
L101: mov ah,Multiplex ID; AH =
multiplex interrupt ID value
xor al,al; AL = OO~I




. . , :. :: .. , - :

.. , , - . . , .,: . . . .

W09l/0~57~ rcl/u-90/~3878 ~ ~
~ - 283 _ 2~ J ~ I
int ~Fh; multiplex interrupt ,.
test al,al
jz L103; jump if ok to
install
cmp al,OFFh
jne L102; jump if not already
installed
mov al,2 .
call FatalError; already
ins.alled
L102: mov al,3
call FatalError; can't install
; Install this TSR~s interrupt handlers
L103: push es; preserve PSP segment
mov cx,NISR
mov si,offset StartISRList
L104: mov al,cs:tsi]; AL =
interrupt number
inc si
; DS:SI -> byte past
interrupt number
push ax; preserve AX
mov ah,35h; INT 21H function
35H int 2lh; ES:BX = previous
interrupt vector
mov cs:tsi+l],bx; save offset
and segment
mov cs:[si+3],es; .. of
previous handler
.. . .
pop ax; AL = interrupt
` handler
: push ds; preserve DS
mov dx,cs:tsi+5]
:: . mov bx,seg _ TEXT
- mov ds,bx; DS:DX -> this
TSR's handler
mov ah,25h; INT 21H function
25H
int 2lh; (set interrupt
vector)
pop ds; restore DS
add si,7; DS:SI -> next in
list
loop L104


.... . , . . . ,~ , . - . . .

W091t00s75 PCT/US90/~3878
,... .-` ~,
! `
2~ 284 -
I
; Free the environment
pop es; ES = PSP segment
push es; preserve PSP segment
mov es,es: [2Ch]; ES =
segment of environment
mov ah,49h; INT 21H function
49H
. int 21h; (free memory block)
; Terminate and stay resident
pop ax; AX = PSP segment
mov dx,cs; DX = paragraph
address of start of
; transient portion (end
of resident
; portion)
. sub dx, ax; DX = size of.
resident portion
add dx, buffer size; then
add the ring buffer length
mov dx,0780H
mov ax,3100h; AH = INT 21H
function number
; AL = OOH (return code)
int 2lh
_InstallTSR ENDP
: .
- GetDOSVersion PROC near; Caller: DS = seg
RESIDENT DATA
; ES = PSP
: ; Returns: AH = major
version
; AL = minor version
mov ah,3Oh; INT 2lh function
. 30H:
: ; (get MS-DOS version)
int 21h
cmp al,2
jb L110; jump if version l.x
xchg ah,al; AH = major version
; AL = minor version
mov DOSYersion,ax; save with
major version in
; high-order byte
ret
; L110: mov al,00h
.~ .




., : - ... ..
:. ' '',,' . .''' ,

WOsl/00575 PCT/USgO/0387

- 285 - 2

FatalError ENDP
;TRANSIENT TEXT ENDS
PAGE
;




, , Transient data segment
,

;TRANSIENT DATA SEGNENT word public IDATA
.DATA
MessageTable DW MessageO; MS-DOS version
DWMessagel; PRINTo COM
found in MS-DOS 2.x
installed DW Message2; already
install DW Message3; can't
flag DW Message4; can't find
MessageO DB CR,LF,'TSR requires MS-
DOS 2.0 or later version',CR~LF,'$'
Messagel DB CR,LF,'Can " t install
: TSR: PRINT.COM active',CR,LFI$1
Message2 :.DB CR,LF,'This TSR is
already installed',CR,LF,~$'
TSR',CR,LF,'S' CR,LF,'Can't install this
Message4 DB CR,LF,'Unable to locate
MS-DOS Error Mode flag',CR,LF,'$'
DBTSRStackSize dup(?)
; debug fragments
. . .
; mov ax,OE07h; AH = INT lOH
function number
; int 10h; emit a beep
; push ds
; push ax
; mov ax, OB800H
; mov ds, ax
; inc byte ptr ds:[O]
; mov al,cs; HotFlag
; mov byte ptr ds:[2], al
; mov al, cs:InISR9
; mov byte ptr ds:t4], al



.. . . . . . .

~ - - ,
. .:

W091/00575 PCT/US90/03878


r~ ~ 2 8 6 ~

call FatalError; abort if
version l.x
GETDosVersion ENDP

FatalError PROC near; Caller; AL
message number
; ES = PSP

push ax; save message number
on stack

mov bx,seg DATA
mov ds,bx
; Display the requested message

mov bx,offset MessageTable
xor ah,ah; AX = message
number
shl ax,l; AX = offset into
MessageTable
add bx,ax; DS:BX -> address
of message
mov dx,[bx~; DS:BX -~ message
mov ah,O9h; INT 2lH function
O9H (display string)
int . 21h; display error
message

pop ax; AL = message number
or al,al
- jz L130; jump if message
. number iS zero
; (MS-DOS versions l.x)
; Terminate (MS-DOS 2.x and later)

mov ah,4Ch; INT 21H function
4CH
int 21h; (terminate process
with return code)

; Terminate (MS-DOS l.x)
L130 PROC far

push es; push PSP:OOOOH
xor ax,ax
push ax
ret ; far return (jump to
PSP:OOOOH)
L130 ENDP




..... - .: :, ~
... .. .... . .

... .. ~,: , . .. .

WO 9]/0057s
- - PCI /US90/03878
- 287 - ~ ;,$ ~ .
PP ax
mov byte ptr ds: ~6], al
pp ds

END InstallTSR.




, ,

Representative Drawing
A single figure which represents the drawing illustrating the invention.
Administrative Status

For a clearer understanding of the status of the application/patent presented on this page, the site Disclaimer , as well as the definitions for Patent , Administrative Status , Maintenance Fee  and Payment History  should be consulted.

Administrative Status

Title Date
Forecasted Issue Date Unavailable
(86) PCT Filing Date 1990-07-03
(87) PCT Publication Date 1991-01-04
(85) National Entry 1991-12-18
Dead Application 1996-01-03

Abandonment History

There is no abandonment history.

Payment History

Fee Type Anniversary Year Due Date Amount Paid Paid Date
Application Fee $0.00 1991-12-18
Maintenance Fee - Application - New Act 2 1992-07-03 $100.00 1992-06-19
Registration of a document - section 124 $0.00 1993-06-11
Maintenance Fee - Application - New Act 3 1993-07-05 $100.00 1993-06-18
Maintenance Fee - Application - New Act 4 1994-07-04 $100.00 1994-06-17
Owners on Record

Note: Records showing the ownership history in alphabetical order.

Current Owners on Record
WILLIAMS, PAUL E.
MCCARTHY, KEVIN G.
CERCHIO, GERARD J.
ALVES, ROBERT A.
TDS HEALTHCARE SYSTEMS CORPORATION
Past Owners on Record
None
Past Owners that do not appear in the "Owners on Record" listing will appear in other documentation within the application.
Documents

To view selected files, please enter reCAPTCHA code :



To view images, click a link in the Document Description column. To download the documents, select one or more checkboxes in the first column and then click the "Download Selected in PDF format (Zip Archive)" or the "Download Selected as Single PDF" button.

List of published and non-published patent-specific documents on the CPD .

If you have any difficulty accessing content, you can call the Client Service Centre at 1-866-997-1936 or send them an e-mail at CIPO Client Service Centre.


Document
Description 
Date
(yyyy-mm-dd) 
Number of pages   Size of Image (KB) 
Drawings 1996-02-19 73 1,885
Claims 1991-01-04 12 341
Abstract 1991-01-04 1 62
Cover Page 1991-01-04 1 22
Abstract 1991-01-04 1 58
Representative Drawing 1999-02-11 1 8
Description 1991-01-04 287 12,333
International Preliminary Examination Report 1991-12-18 21 721
Office Letter 1992-03-25 1 20
PCT Correspondence 1992-04-07 1 24
Office Letter 1992-09-16 1 52
Fees 1994-06-17 1 42
Fees 1993-06-18 1 33
Fees 1992-06-19 1 32