BANCStar

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.
=== Syntax ===
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.
== Instructions ==
Known values for opcodes are detailed below.
Opcode 	Operands	Operands	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	Operands	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	Operands	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	Exponentiation operations	Exponentiation operations	Exponentiation operations	Exponentiation operations 	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 	Miscellaneous operations 	Miscellaneous operations 	Miscellaneous operations 	Miscellaneous operations 	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 	Date operations 	Date operations 	Date operations 	Date operations 	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:
 10222,22427,22002,22002
Note the two optional arithterms have been left as 22002. Now we will change one of them to "subtract 64", which encodes as 22641.
 10222,22427,22641,22002
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:
 10222,22427,22641,7773
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	<	≤	=	≥	>	≠
==== Special ====
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:
 Pmts/Year,2304,2
 Term(# Pmts),204,3
 Principal,205,10
 BALANCE,205,10
 Payment,205,8
 Balloon,205,7
 Intrest Rate,206,7
 Total P&I,205,12
 Date,2303,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
== Implementation ==
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.
== References ==
* Short description of BANCStar by someone who had worked with it
* On the c2 wiki
* On en.Wikipedia
* Scanned document containing some old source code
* source code of pretty-printer or disassembler
* BANCNova: an assembler/disassembler toolkit
Category:Languages
Category:Before 1993‏‎