CADO Systems Technical Information

This article documents the CADO Systems Architecture. Initially developed in 1976 for CADO Business Systems running on CAT machines, it was ported to Contel's Tiger ATS platform in 1983 and later to the VERSYSS hardware in the 1990s.
System Overview
The CADO architecture is designed to allow multiple users to run business applications in a multitasking environment. The emphasis is on rapid software development and deployment. The primary software development language is CADOL.
It was possible to write Intel 8080-based instructions directly into CADOL code by means of an "escape to ASM" instruction <code>MACH</code>, and return to CADOL with an "escape to CADOL" instruction <code>MACH RETURN</code>. This was rarely done as assembly machine code programming:
* Was beyond most CADOL programmers (who were trained for rapid application development)
* Suspended multitasking on your 8-user transaction processor.
* And an assembly bug could result in the entire machine crashing. (Whereas a bug in CADOL code would only terminate that user's session.)
Assembly-language routines were not portable beyond the Tiger ATS series because the assembly code was incompatible between 8085A machines (CADO 20/IV) and 8086 machines (TIGER ATS). Also the programming in assembly code was done by <code>HEX</code> instructions. In addition, the code ran in the Z-buffer, as did many of the operating system lib 0 programs, so if you were to write in assembly (which was possible if it was hand coded), you needed to code for a specific address base.
Compiled CADOL code runs in a private, memory protected, compartment on the machine. Each user is allowed 1 program to run at a time. From an applications standpoint there are no threads, or shared resources. However the user program can trigger a "background" process by a <code>RELEASE TERMINAL</code> command which free the user process redirecting to the program 0 of the current library. There wasn't shared variables or buffers between these processes.
CADOL
CADOL is a BASIC-like language which is "compiled" into an intermediate language bytecode (IL). Each CADOL instruction becomes from one or more bytes depending on complexity. For example <code>N5 1</code> becomes two IL bytes, but <code>IF N5 15 RESET</code> becomes 5 IL bytes (push 15, test N5, intra-segment goto, reset).
Internally each IL instruction maps to an Assembly language routine in the OS to manipulate the correct registers, or perform I/O.
Originally in CADOL II, programs were limited to 256 IL bytes each. Later in CADOL III, chained program segments were allowed. Thus, at the end of one 256-byte block of code, the next segment would be loaded. Longer, more complex programs can be built in CADOL III. However in CADOS (CADO for PC) the technology goback to the programs limited to 256 bytes.
Many of the other, later, additions to the CADOL language are syntactic sugar over older IL statements. Thus, a <code>FOR</code> loop is simply broken down to an assignment, conditional check, and a pair of <code>GOTO</code> instructions. <code>IF</code> statements that could perform other instructions (i.e. <code>IF N5 = 1 RETURN</code>) were broken down into a negated <code>IF,GOTO</code> pairing.
A CADOL III compiler can produce CADOL II code, if it's written carefully and does not exceed 256 bytes of IL.
It was not uncommon for CADOL programmers to become familiar with the IL instructions themselves. Many program fixes were distributed as patches to the IL code and the operating system came with a utility for patching programs.
Libraries
CADOL programs are stored in special files called Libraries. CADOL Libraries can contain up to 256 programs in numbered slots.
Calling other programs can be done through the <code>LOAD</code> instruction, which causes an immediate branch to the other program. Or the <code>GOSUB</code> instruction which places a return address onto a call stack, and runs the other program until a <code>RETURN</code> instruction is reached whereupon the caller resumes running.
CADO/Contel/VERSYSS distributed a library of system routines which could be addressed with a <code>GOSUB</code> instruction to a negative program number. So <code>GOSUB -100</code> will call program 100 in the system library instead of program 100 in the current library. The system routines reside on library 0 (system library) so we can program system routines and keep on library 0 for general use.
Calling between libraries (other than a system library) is difficult and required a system call to perform it. So typically, a library will contain an entire functional application (Payroll, Patient History) along with a reserved block of "utility" programs for that library. These "utility" programs are often standardized within a programming team or a project. For example, programs 1-50 might be reserved for "variable initilization", "date conversion routines", or "sort setup".
Since each CADO/Contel/VERSYSS location was run as a separate office, they were rarely standardized between applications.
Terminal
CADOL programs assume a standard output device. This device is based (loosely) on a VT100-type terminal (actually the Micro-bee).
Each cell on an 80x24 terminal contains two types of information: a display character, and an attribute. Display characters are 7-bit ASCII characters. A status line (the 25th line) could also be overwritten with messages if the programmer was familiar with ESC-code sequences. It normally contain status values such as the system clock, Etc.
Attributes marked regions of the screen as protected, unprotected, dim, bold, or blinking. When a <code>CLEAR</code> instruction is processed, all characters in unprotected fields on the screen are removed but the attributes remain behind. If a <code>RESET</code> instruction is processed all characters and attributes are removed.
CADO terminals had two special keys that were treated as exceptions if they were pressed while the system was waiting for input:
* ESCAPE—Will cause Program 0 of the current library to load. This can be trapped for a special behavior (i.e. to force the user to finish the current task) but that generally isn't done.
* CANCEL—Will cause the current program to restart at Segment 0, IL byte 0.
Additionally, there is an <code>ESCAPE</code> and a <code>CANCEL</code> instruction.
Screen layouts can be designed by programming through a series of <code>ATT</code> and <code>DISPLAY</code> instructions, or using an external program called a mask editor. The masks can then be loaded onto a blank screen via a system routine.
Buffers and Memory
User memory is private, protected by the OS. Accessing memory outside of the assigned area causes a memory fault for that user. Memory space is fixed and global, with the exception of being able to temporarily allocate an 8k track buffer (only on later Tiger models). Each user's memory footprint is 8k including variables, buffers and call stack space.
Each user of the system has available:
* 26 6-byte integer registers, labeled N, N1 to N25.
* 9 Alpha registers.
** A, B, and C of 40 bytes each
** A1, A2, B1, B3, C1, C2 of 20 bytes each
*: The alpha registers are arranged in A, A1, A2, B, B1, B2, C, C1, C2 order. If a register overflows, it will be continued into the next register. Thus, there is room for 240 bytes of alpha storage in the A register as long as you didn't use the other 8.
* A special-purpose 20 byte alpha register called <CODE>KEY</CODE> for file I/O.
* A special-purpose 6 bytes numeric register called <CODE>rec</CODE> also for file I/O.
* 5 256-byte Buffers: R, Z, X, Y, W
** The R buffer is where records are read into by <code>READ</code>, <code>READ REC</code>, and <code>READ KEY</code> statements. Also the records can be updated from the R buffer by <code> WRITE BACK </code>.
** The Z buffer was a general-purpose buffer, but was often overwritten by system-level functions. The <code>MERGE</code> command, which was used in combination with a <code>FETCH</code> command to create sort lists of records "on the fly" used the Z buffer. Also the Z buffer is often used as workspace by the system routines.
** The X and Y buffers are general-purpose buffers.
** The W buffer is typically where records are written from by the <code>WRITE</code>, <code>WRITE REC</code> and <code>WRITE KEY</code> instructions.
Calling conventions for subroutines and other programs generally means placing the arguments in low numbered registers (<code>N,N1-N5, A, A1</code>) and making the call. Well behaved programs will document which registers will be used so that the programmer can re-load them after the call if necessary.
Strings
String values in CADOL are stored with the high-bit on for the length of the string, and then the high bit off on the final character to designate the end of string. Thus "Hello, World" becomes (in hex):
<code>C8 E5 EC EC EF AC C0 D7 EF F2 EC '44'</code>
This is done to save space as there's no need for a trailing Null character.
Record Structure
Records are keyed by an up-to-20 character alphabetic key. The record structure isn't externally defined for the file (as with an SQL data base) or in a header (as with a C struct). Alpha and numeric fields are lumped together and accessed by skipping fields you aren't interested in:
READ KEY 1 100 # Read a record
INIT RP # Initializes Buffer R Pointer
INIT RP2 # Initializes Buffer R Page Pointer
SKIP R(A)4 # Skip 4 alphabetic fields
SKIP R(12) # Skip 12 additional bytes
N4 = R(2) # Move two bytes to N4
SKIP R(-6) # Skip back 6 bytes
MOVE (4) R TO W # Move four bytes to W Buffer
Files and disk I/O
Disk storage on CADO systems is arranged in a series of nested containers. The Device represents a single disk drive. A Volume is a contiguous area on a Device where all files are contained. A Device can have multiple Volumes. Within a Volume, file and library names must be unique. Allocation for files and libraries is done when they are created, must be contiguous, and cannot be expanded once created.
This creates a major problem on systems with large files that are tight on space. If a file spans 20 tracks and is full, to allocate an additional track there must be 21 contiguous tracks free on the disk. If there are not, the system must be backed up, files deleted, a new file allocated, records copied, the original file removed, and then the rest of the system restored from tape, floppy diskette (8-inch) or pertec platter.
Files on CADO systems are one of three types:
* Text files. These are rarely used, and usually only for word-processing applications.
* Sequential files.
* Hashed files.
Hashed and sequential files are fixed sized. The entire extent of the file is reserved when the file is created. The extent is calculated based on the number of records, the length of the key for the record, and the average size of the records in the file. Some adjustment to the record size during declaration (usually reducing it) can be done to avoid wasted space at the end of a track.
On 20/IV, 20/VIII and CAT Systems, for programming purposes, files are not named, they are numbered. Normally a fileset is opened which consists of nine files. Once the proper fileset is opened, a program would move on to read and write those files in known positions (e.g. an employee file as file 6, invoice file as file 7, options file as file 9, etc.). By convention, one file was usually reserved for usage as a sort file. Which specific file number depended upon the vertical market application (such as using file 7 for sorting for the utility billing system sold in the Pacific Northwest). File zero was always considered a system file, and could be used for specific configuration records as long as the first byte of the record did not overlay an existing system type (for example: a screen mask=21 in the first byte). It also could be set up to open a file zero that was specific to a given filemap (e.g. one could set up 10 companies all with their own tables and just switch the file zero to open the next company).
On TIGER ATS Systems, up to 20 files can be opened at one time by any user.
Record locking is achieved through the <code>LOCK</code> and <code>UNLOCK</code> statements. To avoid deadlocking and keep lock management simple, only one record can be locked by any user at one time. Attempting to lock a second record results in an error.
Track format
Each file is a collection of 8192 tracks, divided into 32 256-byte sectors. Some of the sectors in each track are designated as key sectors, some as data sectors.
When a record is written, the key is hashed to determine which track it belongs to. That track is read and (if possible) the key is written into a key sector, and the data is written into a data sector. If the key will not fit (the key sectors are full) or the data will not fit (the data sectors are full), then it is written to the next available track. As a consequence, deleted records are simply marked as deleted on the track, but the space is left allocated. The file must be compressed to removed deleted data or re-hashed to another file to removed deleted keys.
Sequential files are identical to hashed files, except that the hashing algorithm is disabled so each record is written to the first track and overflows as necessary.
Structured Query Language
"Just Ask" is the name of the English language structured query language used with the Cado file system. Just Ask has Create, Read, Update, Delete, Sorting, Grouping and conditional selection functionality.
The database definitions are created and stored independently of the actual hashed or sequential data files.
 
< Prev   Next >