bson@rice-chex.ai.mit.edu (Jan Brittenson) (12/10/90)
Anyone interested in STAR 1.02 can pick it up as @rice-chex.ai.mit.edu: ~/pub/star-1.02.tar.Z. The only known bug is the 64-bit integer constant one. data.w doesn't work properly. data.15 and less will work fine, though. Also notice that you need GCC, the GNU C compiler, to take advantage of 64-bit integer arithmetic. Otherwise all integers will be of size `long', which usually is 32 bits. All real arithmetic is carried out as floating-point, with its limitations. The C data type used is `double' for this. Strings cannot contain NUL characters. Included is the README file. Have fun! -- Jan Brittenson bson@ai.mit.edu PS. The reason for the delay between 1.01 and 1.02 was that had to design ways to circumvent GNU C `long long' bugs, as well as fixing all bugs reported. Thanks to everyone who beta-tested 1.01! STAR 1.02 README There is no documentation yet, but I have included the files I have used for testing STAR this far. They can be found as *.star. There are a few instructions that differ syntactically from ASAP, SASS, and Alonzo's Processor Notes. This is so, because I found no way to lexically cope with differing numbers of arguments, depending on what these arguments are. The instructions are: move.1 c,i,p --> move.1 c.i, p move.1 p,c,i --> move.1 p, c.i swap.1 p,c,i --> swap.1 p, c.i (or c.i, p) Also, STAR implements the special register HST. To clear (or similarly, to test) HST bits, use (for example): clrb 5, hst ; Three identical constructs clrb (1<<xm)|(1<<sr), hst ; XM = 0, SR = 2 clrb [xm,sr], hst ; [] = bit mask Default suffixes are as per Alonzo's Processor Notes with the following exceptions: rln --> rln.w rrn --> rrn.w move id,a --> move.a id,a STAR also can't cope lexically with Alonzo's notation brcc pc+17 since PC is a register, and as such can't be used in expressions. Instead, use "." (the dot) to refer to the address of the current instruction. The above would in STAR be written as: brcc .+17 JUMP and CALL instructions default to relative (.3 or .4) when the address is in RAM, to absolute (.A) when the address is in ROM, and signal an error when the address is in neither. (See the STATIC and FLOATING directives below.) Relative addresses are by default the smallest possible. This is where the optimizer pass comes in. In the first pass all relative offsets are 4 nibbles, but during the remaining passes offsets are cut down to 3 nibbles when feasible. Reducing the size of offsets will reduce the code size, perhaps resulting in further possible reductions if run through further passes. The optimizer pass is repeated until no further reductions are possible. The idea is that in the future nonreferenced code will be ditched. You are recommended to use the memory configuration (STATIC/FLOATING partitioning) set up by the HP-48SX Standard Macro Library (hp48.star), and totally ignore the use of suffixes with JUMP and CALL instructions. Use suffixes only for very special purposes, like generating ROMable code. Let STAR handle the offset sizes. [ Note: STAR is based on an assembler I wrote in 1986 for National Semiconductor's Series 32000. NS32k heavily (read: almost always) uses displacements to address data, esp. in code generated by an HLL compiler. The optimizer pass(es) would in some cases cut down the code size by 30% or more. The technical reason for not optimizing references during pass 1, is that forward references are yet unresolvable, and so the worst case must be assumed - 24 bits on the 32k. Very little code hasn't actually been rewritten for the Saturn version, though.] Here follows a list of recognized operators. Note that &&, ||, and ^^ always evaluate both arguments, unlike in C. They are logically the same, though, i.e.: (1 & 2) --> 0 1 and 2 (1 && 2) --> 1 Both nonzero Like any assembler worth the media it's stored on, STAR ignores operator arities. # ^x x' 0x 16' Hex number ^d d' 10' Decimal (base 10) number ^o o' 8' Octal number ^b b' 2' Binary number r^ r' Real (double) number - default for any number containing a decimal point or `e' character ~ Binary NOT ! Logical NOT (is zero) & Binary AND && Logical AND (both nonzero) | Binary OR || Logical OR (either nonzero) ^ Binary XOR ^^ Logical XOR (either, but not both nonzero) << Left shift >> Right shift [i1,i2,i3...] Integer with bits i1, i2, i3... set and all other bits clear. rm^ (rm^i) Right mask, yields an int with `n' right-adjusted 1s. wd^ (wd^real) Real as 64-bit word * / - Standard arithmetic, no arity + Add numbers or concatenate strings % Modulo (same as `fmod' for reals) - Unary minus ** Power (coerced to real) `str' String r% (str r% n) Right, all characters from pos n to end of string l% (str l% n) Left, all characters up to n sz^ (sz^ str) Length of string in bytes ch^ (ch^i) Integer ASCII value to string tl^ (tl^ str) Trim leading blanks tt^ (tt^ str) Trim trailing blanks ev^ (ev^str) Evaluate expression uc^ (uc^str) Convert to uppercase i^ (i^str) Machine code of string (e.g. i^`add.a a,b') ni^ (ni^str) Length of i^ for string. def name -or- Nonzero if "name" is a defined df name symbol. () Parenthesis, subexpression. > < >= <= == != C-style relational operators Real operators: cos, sin, tan, acos, asin Trig atan, sinh, cosh, tanh log, log10 e and 10 logs ceil, floor Rounding (from 0, towards 0) exp e**x fabs Absolute value fmod Modulo, same as % sqrt Square root Predefined symbols: saturn 48; default memory model version Current version, 1.02 (real) list Nonzero if listings enabled bits Number of bits in an integer xm 0; HST XM bit # sb 1; HST SB bit # sr 2; HST SR bit # mp 3; HST MP bit # pass Current pass, 1, 2, or 3 . Current location pi, e ln2 log(2) sqrt2 sqrt(2) log2e log10(2*e) log10e log10(10*e) ln10 log(10) Operator usage examples: s=`add.a a,a' data.$(ni^s) i^s ; Create code for ADD.A A,A s=1.5 data.w wd^s ; Identical... double s ; ...with this move.p16 wd^s, c ; C=1.5e0 Preexpansion: $name Expands to value of name. \$ escapes expansion. $(expr) Expands to result of expr. Example: lseq=1 ... m=`move' foo=5 dreg=1 lseq=lseq+1 L_$(lseq+1): $m.$foo addr, d$dreg Will expand to: L_3: move.5 addr, d1 Notice that expansion can not be nested, i.e. the following won't work: foo=``1+2'' data.a $($foo) ; WILL NOT WORK AS INTENDED Conditional assembly, nesting up to 16 levels: if expr ... else ... endif Some pseudo instructions: radix i Set default radix Supported radixes are 2, 8, 10, 16, and 0 for real. origin expr .=expr name=value Assign value to symbol define name value name=value odd Align for odd address even Align for even address align n Align for even n-nibble word byte i1, i2, i3... Byte data (same as data.b) data.f i1, i2, i3... Data of size 'f' (.1-.16, .B, .X, .A, and .W) ascii s1, s2, s3... Ascii data. S1...Sn are either: parenthesized expressions, in which case the value is used as a byte, or delimited strings. The delimiter is chosen to be the first character of the string. Escapes \n, \r, \b, \e, \ooo, \xhh work. asciz s1, s2, s3,... Same as ascii, but terminate with NUL (\000) character. double r1, r2, r3... 16-nibble real data error str Display error message end End of file exit End of assembly doblock m, blockterm Read block of input and apply macro m to it (see hp48.star for examples) DO NOT NEST Macros. Macro definitions are of the form: label: macro name arg1, arg2..., argn ... macro body ... endmacro where n is 0 or up, and `argi' is of the form: name -or- name=default where `name' is the symbol to be instantiated to the argument value (passed at the macro call as a string, use ev^ to evaluate an expression). If no value is given for the argument in the macro call, the optional default value is used instead. If no default value is defined, an error is signal and the macro call ignored. Here is a sample macro. It implements the HP-48 `global name' data type. A similar macro can be found in the STAR HP-48SX Standard Macro Library (file hp48.star). When called with no argument, it defaults to a null string name. macro global name=``'' data.a x'2e48 data.b sz^&name ascii &name endmacro global `ABC' ; Global name `ABC' global ; Header template ascii `XXXXXXXXX' ; Filled in later HP-48SX Standard Macro Library definitions: false 0 true 1 warnings Symbol - nonzero value means warnings enabled warning msg Generate warning sym: equ value EQU-style assignment listblock Enable listings nlistblock Disable listings endlist Revert back to previous enable/disable rpl Implicit RPL/data.a body ...rpl body... DO NOT NEST endrpl header rev Kermit preamble HPHP48- followed by revision string str RPL string object global name RPL global name object local name RPL local name object binary value,digits RPL binary integer object short i RPL system binary object address i RPL system binary object character c RPL character object code RPL code object ...ml code... DO NOT NEST endcode Note: Do not nest macros where so indiciated. It won't work as intended - in fact, the results are unpredictable - they may not even contain references to each other. To `unquote' from within an RPL body, prefix the line with underscore (_). Example: Drop = x'3244 RPL Drop _ascii `foo' Drop ENDRPL The above example will be identical to: data.a Drop ascii `foo' data.a Drop Symbols can be defined within both RPL and CODE constructs.