Technical Reference Manual
Each operand stacks either a constant value or a pointer to a variable.
There are a number of types of operands. Operands are named after their type, the types are:
These operands take the following word, add it to RTA_FP (see section Language Pointers) and stack the variable at that address.
These operands take the following word, adds it to RTA_FP to get the start of the array. The required element number is dropped off the stack and checked against the maximum size of the array. The address of the element is then calculated and the variable stacked.
This operand gives access to the calculators memories, M0 to M9. The operand is followed by the offset to the memory required.
These operands take the following word, add it to RTA_FP, load the address at that address and stack the variable at that address.
These operands take the following word, adds it to RTA_FP, loads the address at that address to get the start of the array. The element of the array required is dropped off the stack, it is then checked against the maximum size of the array. The address of the element is then calculated and the variable stacked.
These operands correspond to their right side equivalents. In the case of strings the maximum length is stacked first. Then, in all cases, the address of the variable is stacked. The field flag byte is then stacked, in all these cases it is zero to show that it is not a field reference.
These operands are followed by a logical file name, 0,1,2 or 3, which says which logical file to use. First it looks for the field name in the Field Name Symbol Table. If it is found the corresponding field is split from the corresponding File Buffer. If it is a string it is immediately placed on the stack. If it is numeric it is converted from ASCII to the relevant format and placed on the stack.
These operands stacks the logical file, the byte following the operand, and the field flag which in this case is non-zero. All the work is done by the assign.
Stacks the following byte or word. QI_STK_LIT_WORD is identical to QI_INT_CON.
Stacks the constant value following.
Operators generally do things to the variables already on the stack.
In the following section if an operand cannot return an error then no errors are listed.
Any access to a device can result in the following errors. They are no given explicitly as error for that operand/operator:
When writing to a pack the following are always possible:
If the operator calls an operating system then that is listed. If no calls are given then the run time code handles it all itself. In general there is no difference between call with a $ and with an _, the $ calls are called through SWIs whereas the _ calls are made directly. Direct calls are faster, but SWIs can be redirected for the addition of extra features.
If there is more than one parameter they are listed. The values are stacked in order. So para1 is stacked before para2 - when the operator is called the last parameter is the one pointed to by the RTA_SP.
The compares drop whatever is on the stack and return an integer either TRUE(-1) or FALSE(0).
The string compares are case sensitive.
These operators are only available on the LZ model range.
Positions the cursor.
Clears RTB_CRFL, the carriage return flag.
Beeps with a frequency of 460800/(39+para2).
Break the execution of OPL. Note that this is not equivalent to the OPL word BREAK.
Clears the screen. The cursor is homed to the top left.
Set the cursor on or off.
Gets byte after operator, sets or clears most significant bit of DPB_CUST.
Enables or disables the ON/CLEAR key freeze and quit.
Gets byte after operator, sets or clears RTA_ESCF.
Jump RTA_PC to a new location in the same procedure.
Adds word after the operator to RTA_PC. See QCO_BRA_FALSE.
Turns off the machine. Does not terminate language execution.
This is exactly the same state as when the machine is turned off at the top level. The drain on the battery is minimal.
Turns off the machine for a specified amount of seconds. Only available on the LZ model range.
Works like QCO_OFF but turns organiser on again after n% seconds. n% must be in the range 2-1600. Organiser wakes prematurely if an alarm is due.
Set up error handling.
The following word contains the offset to the address to jump to in the event of an error being detected. ONERR OFF is the same operator followed by a zero word. The ONERR address is saved in the procedure header.
If positive it pauses for that many 50 millisecond units, if negative it pauses for that many 50 millisecond units or until the first key press. If it is zero it waits for the next key press.
Uses the 'SLP' processor instruction, so less power is used when PAUSEd compared to normal operation. It does however use more power than being switched off.
Pokes a byte into memory.
Reports an error if para2 is not a byte. If the address is in the protected range $00 to $3F or $282 to $400 then it does nothing.
Pokes a word into memory.
If the address is in the protected range $00 to $3F or $282 to $400 then it does nothing.
Generates an error condition.
If integer on the stack is not a byte it reports error. Otherwise it has exactly the same effect as if that error was generated. Errors generated by RAISE are handled in the normal way by ONERR.
Using this command and ONERR the programmer can completely take-over the handling and reporting of errors.
If the error is out of the range normally reported by the OS the message "*** ERROR ***" is reported.
RAISE 0 is special as it does not report an error.
Set the seed of the random number generator. The sequence numbers generated by RND becomes repeatable.
Special operator used to vector to machine code.
Vectors via the contents of the location RTA_1VCT to machine code. The machine code should return with the carry flag set to report an error.
If the ASCII value 1 is encountered in the OPL source code it is taken to be a SPECIAL call which returns an integer. A 2 is for a floating point return and 3 for a string. It is impossible to get these values into the source code from the editor, it must be generated by another program.
Stops executing the language.
Resets RTA_SP, zeroes the file buffers by calling AL_ZERO and leaves the language.
Disables the reporting of any error arising from the execution of the following operator. Instead the error number is saved in RTB_EROR which can be read by the function ERR.
Clears RTB_EROR and sets the trap flag RTB_TRAP. The following operators can be used with TRAP:
If no error occurs these operators clear RTB_TRAP.
Most of these are file-related operator. The programmer will frequently either need to report errors arising from the operators himself or handle them in a discriminating way. For example:
TRAP OPEN "B:XYZ",A,A$ IF ERR TRAP OPEN "C:XYZ",A,A$ IF ERR CLS :PRINT "FILE XYZ NOT" :PRINT "FOUND" BEEP 100,100 :GET :STOP ENDIF ENDIF
INPUT and EDIT are different. TRAP changes the conditions under which they exit. "EDIT A$" will not exit on the ON/CLEAR key, "TRAP EDIT A$" will exit with RTB_EROR set to ER_RT_BK. When inputting a number without the TRAP option, the routine will not exit until a valid number is input; however with TRAP any input will be accepted and the corresponding error condition placed in RTB_EROR.
See QCO_INPUT_INT, QCO_INPUT_NUM, QCO_INPUT_STR, QCO_EDIT.
Adds the current record buffer to the current file as a new record.
The contents of the file buffer are saved at the end of the current device. The first byte of the buffer is the length of the buffer.
Closes the current file.
CLOSE has no effect on the file itself, it checks that the file is open, clears the record type in RTT_FIL, and zeroes the two cells.
Copies a file from one device to another. If the target already exists the data is appended.
Copies files from one device to another using wildcards. Only available on the LZ model range.
Creates a file.
Deletes a file.
Checks that the file is not open. Deletes all records, starting with the first, and finally the file name record of the file.
Deletes files using wildcards. Only available on the LZ model range.
Erases the current record of the current file.
Goes to the first record of the current file.
Goes to the last record of the current file.
Goes to the next record.
Steps back one record.
Open a file.
OPEN has exactly the same form as CREATE.
Position at that record.
Renames a file.
Erases the file name record and writes a new one.
Defines an UDG. Only available on the LZ model range.
Updates a record.
It deletes the current record in the current file and then APPENDs the contents of the buffer.
Changes the current file.
Takes the byte following the operator and after checking it makes it the new current logical file. See logical file names.
Set the shift state of the keyboard.
Use KSTAT to change the upper/lower alpha/numeric case:
Edits a string.
If the string to be edited is a field then the maximum length of the string is 252. Otherwise the maximum length allowed is the length of the string as defined in the LOCAL or GLOBAL statement. The string to be edited is copied into RTT_BUF. Once the string is edited it is assigned to the source. If the EDIT is preceded by TRAP then the edit will exit on the ON/CLEAR key with the error condition ER_RT_BK. The string remains unchanged. Before execution of this operator RTB_CRFL is tested and, if set, a carriage return is sent to the screen and the flag cleared.
Input an integer.
If the INPUT is preceded by TRAP then the input will exit on the ON/CLEAR key with the error condition ER_RT_BK. It will also exit if an invalid integer is input, e.g. 99999 or $1. If there is no TRAP then the INPUT will not exit on the ON/CLEAR key and invalid integers generate a '?' on the next line and the INPUT is repeated. Up to 6 characters, including leading spaces, are allowed. Before execution of this operator RTB_CRFL is tested and, if set, a carriage return is sent to the screen and the flag cleared.
Inputs a floating point number.
If the INPUT is preceded by TRAP then the input will exit on the ON/CLEAR key with the error condition ER_RT_BK. It will also exit if an invalid floating point number is input, e.g. 999999999999999 or $1. If there is no TRAP then the INPUT will not exit on the ON/CLEAR key and invalid integers generate a '?' on the next line and the INPUT is repeated. Up to 15 characters, including leading spaces, are allowed. Before execution of this operator RTB_CRFL is tested and, if set, a carriage return is sent to the screen and the flag cleared.
Inputs a string.
QCO_INPUT_STR is exactly equivalent to QCO_EDIT with an initial null string.
Prints an integer to the screen.
Before execution of this operator RTB_CRFL is tested and, if set, a carriage return is sent to the screen and the flag cleared.
Prints a floating point number to the screen.
Before execution of this operator RTB_CRFL is tested and, if set, a carriage return is sent to the screen and the flag cleared. The format in which a number is displayed is integer, decimal or scientific in that order of precedence.
Print a string to the screen.
Before execution of this operator RTB_CRFL is tested and, if set, a carriage return is sent to the screen and the flag cleared.
Prints a space to the screen.
This operator is generated by use of the ',' separator in a PRINT statement. Before execution of this operator RTB_CRFL is tested and, if set, a carriage return is sent to the screen and the flag cleared.
Print a carriage return to the screen.
If a PRINT, INPUT or EDIT statement is not followed by a ';' or ',' then this operator is automatically inserted. It is not acted on immediately; it sets the flag RTB_CRFL. Before execution of this operator RTB_CRFL is tested and, if set, a carriage return is sent to the screen and the flag cleared. Note that if a carriage return results in scrolling the screen there is an automatic delay; the length of this delay is defined by DPW_DELY which is in 50 millisecond units, the default being 10.
Sends an integer to the RS232.
Exactly as PRINT_INT, except the CR flag is not tested.
Send a floating point number to the RS232.
Exactly as PRINT_NUM, except the CR flag is not tested.
Send a string to the RS232.
Exactly as PRINT_STR, except the CR flag is not tested.
Send a space character to the RS232.
Exactly as PRINT_SP, except the CR flag is not tested.
Send a carriage return to the RS232.
As PRINT_CR except it is acted on immediately.
Return from a procedure.
This operator follows the operator which stacks the return value. All procedures return a value. If no explicit value is returned then it will return integer zero for integer procedures, floating point zero for floating point procedures or a null string for string procedures.
For an integer procedure this is the default return.
Stacks default return value, then exactly the same as QCO_RETURN.
For an floating point procedure this is the default return.
Stacks default return value, then exactly the same as QCO_RETURN.
For a string procedure this is the default return.
Stacks default return value, on the stack, then exactly the same as QCO_RETURN.
Call a procedure.
First checks to see if a language extension of that name has been booted into memory. If not it searches the 4 devices for an OPL procedure of the right name. It starts with the default device. So if the procedure called was on C: then it searches in the order C:, D:, A: and B:. If a language extension has been found (for example LINPUT) it calls the relevant vector and the device is then responsible for checking the parameters and handling the stack. See language extensions. If it is an OPL procedure the header information is read in and the memory required checked. The external references are then checked and the fixups on the strings and arrays performed. The Q code is then read in, and RTA_PC and RTA_SP are set to their new values.
Branches if the integer on the stack is false.
Adds the integer following the operator to RTA_PC if the value on the stack is zero.
Assign an integer to a variable.
At the start of the operand the stack looks like:
High memory Address of integer variable 0 (field flag) Low memory Integer or: High memory Field name Logical file name (0,1,2 or 4) 1 (field flag) Low memory Integer
If the assign is to a field, it checks that the file is open, checks the field name and saves the value. If not a field it simply saves the integer to the address.
Assigns a floating point number.
Exactly the same as QCO_ASS_INT except it handles floating point numbers.
Assigns a string.
Exactly the same as QCO_ASS_INT except it handles strings.
Drops a byte off stack.
Drops a word off the stack.
Used internally to drop unwanted results off the stack, for example a statement "GET" which translates into RTF_GET,QCO_DROP_WORD.
Drops a floating point number off the stack.
Used internally to OPL when, for example, a floating point procedure returns a value that is not required.
Drops a string off the stack.
Used internally to OPL when, for example, a string procedure returns a string that is not required.
Converts an integer into a floating point number.
Used for automatic type conversion.
Converts a floating point number to integer.
Used for automatic type conversion.
Indicates where the field names end.
Only used internally at the end of an OPEN or CREATE command.
Runs machine code immediately after operator.
Runs the code immediately after the operator as machine code. On return if there are no errors carry must be clear and the B register must be the number of bytes for RTA_PC to jump. If there is an error carry must be set and the B register should contain the number of the error to be reported. This cannot be generated from the editor.
These functions return integer values.
Returns the address of a numeric variable.
In the case of arrays ADDR returns the address of the first element which is immediately after the word giving the size of the array. So "PRINT PEEKW(ADDR(A%))" is exactly the same as "PRINT A%" and "PRINT PEEKW(ADDR(A%())) is the same as "PRINT A%(1)".
Returns the ASCII value of the first character of the string.
Turns UDG clock on or off. Only available on the model LZ range.
Returns the current day of the month - in the range 1 to 31.
Returns number of days since 1/1/1900 for a specified date. Only available on the model LZ range.
Displays a string, a record or the last string displayed, using cursor keys for viewing and waiting for any other key to exit.
The display used is the same as that used by FIND in the top level. Each field, delimited by a TAB character, is on a different line. There is no limit to the number of fields.
Returns day of the week of the given date (1...Monday). Only available on LZ model range.
Returns the current error value.
When the language starts running the value of RTB_EROR is zero. If an error is encountered and handled by a TRAP or ONERR the value remains until the next error or a TRAP command.
Finds a string in the current file.
Finds a string in the current file using wildcards. Only available on LZ model range.
Returns the amount of free memory.
Calculates the amount of free memory by subtracting ALA_FREE from RTA_SP and then subtracting $100.
Get a single character.
If there is a key in the buffer it gets that key first. If no key is received the Organiser will turn itself off after the timeout.
Returns the current hour of the day - in the range 0 to 23.
Does an ABS on an integer.
Converts a negative integer to a positive integer. If ABS is used in place of IABS the result would be the same but the function would require two unnecessary type conversions. IABS is significantly faster than ABS.
Converts a floating point number to an integer.
Identical to QCO_NUM_TO_INT.
Returns any key in the input buffer. Zero if no key is waiting.
Returns the length of the string.
Locates one string in another, returns zero if not found.
Gives a menu of options.
The normal input is a string with each menu item delimited by a comma. An item is selected either by a unique first letter or by positioning on that item and pressing the EXE key. If the menu exits by the ON/CLEAR key it returns zero.
Gives a one-line menu of options. Only available on LZ model range.
Returns the current minute of the hour - in the range 0 to 59.
Returns the current month of the year - in the range 0 to 11.
Peeks a byte at the given address.
If the address is in the ranges $00-$3F and $282-$400 then it returns zero. These ranges are the processor registers and the custom chip's control addresses. The informed user may access these addresses via machine code.
Peeks a word at the given address.
See the comments after RTF_PEEKB.
Returns the size of the current record.
See Records and Fields for more details.
Returns the current second of the minute - in the range 0 to 59.
Returns the week number of a specified date. Only available on LZ model range.
Calls machine code.
Returns the address of a string.
Returns the address of the length byte, the byte after the the maximum length. In the case of an array it returns the address of the length byte of the first element of the array. So "ADDR(A$())-2" is the address of the size the array (a word) and "ADDR(A$())-3" is the address of the maximum string length (a byte).
View a string, or the last string viewed.
If the string is null it re-displays the last string VIEWed (which is held in RTT_BUF).
Returns the current year - in the range 0 to 99.
Returns the number of records in the current file.
Returns TRUE if the position in the file is at the end of file. If the current record is the last record of the file, EOF returns FALSE.
Returns TRUE if the current record buffer is zero. When OPL appends a record with zero length it adds a TAB ($09) character so that it never actually saves a null string.
Returns TRUE is the file exists.
Returns the current record number in the current file.
These functions return a floating point value.
Does an ABS on a floating point number.
Returns the reverse cosine of the input in radians. Only available on LZ model range.
Returns the reverse sinus of the input in radians. Only available on LZ model range.
Returns the arctangent of the input in radians.
Returns the cosine of the input, the input being in radians.
Converts the input from radians to degrees.
Returns the value of e raise to the specified power.
Converts an integer to floating point format.
Exactly the same effect as QCO_INT_TO_NUM.
Rounds a floating point number down to a whole number.
Essential to use INTF rather than INT if the number is out of the integer range.
Returns the natural logarithm of the input.
Returns the base 10 logarithm of the input.
Returns the number pi = 3.14159265359.
Converts the input number to radians. The inverse of DEG.
Returns a pseudo-random number in the range 0(inclusive) to 1(exclusive).
Returns the sine of the input, the input being in radians.
Returns the square root of the input.
Returns the tangent of the input, the input being in radians.
Returns the input string as a number.
Returns the amount of space on the current device.
On execution first the last two bytes are dropped from the stack. If the last byte is $01, the second last byte is the number of array items to be inspected and the array reference is dropped. If it is $00, the second last byte denotes the number of list items. These are dropped as well.
Returns the maximum of the specified array items or list.
Returns the mean of the specified array items or list.
Returns the minimum of the specified array items or list.
Returns the standard deviation of the specified array items or list.
Returns the sum of the specified array items or list.
Returns the variance of the specified array items or list.
Converts an integer (0-7) to the day of the week. 1 returns "Mon" etc. Only available on the LZ model range.
Returns the name of the first/next file on a device.
If the string is non-null it checks that it is of the form "A:" or "A". It splits out the device name and returns the first file name preceded by the device name. If the string is null it returns the next file name, on the device already specified. When there are no more file it returns a null string.
Returns the name of the first/next file (of any type) on a device using wildcards. Only available on the LZ model range.
Converts the integer input to a one character string.
Returns the date-time string in the form: "TUE 04 NOV 1986 10:44:29"
Returns the error string associated with the integer error number.
Returns the floating point number as a string with a fixed number of decimal places.
Returns the floating point number as a string. This is the same format as used by QCO_PRINT_NUM.
The format in which the number is displayed is integer, decimal or scientific in that order of precedence.
Get a character and return it as a one character string.
Converts the integer into a hexadecimal string.
Returns any keys in the input buffer as a string. Returns the null string if no key is waiting.
Returns the first n characters of the string.
Converts the string to lower case.
Returns the middle of a string.
You can get all the characters after the n'th by the statement: MID$(a$,n,255)
Converts an integer (1-12) to the name of the month. 1 returns "Jan" etc. Only available on the LZ model range.
Converts a number to an integer string.
Returns the last n characters of a string.
Repeats the string n times.
Returns the floating point number as a string in scientific form.
Converts the string to upper case.
Calls machine code.
00 QI_INT_SIM_FP 0D QI_LS_INT_SIM_FP 1A QI_INT_FLD 01 QI_NUM_SIM_FP 0E QI_LS_NUM_SIM_FP 1B QI_NUM_FLD 02 QI_STR_SIM_FP 0F QI_LS_STR_SIM_FP 1C QI_STR_FLD 03 QI_INT_ARR_FP 10 QI_LS_INT_ARR_FP 1D QI_LS_INT_FLD 04 QI_NUM_ARR_FP 11 QI_LS_NUM_ARR_FP 1E QI_LS_NUM_FLD 05 QI_STR_ARR_FP 12 QI_LS_STR_ARR_FP 1F QI_LS_STR_FLD 06 QI_NUM_SIM_ABS 13 QI_LS_NUM_SIM_ABS 20 QI_STK_LIT_BYTE 07 QI_INT_SIM_IND 14 QI_LS_INT_SIM_IND 21 QI_STK_LIT_WORD 08 QI_NUM_SIM_IND 15 QI_LS_NUM_SIM_IND 22 QI_INT_CON 09 QI_STR_SIM_IND 16 QI_LS_STR_SIM_IND 23 QI_NUM_CON 0A QI_INT_SIM_IND 17 QI_LS_INT_SIM_IND 24 QI_STR_CON 0B QI_NUM_SIM_IND 18 QI_LS_NUM_SIM_IND 0C QI_STR_SIM_IND 19 QI_LS_STR_SIM_IND
Operators that are only available on the LZ model range are marked by an asterisk.
25 QCO_SPECIAL 47 QCO_GT_STR 69 QCO_USE CC* QCO_LT_PERC 26 QCO_BREAK 48 QCO_GTE_STR 6A QCO_KSTAT CD* QCO_GT_PERC 27 QCO_LT_INT 49 QCO_NE_STR 6B QCO_EDIT CE* QCO_ADD_PERC 28 QCO_LTE_INT 4A QCO_EQ_STR 6C QCO_INPUT_INT D0* QCO_SUB_PERC 29 QCO_GT_INT 4B QCO_ADD_STR 6D QCO_INPUT_NUM D1* QCO_MUL_PERC 2A QCO_GTE_INT 4C QCO_AT 6E QCO_INPUT_STR D2* QCO_DIV_PERC 2B QCO_NE_INT 4D QCO_BEEP 6F QCO_PRINT_INT 2C QCO_EQ_INT 4E QCO_CLS 70 QCO_PRINT_NUM 2D QCO_ADD_INT 4F QCO_CURSOR 71 QCO_PRINT_STR 2E QCO_SUB_INT 50 QCO_ESCAPE 72 QCO_PRINT_SP 2F QCO_MUL_INT 51 QCO_GOTO 73 QCO_PRINT_CR 30 QCO_DIV_INT 52 QCO_OFF 74 QCO_LPRINT_INT 31 QCO_POW_INT 53 QCO_ONERR 75 QCO_LPRINT_NUM 32 QCO_UMIN_INT 54 QCO_PAUSE 76 QCO_LPRINT_STR 33 QCO_NOT_INT 55 QCO_POKEB 77 QCO_LPRINT_SP 34 QCO_AND_INT 56 QCO_POKEW 78 QCO_LPRINT_CR 35 QCO_OR_INT 57 QCO_RAISE 79 QCO_RETURN 36 QCO_LT_NUM 58 QCO_RANDOMIZE 7A QCO_RETURN_NOUGHT 37 QCO_LTE_NUM 59 QCO_STOP 7B QCO_RETURN_ZERO 38 QCO_GT_NUM 5A QCO_TRAP 7C QCO_RETURN_NULL 39 QCO_GTE_NUM 5B QCO_APPEND 7D QCO_PROC 3A QCO_NE_NUM 5C QCO_CLOSE 7E QCO_BRA_FALSE 3B QCO_EQ_NUM 5D QCO_COPY 7F QCO_ASS_INT 3C QCO_ADD_NUM 5E QCO_CREATE 80 QCO_ASS_NUM 3D QCO_SUB_NUM 5F QCO_DELETE 81 QCO_ASS_STR 3E QCO_MUL_NUM 60 QCO_ERASE 82 QCO_DROP_BYTE 3F QCO_DIV_NUM 61 QCO_FIRST 83 QCO_DROP_WORD 40 QCO_POW_NUM 62 QCO_LAST 84 QCO_DROP_NUM 41 QCO_UMIN_NUM 63 QCO_NEXT 85 QCO_DROP_STR 42 QCO_NOT_NUM 64 QCO_BACK 86 QCO_INT_TO_NUM 43 QCO_AND_NUM 65 QCO_OPEN 87 QCO_NUM_TO_INT 44 QCO_OR_NUM 66 QCO_POSITION 88 QCO_END_FIELDS 45 QCO_LT_STR 67 QCO_RENAME 89 QCO_RUN_ASSEM 46 QCO_LTE_STR 68 QCO_UPDATE
Functions that are only available on the LZ model range are marked by an asterisk.
8A RTF_ADDR A0 RTF_VIEW B6 RTF_SPACE D6* RTF_CLOCK 8B RTF_ASC A1 RTF_YEAR B7 RTF_DIR D7* RTF_DOW 8C RTF_DAY A2 RTF_COUNT B8 RTF_CHR D8* RTF_FINDW 8D RTF_DISP A3 RTF_EOF B9 RTF_DATIM D9* RTF_MENUN 8E RTF_ERR A4 RTF_EXIST BA RTF_SERR DA* RTF_WEEK 8F RTF_FIND A5 RTF_POS BB RTF_FIX DB* RTF_ACOS 90 RTF_FREE A6 RTF_ABS BC RTF_GEN DC* RTF_ASIN 91 RTF_GET A7 RTF_ATAN BD RTF_SGET DD* RTF_DAYS 92 RTF_HOUR A8 RTF_COS BE RTF_HEX DE* RTF_MAX 93 RTF_IABS A9 RTF_DEG BF RTF_SKEY DF* RTF_MEAN 94 RTF_INT AA RTF_EXP C0 RTF_LEFT E0* RTF_MIN 95 RTF_KEY AB RTF_FLT C1 RTF_LOWER E1* RTF_STD 96 RTF_LEN AC RTF_INTF C2 RTF_MID E2* RTF_SUM 97 RTF_LOC AD RTF_LN C3 RTF_NUM E3* RTF_VAR 98 RTF_MENU AE RTF_LOG C4 RTF_RIGHT E4* RTF_DAYNAME 99 RTF_MINUTE AF RTF_PI C5 RTF_REPT E5* RTF_DIRW 9A RTF_MONTH B0 RTF_RAD C6 RTF_SCI E6* RTF_MONTHNAME 9B RTF_PEEKB B1 RTF_RND C7 RTF_UPPER 9C RTF_PEEKW B2 RTF_SIN C8 RTF_SUSR 9D RTF_RECSIZE B3 RTF_SQR C9 RTF_SADDR 9E RTF_SECOND B4 RTF_TAN 9F RTF_IUSR B5 RTF_VAL
In these examples all values are given in hexadecimal; word values are given as 4 digits, bytes as 2 digits each one separated by a space. If values are undefined they are written as **.
EX1: LOCAL A$(5) A$="ABC"
The Q code header is:
High memory 0009 size of the variables on stack 000A length of Q code 00 number of parameters type of parameter 0000 size of global area global name global type offset 0000 size of externals external name external type 0003 bytes of string fix-ups FFF7 string fix-up offset (from FP) 05 max length of string Low memory 0000 bytes of array fix-ups array fix-up offset (from FP) size of array
The Q code is:
0F FFF8 QI_LS_STR_SIM_FP 24 QI_STR_CON 03 41 42 43 "ABC" 81 QCO_ASS_STR 7B QCO_RETURN_ZERO
If this program is run on a CM the stack looks like:
Initially Left Side Constant Assign On Return 3EFF '1' '1' '1' '1' '1' 3EFE 'X' 'X' 'X' 'X' 'X' 3EFD 'E' 'E' 'E' 'E' 'E' 3EFC ':' ':' ':' ':' ':' 3EFB 'A' 'A' 'A' 'A' 'A' 3EFA 05 05 05 05 05 3EF9 00 - Top proc 00 00 00 00 3EF8 00 - No. paras 00 00 00 00 3EF6 3EF9 - Return PC 3EF9 3EF9 3EF9 3EF9 3EF4 0000 - ONERR 0000 0000 0000 0000 3EF2 3EDB - BASE SP 3EDB 3EDB 3EDB 3EDB 3EF0 0000 - FP 0000 0000 0000 0000 3EEE 3EEE - Global table 3EEE 3EEE 3EEE 3EEE 3EED 00 00 00 00 00 3EEC 00 00 00 00 00 3EEB 00 00 'C' 'C' 'C' 3EEA 00 00 'B' 'B' 'B' 3EE9 00 00 'A' 'A' 'A' 3EE8 00 00 03 03 03 3EE7 05 05 05 05 05 3EE6 ** ** ** ** ** 3EE5 ** ** ** ** ** 3EE4 QCO_RETURN_ZERO 7B 7B 7B 7B 3EE3 QCO_ASS_STR 81 81 81 81 3EE2 'C' 'C' 'C' 'C' 'C' 3EE1 'B' 'B' 'B' 'B' 'B' 3EE0 'A' 'A' 'A' 'A' 'A' 3EDF 03 03 03 03 03 3EDE QI_STR_CON 24 24 24 24 3EDC FFF8 FFF8 FFF8 FFF8 FFF8 3EDB QI_LS_STR_SIM_FP 0F 0F 0F 0F 3EDA ** 3EE8 3EE8 ** 00 3ED9 ** 05 05 ** 00 3ED8 ** 00 00 ** 00 3ED7 ** ** 'C' ** 00 3ED6 ** ** 'B' ** 00 3ED5 ** ** 'A' ** 00 3ED4 ** ** 03 ** 00 3ED3 ** ** ** ** 00 3ED2 ** ** ** ** 00 FP 3EF0 3EF0 3EF0 3EF0 PC 3EDB 3EDE 3EE3 3EE4 SP 3EDB 3ED8 3ED4 3EDB
When a file is created the operator QCO_CREATE is followed by the logical name to use and the field type and names. The list is terminated by the operator QCO_END_FIELDS.
is translated as the Q code:
24 QI_STR_CON 05 42 3A 41 42 43 "B:ABC" 5E QCO_CREATE 01 Logical name B 02 Type string 04 41 41 41 24 "AAA$" 00 Type integer 02 42 25 "B%" 01 Type floating point 02 43 43 "CC" 88 QCO_END_FIELDS
RECURS:(I%) IF I% RECURS:(I%-1) ENDIF
Looks like this on the stack:
Address Contents Description 3D5A 0010 Parameter 3D59 00 Parameter type 3D58 01 Number of parameters 3D57 41 Device A 3D55 3D6D Return RTA_PC 3D53 0000 ONERR address 3D51 3D29 BASE SP 3D4F 3D82 Previous FP 3D4D 3D4D Globals start address 3D4B 3D5A Indirect address to parameter 3D49 ** 3D48 7B QCO_RETURN_ZERO 3D47 84 QCO_DROP_NUM 3D40 "RECURS" 3D3F 7D QCO_PROC 3D3E 01 3D3D 20 QCO_STK_LIT_BYTE 3D3C 00 3D3B 20 QCO_STK_LIT_BYTE 3D3A 2E QCO_SUB_INT 3D38 0001 3D37 22 QI_INT_CON 3D35 FFFC 3D34 07 QI_INT_SIM_IND 3D32 001B 3D31 7E QCO_BRA_FALSE 3D2F FFFC 3D2E 07 QI_INT_SIM_IND 3D2C 000F Parameter for next call 3D2B 00 parameter type 3D2A 01 parameter count Note that the top 4 byte and the bottom 4 bytes are almost identical, this is shown at the point where the procedure is about to be invoked: RTA_PC 3D3F RTA_SP 3D2A RTA_FP 3D4F
EX4:(PPP$) LOCAL A$(5) GLOBAL B,C%(3),D$(5) J$=PPP$
The Q code header is:
0035 size of the variables on stack 0008 size of Q code length 01 number of parameters 02 type of parameter 0011 size of global area 01 42 global name 01 global type FFE1 offset 02 43 25 global name 03 global type FFD9 offset 02 44 24 global name 02 global type FFD3 offset 0004 bytes of externals 02 4A 24 external name 02 external type 0006 bytes of string fix-ups FFCB string fix-up offset (from FP) 05 max length of string FFD2 string fix-up offset (from FP) 05 max length of string 0004 bytes of array fix-ups FFD9 array fix-up offset (from FP) 0003 size of array
The Q code is:
16 FFE9 QI_LS_STR_SIM_IND 09 FFEB QI_STR_SIM_IND 81 QCO_ASS_STR 7B QCO_RETURN_ZERO
If this program is run on a CM from the procedure:
XXX: GLOBAL J$(3) EX4:("RST")
The stack looks like:
3EFA "A:XXX" 3EF9 00 Number of parameters 3EF8 00 Top procedure 3EF6 3EF9 Return PC 3EF4 0000 ONERR address 3EF2 3ED1 BASE SP 3EF0 0000 FP 3EEE 3EE8 Start of global table 3EEC 3EE4 Address of global 3EEB 02 Global type 3EE8 "J$" Global name 3EE3 03 00 00 00 00 Global J$ 3EE1 ** 3EE0 7B QCO_RETURN_ZERO 3EDF 84 QCO_DROP_NUM 3EDB "EX4" 3EDA 7D QCO_PROC 3ED8 20 01 QI_STK_LIT_BYTE 3ED6 20 02 QI_STK_LIT_BYTE 3ED2 "RST" 3ED1 24 QI_STR_CON 3ECD "RST" Parameter 3ECC 02 Parameter type 3ECB 01 Number of parameters 3ECA 00 Device A: 3EC8 3EDA Return PC 3EC6 0000 ONERR 3EC4 3E83 BASE SP 3EC2 3EF0 FP 3EC0 3EAF Start global table 3EBE 3E95 3EBD 02 3EBA 02 44 24 Global D$ 3EB8 3E9B 3EB7 03 3EB4 02 43 25 Global C%() 3EB2 3EA3 3EB1 01 3EAF 01 42 Global B 3EAD 3ECD Indirection to PPP$ 3EAB 3EE4 Indirection to J$ 3EA3 00 00 00 00 00 00 00 00 GLOBAL B 3E9B 00 03 00 00 00 00 00 00 GLOBAL C%() 3E94 05 00 00 00 00 00 00 GLOBAL D$ 3E8D 05 00 00 00 00 00 00 LOCAL A$ 3E8B ** 3E8A 7B QCO_RETURN_ZERO 3E89 81 QCO_ASS_STR 3E87 FFEB 3E86 09 QI_STR_SIM_IND 3E84 FFE9 3E83 16 QI_LS_STR_SIM_IND
When running EX4 the offset FFE9 is added to RTA_FP (3EC2) to give 3EAB.
TOP: PRINT ABC:(GET) GET
At the point when ABC: has just been called the stack looks like:
3EFA "A:TOP" 3EF9 00 NO. of parameters 3EF8 00 Top procedure 3EF6 3EF9 Return PC 3EF4 0000 ONERR address 3EF2 3EDD BASE SP 3EF0 0000 FP 3EEE 3EEE Global table 3EEC ** 3EEB 7B QCO_RETURN_ZERO 3EEA 83 QCO_DROP_WORD 3EE9 91 RTF_GET 3EE8 73 QCO_PRINT_CR 3EE7 70 QCO_PRINT_NUM 3EE3 "ABC" 3EE2 7D QCO_PROC 3EE0 20 01 QI_STK_LIT_BYTE 3EDE 20 00 QI_STK_LIT_BYTE 3EDD 91 RTF_GET 3EDB 0020 3EDA 00 Integer 3ED9 01 No. parameters 3ED8 41 Device A: 3ED6 3EE2 Return PC 3ED4 0000 ONERR 3ED2 3EC1 BASE SP 3ED0 3EF0 FP 3ECE 3ECE global table 3ECC 3EE4 Address of N% 3ECA ** 3EC9 79 QCO_RETURN 3EC8 86 QCO_INT_TO_NUM 3EC7 2F QCO_MUL_INT 3EC4 07 FFF7 QI_INT_SIM_IND 3EC1 07 FFF7 QI_INT_SIM_IND 3EBF 0020 0400 0300 3EBD 0020 ** 1024 3EBB ** ** 0000 3EB9 ** ** 0000 PC 3EC7 3EC8 3EC9