From Esolang
Jump to navigation Jump to search

BANCStar is a language that was used in production in finance in the 1990s, even though it looks like an esoteric language. BANCStar was not originally intended to be written by humans, but only by a compiler, the so-called screen generator. The syntax of BANCStar is very bare because of that. However, programmers found the power of the screen generator lacking, so they started to modify BANCStar programs by hand.

Language capabilities

There is no real documentation, so a lot of the information we know is based on archaeological research and experimentation.


A BANCStar program is a sequence of lines. Each line consist of a list of four comma-separated fields, each of which can contain an integer or be blank. The comma field delimiters are required even when some fields are left blank.

The first number in the list is the opcode, which describes the operation being performed by this line. See the table below for the list of opcodes discovered so far.

The numbers can be positive or negative, and are probably limited to between -32768 and 32767.


Known values for opcodes are detailed below.

Opcode Operands Description
1–2000 p1 r p2 Display prompt at position (x, y), where p1 = 100*y+x. A response field is allocated at position p2, and is r characters wide. A position of zero means to not display that component. The response field is prepopulated with the prompt cell's current value.
2999 Introduce new page (body of code similar to a source file). AKA "stop code".
3000 x op y Conditional: if x op y, execute next line
3001 x op y Block conditional: if not x op y, skip until next end-of-block
3001 End-of-block
3101 x op y Reverse block conditional: if not x op y, skip backwards until next reverse end-of-block
3101 Reverse end-of-block
7000–7999 ? ? ? "Draw commands". Draws some sort of "picture" specified in the first parameter.
Opcode Operands Description
8000 clr p1 p2 Window: sets up some sort of window using positions p1 and p2 (possibly corner points). clr = bg*16+fg, where fg and bg are ANSI (possibly actually PC) colour codes. The high 8 colours are considered to be blinking.
8100 n y x Print text file with name "n.TXT" at (x, y).
8400 "Save address", used to save the return address for subroutine calls (possibly stores the address of the instruction after the next instruction into variables 1908 and 1909?)
8500 n Goto page n. n must be less than or equal to 500.
8500 500+f Goto function key f, in the range [1, 20]
8500 1000+p Goto prompt p, in the range [1, 2000]
8500 4000+t Goto "a particular transaction within a document module", specified by t in the range [1, 24]
8500 4000+asc Goto a miscellaneous thingy; asc is an ASCII code. P: "Product & Sales"; M: "Back to Menu"; E: "Exit BANCStar"; S: "Storage"; T: "Multi-task menu".
8550 ? ? ? "Combination goto"; complicated business
8550 11908 11909 According to the LINK source, "Our particular way of returning from a Branch & Link operation.". Seems to use prompts 1908/1909 in some fashion, beyond that is unknown
8560 p Execute DOS command specified by prompt p. Presumably taken from the prompt's name.
8600 Activate F6 & F7
8601–8607 Deactivate F6 & F7
8608 Deactivate F2, activate all other F-keys
8609 Deactivate F2, activate all other F-keys
8610+f Deactivate F-key f (from F0 to F10), activate all other F-keys
8621–8630 Deactivate all F-keys
8650 m Set video mode m (unknown meaning, possibly a VESA number)
8700 "Auto-solve"
9001 "Auto-save"
9100 "Host interface (native)"
9200, 9201 e p q Data model command "run procedure"; prompts p and q (both optional). e seems to denote some sort of subfield: 0: "number"; 1: "label"; 2: "value".
9300, 9301 e p q Data model command "put to data model"; arguments as above
9400, 9401 e p q Data model command "get from data model"; arguments as above. NB: some live examples of 9401 have the prompt addresses added to 10000, but it's unclear why. Other samples are normal.
Opcode Operands Description
10000–11999 x y z Arithmetic instruction (see below)
16000+m d x y File read/write. m is a value that specifies the exact operation (see below). d = dr+10*pos, where dr is the drive number (0=>A, 1=>B, etc), and pos is the position (-1: current). x and y can be prompt numbers in [1, 2000], or an "indirect prompt" of the form 10000+p, or a "table entry (description)" of the form 20000+p, or a "table entry (item)" of the form 30000+p (where p is a prompt number).
20000+p "Form display command (long prompt name)"
30000+p x y q Table commands. Some prompt p is specified in the command head. q = 10*z+op, where op is as specified below. p, x, y, and z are parameters of the resulting table operator.

Arithmetic instructions

The most complicated type of instruction seems to be arithmetic instructions. Here, the first number is 10000+d, where d is the address of one of the 2000 variable cells ("prompts") as the destination operand.

The other three numbers are of the form (10v+p) or (22000+10n+p) where p is an operation code, v is a variable cell in the range [1, 2000], and n is a constant literal integer.

When a parameter is unneeded, it is usually set to 22002 (i.e. "add 0").

The arithmetic instructions which can be constructed are as in the following table. Here dest is the destination cell from the first number and p1/p2/p3 are the operation codes extracted from the other three numbers. Where an operand's value is always being treated as an address it is marked v1; when it's always a literal number it's written n1; and if it can be either then it is written a1.

If an operand must be left unused (22002), then its operation code is blank.

In some cases, a spare operand can optionally be used to squeeze an extra operation onto the same line: we call these "arithterms". Such operands are marked with "A" in the table below. If you don't want to use the arithterm, set that number to 22002, which is equivalent to the arithterm "add 0". An example of how arithterms work follows this table.

p1 p2 p3 Instruction Description Notes
2 A A Set Set dest equal to a1.
1 A A Negate Set dest equal to negative-a1.
0 A A Length Set dest to the length of a1. Unknown what the length of a literal integer is.
5 Clear Clear dest. Samples seen all have the same address in v1 and dest (not known if this is required). It's unknown how this relates to setting the cell to zero; might depend on data type.
7 A A Logarithm Calculate the logarithm of a1 and store it in dest. Logarithm base is unknown, probably either e or 10.
8 A A Truncate Calculates the positive integer part of a1 and stores it in dest. Unknown how this interacts with other datatypes
Exponentiation operations
6 2 A Power Set dest to a1 raised to the power of a2.
6 3 A Power Believed to be the same as the above. Speculative
6 1 A Inverse power Set dest to a1 raised to the power of negative-a2. Speculative
6 4 A Root Set dest to the a2-th root of a1. Speculative
Miscellaneous operations
6 5 2 Substring Set dest to the substring of v1 that starts at a2 and has length a3. Not known if strings index from 0 or from 1
6 6 A Time Get the system time and store it in dest. v1 always seems to be the same address as dest (not known if this is required). n2 always seems to be 0. Format of time value is unknown
Date operations
9 1 Future date 365 Performs some operation on a1 and a2, storing the result in dest. Date routines are very poorly understood.
9 2 Future date 360 Performs some operation on a1 and a2, storing the result in dest. Date routines are very poorly understood.
9 3 Date difference Calculates the number of days between dates a1 and a2, storing the result in dest. Date routines are very poorly understood.
9 4 ? Mystery date operation Function unknown, described in LIST source as "Future Date 360 and number of days". It is noted there that nobody has been able to use this. Date routines are very poorly understood, this one most of all.

In all cases, we don't know how error conditions (divide by zero, substring out of range, etc) are treated.

In LIST, these are decoded by L_COMMTS.C lines 869–1691.

Arithterm example

An arithterm is used to squeeze an extra operation onto the same line as an existing one. Each arithterm takes up a single BANCStar number and encodes one of the four arithmetic operators (+-×÷) plus a constant or variable cell.

Arithterms are encoded in the way mentioned above (i.e. as 10v+p or 22000+10n+p). The operation code p can be one of the following:

p 1 2 3 4
operator - + × ÷

The arithterm takes effect after the main operation. For example, this BANCStar line calculates the logarithm of the literal number 42, and saves it into variable cell 222:


Note the two optional arithterms have been left as 22002. Now we will change one of them to "subtract 64", which encodes as 22641.


Executing this single line now calculates the logarithm of 42, subtracts 64, and stores the result in cell 222. We can add one more arithterm:


Now this single line calculates log(42), subtracts 64, multiples by the value of variable cell 777, and finally stores the result in cell 222.

Conditional instructions

The various conditional instructions (conditional, block conditional, reverse block conditional) use a different encoding for operands.

The first operand (x) must always be a variable cell ("prompt"). It is given simply as the prompt number, in the range [1, 2000].

The second operand may be one of the following:

Form Meaning
10000 + z Nonnegative value z, in range [0, 9999]
20000 + p Value of prompt p, in range [1, 2000]
30000 + c ASCII character c, in range [0, 255]

The operation argument op in the conditional instructions are encoded differently depending on the remaining operands.

Page conditionals

The op argument may have 10 added to it (i.e. {12, 13, 14, 15, 16}), in which case it signifies a "page conditional". The meaning of this is unclear, but it looks like any conditional statement may be used as a "page conditional".

Unary operations

Two unary operations are available by omitting the last operand (y) or setting it to zero. The following operand table is used in this case:

Op 1 2
Relation null not null

General comparisons

The table below is used if both operands are numbers, or if x is an "alpha" (string?) variable and y is an ASCII character:

Op 1 2 3 4 5 6
Relation < = >


If the first operand is a prompt of type 7 (alpha, believed to be a string), and the second operand is not an ASCII character, the following table is used:

Op 1 2 3 4 5 6
Relation null not null = until null while null

The last two operators seem to provide some sort of looping capability.

File instructions

Add 16000 to get the instruction number (see above). Note there seems to be some duplication of functionality here, I don't know if there is any hidden meaning.

Operation Meaning
160 Continue reading (comma or CR/LF)
161 Open file for fixed-length read
162 Open file for comma or CR/LF read
163 Open file for CR/LF read
164 Open file for fixed-length read, then close
165 Open file for comma or CR/LF read, then close
166 Open file for CR/LF read, then close
167 Continue reading fixed length
168 (n/a)
169 Close file
170 Continue writing (comma or CR/LF),
171 Open existing file for fixed-length write
172 Open existing file for comma or CR/LF write
173 Open existing file for CR/LF write
174 Open existing file for fixed-length write, then close
175 Open existing file for comma or CR/LF write, then close
176 Open existing file for CR/LF write, then close
177 Continue reading fixed length
178 (n/a)
179 Close file
180 Continue writing (comma or CR/LF)
181 Open new file for fixed-length write
182 Open new file for comma or CR/LF write
183 Open new file for CR/LF write
184 Open new file for fixed-length write, then close
185 Open new file for comma or CR/LF write, then close
186 Open new file for CR/LF write, then close
187 Continue reading fixed length
188 (n/a)
189 Close file

Table instructions

See the entry for 30000+p in the main instruction table.

Each table operator has parameters p, x, y, and z as specified earlier. p is always a prompt. x may be a prompt number, or 10000+n, denoting some number n in [0, 9999]. y and z are both simple numbers unless otherwise specified.

Operator Name Description in LIST source Notes
1 table search p <-- x at y (z) [return location]
2 table search p <-- x at y (z) [return description]
3 table search range p <-- x at y (z) [return location]
4 table search range p <-- x at y (z) [return description]
5 table search range pairs p <-- x at y (z) [return location]
6 table search range pairs p <-- x at y (z) [return description] (the LIST source actually says "return location", assumed typo)
7 table transfer p <-- y (z item) [return item]
8 table transfer p <-- y (z item) [return description]
9 table transfer p --> y (z item) [return item] note direction of arrow is reversed
10 table transfer p --> y (z item) [return description] as above

Prompt file

The "prompts" (variable cells) used by a BANCStar program seem to have some metadata stored in a prompt file (*.PFL). It is probable that the prompt number is just the line number in this file. Each line has three comma-separated values: name (a human-readable string), type (an integer of unknown meaning), and length (an integer unknown meaning).

Some sample prompt entries:

Term(# Pmts),204,3
Intrest Rate,206,7
Total P&I,205,12
#1 Pmt Date,2303,12
Trans Date,3,12

Prompt type

The LIST source code specifies the following prompt types:

Type Meaning
0 no data?
1 Telephone number
2 U.S. social security number
3 Date
4 Number
5 Currency (USD) amount
6 Rate (a percentage?)
7 Alpha (an ASCII value?)
8 Constant

Prompts of type 8 are used solely as on-screen display text, e.g.:

Press the ENTER key to continue . . .,8,

However, the sample data with the program include prompts with other type codes, e.g. 2304. The last digit always seems to match up with the above table. It's not known what the rest of the type code means.

Prompt length

The length value seems to be related to the size of the text entry box displayed alongside the prompt. Possibly the size specified in the prompt-display command must be less than or equal to this length?

Special variables

There seems to be some "special variables" (details are not quite known for certain):

  • 1547 = Pause flag
  • 1908 = Half of the return address
  • 1909 = Half of the return address


The implementation is not available yet. We heard someone was trying to rescue the original implementation from an old floppy disk, but he then went missing. We are sure there's nothing fishy about this.