├── M.md ├── README.md ├── green-book.pdf ├── minimal.md ├── spitbol-manual-v3.7.pdf └── v37.min /README.md: -------------------------------------------------------------------------------- 1 | ## Documentation 2 | 3 | http://github.com/spitbol/spitbol-docs 4 | 5 | This directory contains the documentation files for Macro SPITBOL. 6 | 7 | These documents rarely change. 8 | 9 | ### [The SNOBOL4 Programming Language](docs/green-book.pdf) by R. E. Griswold, J. F. Poage and I. P. Polonski. 10 | 11 | This is the classic "Green Book" (because of the cover of its color). It is a marvel of typography, and first 12 | introduced the use of "beads" to explain SNOBOL pattern matching. 13 | 14 | 15 | 16 | ### [MACRO SPITBOL: The High-Performance SNOBOL4 Language](docs/spitbol-manual-v3.7.pdf) by Mark Emmer and Edward Quillen. 17 | 18 | The SPITBOL project notes with sadness the death of Ed Quillen in June, 2012. 19 | To quote from Mark Emmer's Acknowledgments in the SPITBOL Manual: 20 | 21 | > Ed Quillen, local novelist, political columnist, and SNOBOL enthusiast, co- 22 | authored this manual. He combined various terse SPITBOL documents from other 23 | systems with Catspaw's SNOBOL4+ manual, while providing more complete 24 | explanations of some concepts. Any observed clarity is this manual is due to 25 | Ed, while the more opaque portions can be blamed on me. 26 | 27 | You can learn more about Ed at [Ed's web site](http://www.edquillen.com/) and 28 | [ Denver Post columnist Ed Quillen dies at age 61 in his Salida 29 | home](http://www.denverpost.com/obituaries/ci_20781716/denver-post-columnist- 30 | ed-quillen-dies-at-age). 31 | 32 | ### v37.min 33 | 34 | `v37.min` is the source file for SPITBOL v3.7. It is the state of SPITBOL as of 2009 when 35 | Dave Shields took over the maintainer role. The actual code in the current system is 36 | very close to v3.7. The main difference is that the change history has been deleted, and 37 | the MINIMAL specification formerly in this document can now be found in the file `minimal.md` 38 | 39 | The supplied version of v37.min is just the source for SPITBOL converted from all upper case 40 | to all lower case. 41 | 42 | 43 | ### minimal.md 44 | 45 | `minimal.md` contains the specification of the MINIMAL language, based on the text in `v37.min`. 46 | 47 | ## Licensing 48 | 49 | SPITBOL is licensed using the GPLv2 (or later) license. 50 | 51 | [COPYING](COPYING) contains a copy of the GPLv2 license. 52 | 53 | [COPYING-SAVE-FILE](COPYING-SAVE-FILES) describes licensing issues for a 54 | SPITBOL "save file." 55 | 56 | [COPYING-LOAD-MODULES](COPYING-LOAD-MODULES) describes licensing issues for a 57 | SPITBOL "load module." 58 | 59 | -------------------------------------------------------------------------------- /green-book.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spitbol/spitbol-docs/2d4d67144b285c8a7bf1aeb1f8fdfbb2e8afc1b1/green-book.pdf -------------------------------------------------------------------------------- /minimal.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | The implementation of MACRO SPITBOL is written in three languages: 4 | MINIMAL, C, and assembler. 5 | 6 | The SPITBOL compiler and runtime is written in MINIMAL, a 7 | machine-independent portable assembly language. 8 | 9 | The runtime is augmented by procedures written in C that 10 | collectively comprise OSINT (Operating System INTerface). These 11 | procedures provides such functions as input and output, system 12 | initialization and termination, management of UNIX pipes, the loading 13 | of external functions, and so forth. 14 | 15 | The implementation also includes assembly code. This size of this 16 | code varies according to the target machine. About 1500 lines are 17 | needed for the x86 architecture running UNIX. This code provides such 18 | functions as macros that define the translation of MINIMAL 19 | instructions that take more than a few machine-level instructions, 20 | support for calling C procedures from MINIMAL, for calling MINIMAL 21 | procedures from C, for creating save files and load modules, and for 22 | resuming execution from save files or loand load modules. 23 | 24 | To give some idea of the flavor of the code, consider the following simple 25 | SPITBOL program that copies standard input to standard output. 26 | 27 | ``` 28 | loop output = input :s(loop) 29 | end 30 | ``` 31 | 32 | By default, the variable _input_ is input-associated to standard input, so each attempt to 33 | get its value results in reading in a line from standard input and returning the line as a string. 34 | The read fails if there are no more lines, and succeeds otherwise. 35 | 36 | 37 | Similarly, the variable _output_ is output-associated with standard output, so each assignment 38 | to _output_ causes the assigned value to be written to the standard output file. 39 | 40 | The osint procedure for writing a line is SYSOU. It is called from within SPITBOL as part 41 | of assignment, as shown in the follwing excerpt from the MINIMAL source: 42 | 43 | ``` 44 | * here for output association 45 | 46 | asg10 bze kvoup,asg07 ignore output assoc if output off 47 | asg1b mov xr,xl copy trblk pointer 48 | mov trnxt(XR),xr point to next trblk 49 | beq (XR),=b_trt,asg1b loop back if another trblk 50 | mov xl,xr else point back to last trblk 51 | .if .cnbf 52 | mov trval(XR),-(XS) stack value to output 53 | .else 54 | mov trval(XR),xr get value to output 55 | beq (XR),=b_bct,asg11 branch if buffer 56 | mov xr,-(XS) stack value to output 57 | .fi 58 | JSR gtstg convert to string 59 | PPM asg12 get datatype name if unconvertible 60 | 61 | * merge with string or buffer to output in xr 62 | 63 | asg11 mov trfpt(XL),wa FCBLK ptr 64 | bze wa,asg13 jump if standard output file 65 | 66 | * here for output to file 67 | 68 | asg1a JSR sysou call system output routine 69 | err 206,output caused file overflow 70 | err 207,output caused non-recoverable error 71 | exi else all done, return to caller 72 | ``` 73 | 74 | From the OSINT C code (the C procedure name starts with 'z' since there is some 75 | needed intermediate code (shown below) to go from MINIMAL to C at runtime): 76 | 77 | 78 | ``` 79 | zysou() 80 | { 81 | REGISTER struct FCBLK *fcb = WA(struct FCBLK *); 82 | REGISTER union block *blk = XR(union block *); 83 | int result; 84 | 85 | if (blk->scb.typ == type_scl) { 86 | /* called with string, get length from SCBLK */ 87 | SET_WA(blk->scb.len); 88 | } else { 89 | /* called with buffer, get length from BCBLK, and treat BSBLK 90 | * like an SCBLK 91 | */ 92 | SET_WA(blk->bcb.len); 93 | SET_XR(blk->bcb.bcbuf); 94 | } 95 | 96 | if (fcb == (struct FCBLK *) 0 || fcb == (struct FCBLK *) 1) { 97 | if (!fcb) 98 | result = zyspi(); 99 | else 100 | result = zyspr(); 101 | if (result == EXI_0) 102 | return EXI_0; 103 | else 104 | return EXI_2; 105 | } 106 | 107 | /* ensure iob is open, fail if unsuccessful */ 108 | if (!(MK_MP(fcb->iob, struct ioblk *)->flg1 & IO_OPN)) { 109 | return EXI_1; 110 | } 111 | 112 | /* write the data, fail if unsuccessful */ 113 | if (oswrite 114 | (fcb->mode, fcb->rsz, WA(word), MK_MP(fcb->iob, struct ioblk *), 115 | XR(struct scblk *)) != 0) 116 | return EXI_2; 117 | 118 | /* normal return */ 119 | return EXI_0; 120 | } 121 | ``` 122 | 123 | Here is a fragment of the assembly code that is used to 124 | call a C procedure from MINIMAL. The code is for 32-bit X86 125 | and is written using NASM (Netwide Assembler) syntax. 126 | 127 | ``` 128 | %macro mtoc 1 129 | extern %1 130 | ; save minimal registers to make their values available to called procedure 131 | mov dword [reg_wa],ecx 132 | mov dword [reg_wb],ebx 133 | mov dword [reg_wc],edx ; (also reg_ia) 134 | mov dword [reg_xr],edi 135 | mov dword [reg_xl],esi 136 | mov dword [reg_cp],ebp ; Needed in image saved by SYSXI 137 | call %1 ; call c interface function 138 | ; restore minimal registers since called procedure may have changed them 139 | mov ecx, dword [reg_wa] ; restore registers 140 | mov ebx, dword [reg_wb] 141 | mov edx, dword [reg_wc] ; (also reg_ia) 142 | mov edi, dword [reg_xr] 143 | mov esi, dword [reg_xl] 144 | mov ebp, dword [reg_cp] 145 | ; restore direction flag in (the unlikely) case that it was changed 146 | cld 147 | ; note that the called procedure must return exi action in eax 148 | ret 149 | %endmacro 150 | 151 | ... 152 | 153 | global sysou ; output record 154 | sysou: 155 | mtoc zysou 156 | ``` 157 | 158 | The remainder of this document consists of text that was formerly 159 | part of the source code for the MACRO SPITBOL compiler. It was converted 160 | from plain text to HTML by Dave Shields. 161 | 162 | ## MINIMAL -- Machine Independent Macro Assembly Language 163 | 164 | 165 | 166 | The following sections describe the implementation language originally 167 | developed for SPITBOL but now more widely used. 168 | MINIMAL (Machine Independent Macro Assembly Language) is an assembly 169 | language for an idealized machine. The following describes the basic 170 | characteristics of this machine. 171 | 172 | ### Configuration Parameters 173 | 174 | 175 | 176 | There are several parameters which may vary with the target machine. 177 | the macro-program is independent of the actual definitions of these 178 | parameters. 179 | 180 | 181 | 182 | The definitions of these parameters are supplied by the translation 183 | program to match the target machine. 184 | 185 | * CFP$A 186 | 187 | Number of distinct characters in internal alphabet in the range 64 le CFP$A le MAXLEN. 188 | 189 | * CFP$B 190 | 191 | Number of bytes in a word where a byte is the amount of storage addressed by the least 192 | significant address bit. 193 | 194 | * CFP$C 195 | 196 | Number of characters which can be stored in a single word. 197 | 198 | * CFP$F 199 | 200 | Byte offset from start of a string block to the first character. depends both on target machine 201 | and string data structure. see PLC psc 202 | 203 | * CFP$I 204 | 205 | Number of words in a signed integer constant 206 | 207 | * CFP$L 208 | 209 | The largest unsigned integer of form 2n - 1 which can be stored in a single word. 210 | _n_ will often be CFP$N but need not be. 211 | 212 | * CFP$M 213 | 214 | The largest positive signed integer of form 2n - 1 which can be stored in a single word. 215 | _n_ will often be CFP$N -1 but need not be. 216 | 217 | * CFP$N 218 | 219 | Number of bits which can be stored in a one word bit string. 220 | 221 | * CFP$R 222 | 223 | Number of words in a real constant 224 | 225 | * CFP$S 226 | 227 | 228 | Number of significant digits to be output in conversion of a real quantity. 229 | .if .CNCR .else 230 | the integer consisting of this number of 9s must not be too large to fit in the integer accum. .fi 231 | 232 | ``` 233 | .if .cucf 234 | CFP$U realistic upper bound on alphabet. 235 | 236 | 237 | .fi 238 | CFP$X number of digits in real exponent 239 | ``` 240 | 241 | 242 | ### Memory 243 | 244 | 245 | 246 | Memory is organized into words which each contain CFP$B bytes.For word machines CFP$B, which is 247 | a configuration parameter, may be one in which case words and bytes are identical. 248 | To each word corresponds an address which is a non-negative quantity which is a multiple of CFP$B 249 | 250 | . Data is organized into words as follows. 251 | 252 | 253 | 254 | * A signed integer value occupies CFP$I consecutive words (CFP$I is a configuration parameter). 255 | The range may include more negative numbers than positive (e.g. the twos complement representation). 256 | 257 | * A signed real value occupies CFP$R consecutive words. (CFP$R is a configuration parameter). 258 | 259 | CFP$C characters may be stored in a single word (CFP$C is a configuration parameter). 260 | 261 | * A bit string containing CFP$N bits can be stored in a single word (CFP$N is a configuration parameter). 262 | 263 | 264 | * A word can contain a unsigned integer value in the range (*0* le n le CFP$L. 265 | These integer values may represent addresses of other words and some of the instructions use 266 | this fact to provide indexing and indirection facilities. 267 | 268 | * Program instructions occupy 269 | words in an undefined manner. Depending on the actual implementation, instructions may occupy several 270 | words, or part of a word, or even be split over word boundaries. 271 | 272 | The following regions of memory are available to the program. each 273 | region consists of a series of words with consecutive addresses. 274 | 275 | 276 | 1 constant section --- assembled constants 277 | 278 | 2 working storage section --- assembled work areas 279 | 280 | 3 program section --- assembled instructions 281 | 282 | 4 stack area --- allocated stack area 283 | 284 | 5 data area --- allocated data area 285 | 286 | 287 | ### Registers 288 | 289 | 290 | There are three index registers called XR,XL, XS. 291 | In addition XL may sometimes be referred to by the alias of XT - 292 | see section 4. Any of the above registers may hold a positive unsigned 293 | integer in the range (*0* le n le CFP$L). When the 294 | index register is used for indexing purposes, this must be an appropriate address. 295 | XS is special in that it is 296 | used to point to the top item of a stack in memory. The stack may 297 | build up or down in memory.since it is required that 298 | XS points to the stack top but access to items below 299 | the top is permitted, registers XS and XT may be used 300 | with suitable offsets to index stacked items. only XS 301 | and XT may be used for this purpose since the direction of the offset 302 | is target machine dependent. XT is a synonym for XL 303 | which therefore cannot be used in code sequences referencing XT. 304 | 305 | 306 | 307 | The stack is used for subroutine linkage and temporary data storage for which 308 | the stack arrangement is suitable. XR 309 | ,XL can also contain a character pointer in 310 | conjunction with the character instructions (see description of plc). 311 | 312 | 313 | 314 | 315 | There are three work registers called *WA*,*WB*, *WC*, each of which can contain any data item which can be 316 | stored in a single memory word. In fact, the work registers are just like memory locations 317 | except that they have no addresses and are referenced in a special way by the instructions. 318 | 319 | 320 | Note that registers WA,WB have special uses in connection with the CVD,CVM, MVC MVW MWB, CMC, and TRC instructions. 321 | 322 | 323 | 324 | Register WC may overlap the integer accumulator 325 | (IA) in some implementations. thus any operation 326 | changing the value in WC leaves (IA 327 | ) undefined and vice versa except as noted in the following 328 | restriction on simple dump/restore operations. 329 | 330 | 331 | ``` 332 | restriction 333 | ----------- 334 | 335 | if IA and WC overlap then 336 | sti iasav 337 | ldi iasav 338 | does not change WC , and 339 | mov WC ,WC sav 340 | mov WC sav,WC 341 | does not change IA . 342 | ``` 343 | 344 | 345 | 346 | There is an integer accumulator (IA) which is 347 | capable of holding a signed integer value (CFP$I 348 | words long). register WC may overlap the integer 349 | accumulator (IA) in some implementations. thus any 350 | operation changing the value in WC leaves 351 | (IA) undefined and vice versa except as noted in the 352 | above restriction on simple dump/restore operations. 353 | 354 | There is a single real accumulator (RA ) which can 355 | hold any real value and is completely separate from any of the other 356 | registers or program accessible locations. 357 | 358 | The code pointer register (CP ) is a special index 359 | register for use in implementations of interpretors. it is used to 360 | contain a pseudo-code pointer and can only be affected by 361 | ICP , LCP , SCP and 362 | LCW instructions. 363 | 364 | ### The Stack 365 | 366 | The following notes are to guide both implementors of systems written 367 | in MINIMAL and MINIMAL programmers in dealing with stack manipulation. 368 | implementation of a downwards building stack is easiest and in general 369 | is to be preferred, in which case it is merely necessary to consider 370 | XT as an alternative name for XL . 371 | 372 | The MINIMAL virtual machine includes a stack and has operand formats 373 | _-(XS)_ and _(XS)+_ for pushing and 374 | popping items with an implication that the stack builds down in memory 375 | (a d-stack). however on some target machines it is better for the 376 | stack to build up (a u-stack). 377 | 378 | A stack addressed only by push and pop 379 | operations can build in either direction with no complication but such 380 | a pure scheme of stack access proves restrictive. Hence it is 381 | permitted to access buried items using an integer offset past the 382 | index register pointing to the stack top. on target machines this 383 | offset will be positive/negative for d-stacks/u-stacks and this must 384 | be allowed for in the translation. 385 | 386 | A further restriction is that at 387 | no time may an item be placed above the stack top. For some operations 388 | this makes it convenient to advance the stack pointer and then address 389 | items below it using a second index register. The problem of signed 390 | offsets past such a register then arises. to distinguish stack 391 | offsets, which in some implementations may be negative, from non-stack 392 | offsets which are invariably positive, XT, an alias or synonym for 393 | XL is used. 394 | 395 | For a u-stack implementation, the MINIMAL 396 | translator should negate the sign of offsets applied to both 397 | (XS ) and (XT). Programmers should note that since 398 | XT is not a separate register, XL should not be used 399 | in code where XT is referenced. Other modifications needed in u-stack 400 | translations are in the ADD SUB 401 | ICA DCA opcodes applied to 402 | XS , XT. For example 403 | 404 | ``` 405 | MINIMAL d-stack trans. u-stack trans. 406 | 407 | mov WA,-(XS) sbi XS ,1 adi XS ,1 408 | sto WA,(XS) sto WA,(XS) 409 | mov (XT)+,WC lod WC ,(XL) lod WC ,(XL) 410 | adi XL ,1 sbi XL ,1 411 | add XS,=seven adi XS ,7 sbi XS ,7 412 | mov 2(XT),WA lod WA,2(XL) lod WA,-2(XL) 413 | ica XS adi XS ,1 sbi XS ,1 414 | 415 | Note that forms such as 416 | 417 | mov -(XS),WA 418 | add (XS),WA 419 | 420 | are illegal, since they assume information storage above the stack top. 421 | ``` 422 | 423 | ### Internal Character Set 424 | 425 | The internal character set is represented by a set of contiguous codes from 0 to CFP$A-1. 426 | The codes for the digits 0-9 must be contiguous and in sequence. Other than this, there are no 427 | restraints. 428 | 429 | The following symbols are automatically defined to have the value of the corresponding internal character code. 430 | 431 | ``` 432 | ch$la letter a 433 | ch$lb letter b 434 | . . 435 | ch$l$ letter z 436 | 437 | ch$d0 digit 0 438 | . . 439 | ch$d9 digit 9 440 | 441 | ch$am ampersand 442 | ch$as asterisk 443 | ch$at at 444 | ch$bb left bracket 445 | ch$bl blank 446 | ch$br vertical bar 447 | ch$d0 digit 0 448 | . . 449 | ch$d9 digit 9 450 | 451 | ch$am ampersand 452 | ch$as asterisk 453 | ch$at at 454 | ch$bb left bracket 455 | ch$bl blank 456 | ch$br vertical bar 457 | ch$cl colon 458 | ch$cm comma 459 | ch$dl dollar sign 460 | ch$dt dot (period) 461 | ch$dq double quote 462 | ch$eq equal sign 463 | ch$ex exclamation mark 464 | ch$mn minus 465 | ch$nm number sign 466 | ch$nt not 467 | ch$pc percent 468 | ch$pl plus 469 | ch$pp left paren 470 | ch$rb right bracket 471 | ch$rp right paren 472 | ch$qu question mark 473 | ch$sl slash 474 | ch$sm semi-colon 475 | ch$sq single quote 476 | ch$un underline 477 | ``` 478 | 479 | 480 | The following optional symbols are incorporated by defining the conditional assembly symbol named. 481 | 482 | ``` 483 | 26 shifted letters incorporated by defining .casl 484 | 485 | ch$$a shifted a 486 | ch$$b shifted b 487 | . . 488 | ch$$$ shifted z 489 | 490 | ch$ht horizontal tab - define .caht 491 | ch$vt vertical tab - define .cavt 492 | ch$ey up arrow - define .caex 493 | ``` 494 | 495 | ## Conditional Assembly Features 496 | 497 | Some features of the interpreter are applicable to only certain target machines. They may be incorporated 498 | or omitted by use of conditional assembly. The full form of a condition is - 499 | 500 | ``` 501 | .if conditional assembly symbol (cas) 502 | .then 503 | minimal statements1 (ms1) 504 | .else 505 | minimal statements2 (ms2) 506 | .fi 507 | ``` 508 | The following rules apply 509 | 510 | 511 | 1 The directives *.if* *.then* *.else* *.fi* must start in column 1. 512 | 513 | 2 The conditional assembly symbol must start with a dot in column 8 followed by 4 letters or digits e.g. 514 | ``` 515 | .ca$1 516 | ``` 517 | 518 | 3 then is redundant and may be omitted if wished. 519 | 520 | 4 _ms1_, _ms2_ are arbitrary sequences of MINIMAL statements either of which may be null or may 521 | contain further conditions. 522 | 523 | 5 If _ms2_ is omitted, .*else* may also be omitted. 524 | 525 | 6 .*fi* is required. 526 | 527 | 7 Conditions may be nested to a depth determined by the translator (not less than 20, say). 528 | 529 | Selection of the alternatives _ms1_, _ms2_ is by means of the define and undefine directives of form - 530 | 531 | ``` 532 | .*def* _cas_ 533 | .*undef* _cas_ 534 | ``` 535 | 536 | Which obey rules 1. and 2. above and may occur at any point in a MINIMAL program, including within 537 | a condition. Multiply defining a symbol is an error. Undefining a symbol which is not defined is not 538 | an error. 539 | 540 | The effect is that if a symbol is currently defined, then in any condition depending on it, 541 | _ms1_ will be processed and _ms2_ omitted. Conversely if it is undefined, _ms1_ will be 542 | omitted and _ms2_ processed. 543 | 544 | 545 | Nesting of conditions is such that conditions in a section not selected for processing must not be 546 | evaluated. nested conditions must remember their environment whilst being processed. Effectively this 547 | implies use of a scheme based on a stack with if *.fi* matching by the condition processor of 548 | the translator. 549 | 550 | ## Operand Formats 551 | 552 | The following section describes the various possibilities for operands of instructions and assembly operations. 553 | 554 | ``` 555 | 01 int unsigned integer le CFP$L 556 | 02 dlbl symbol defined in definitions sec 557 | 03 wlbl label in working storage section 558 | 04 clbl label in constant section 559 | 05 elbl program section entry label 560 | 06 plbl program section label (non-entry) 561 | 07 x one of the three index registers 562 | 08 w one of the three work registers 563 | 09 (x) location indexed by x 564 | 10 (x)+ like (x) but post increment x 565 | 11 -(x) like (x) but predecrement x 566 | 12 int(x) location int words beyond addr in x 567 | 13 dlbl(x) location dlbl words past addr in x 568 | 14 clbl(x) location (x) bytes beyond clbl 569 | 15 wlbl(x) location (x) bytes beyond wlbl 570 | 16 integer signed integer (dic) 571 | 17 real signed real (drc) 572 | 18 =dlbl location containing dac dlbl 573 | 19 *dlbl location containing dac CFP$B*dlbl 574 | 20 =wlbl location containing dac wlbl 575 | 21 =clbl location containing dac clbl 576 | 22 =elbl location containing dac elbl 577 | 23 pnam procedure label (on prc instruc) 578 | 24 eqop operand for equ instruction 579 | 25 ptyp procedure type (see prc) 580 | 26 text arbitrary text (erb,err,ttl) 581 | 27 dtext delimited text string (dtc) 582 | ``` 583 | 584 | The numbers in the above list are used in subsequent description and in some of the MINIMAL translators. 585 | 586 | 587 | The following special symbols refer to a collection of the listed possibilities 588 | 589 | * _val_ 01,02 590 | 591 | predefined value 592 | 593 | 594 | 595 | _val_ is used to refer to a predefined one word integer value in the range 0 le n le CFP$L 596 | 597 | * _reg_ 07,08 598 | 599 | register 600 | 601 | _reg_ is used to describe an operand which can be any of the registers (XL , XR , XS ,XT , WA , 602 | WB , WC ). Such an operand can hold a one word integer (address). 603 | 604 | * _opc_ 09,10,11 605 | 606 | character 607 | 608 | _opc_ is used to designate a specific character operand for use in the LCH and SCH instructions. 609 | the index register referenced must be either XR or XL (not XS ,XT). see section on character 610 | operations. 611 | 612 | * _ops_ 03,04,09,12,13,14,15 613 | 614 | memory reference 615 | 616 | _ops_ is used to describe an operand which is in memory. the operand may be one or more words long 617 | depending on the data type. In the case of multiword operands, the address given is the first word. 618 | 619 | * _opw_ as for _ops_ + 08,10,11 620 | 621 | full word 622 | 623 | _opw_ is used to refer to an operand whose capacity is that of a full memory word. _opw_ includes all 624 | the possibilities for _ops_ (the referenced word is used) plus the use of one of the three work registers 625 | (WA,WB,WC). in addition, the formats (X)+ and -(X) allow indexed operations in which the index register 626 | is popped by one word after the reference (X)+, or pushed by one word before the reference -(X) these latter two 627 | formats provide a facility for manipulation of stacks. the format does not imply a particular direction 628 | in which stacks must build - it is used for compactness. 629 | 630 | Note that there is a restriction which disallows an instruction to use an index register in one of 631 | these formats in some other manner in the same instruction. e.g. MOV XL ,(XL)+ is illegal. The formats 632 | -(X) and (X)+ may also be used in pre-decrementation, post-incrementation to access the adjacent 633 | character of a string. 634 | 635 | * _opn_ as for _opw_ + 07 636 | 637 | one word integer 638 | 639 | _opn_ is used to represent an operand location which can contain a one word integer (e.g. an address). 640 | This includes all the possibilities for _opw_ plus the use of one of the index registers (XL ,XR, XT, 641 | or XS). The range of integer values is _0_ le n le CFP$L 642 | 643 | * _opv_ as for _opn_ + 18-22 644 | 645 | one word integer value 646 | 647 | _opv_ is used for an operand which can yield a one word integer value (e.g. an address). It includes 648 | all the possibilities for _opn_ (the current value of the location is used) plus the use of literals. 649 | 650 | Note that although the literal formats are described in terms of a reference to a location containing 651 | an address constant, This location may not actually exist in some implementations since only the value 652 | is required. A restriction is placed on literals which may consist only of defined symbols and certain 653 | labels. Consequently small integers to be used as literals must be pre-defined, a discipline aiding 654 | program maintenance and revision. 655 | 656 | 657 | * _addr_ 01,02,03,04,05 658 | 659 | address 660 | 661 | 662 | 663 | _addr_ is used to describe an explicit address value (one word integer value) for use with DAC 664 | 665 | ``` 666 | 667 | ************************************************ 668 | * in the following descriptions the usage -- * 669 | * (XL),(XR ), ... ,(IA) * 670 | * in the descriptive text signifies the * 671 | * contents of the stated register. * 672 | ************************************************ 673 | ``` 674 | 675 | 676 | ## Instruction Mnemonics 677 | 678 | 679 | 680 | The following list includes all instruction and assembly operation mnemonics in alphabetical order. 681 | The mnemonics are preceded by a number identifying the following section where the instruction is 682 | described. A star (asterisk) is appended to the mnemonic if the last operand may optionally be omitted. 683 | See section -15- for details of statement format and comment conventions. 684 | 685 | 686 | 687 | | sec|opcode|operands|description| 688 | | ----- | ---- | ---------------|-------------------------------------------------| 689 | | 2.1|add|opv,opn|add address| 690 | | 4.2|adi|ops|add integer| 691 | | 5.3|adr|ops|add real| 692 | | 7.1|anb|opw,w|and bit string| 693 | | 2.17|aov|opv,opn,plbl|add address, fail if overflow| 694 | | 5.16|atn| |arctangent of real accum| 695 | | 2.16|bct|w,plbl|branch and count| 696 | | 2.5|beq|opn,opv,plbl|branch if address equal| 697 | | 2.18|bev|opn,plbl|branch if address even| 698 | | 2.8|bge|opn,opv,plbl|branch if address greater or equl| 699 | | 2.7|bgt|opn,opv,plbl|branch if address greater| 700 | | 2.12|bhi|opn,opv,plbl|branch if address high| 701 | | 2.10|ble|opn,opv,plbl|branch if address less or equal| 702 | | 2.11|blo|opn,opv,plbl|branch if address low| 703 | | 2.9|blt|opn,opv,plbl|branch if address less than| 704 | | 2.6|bne|opn,opv,plbl|branch if address not equal| 705 | | 2.13|bnz|opn,plbl|branch if address non-zero| 706 | | 2.19|bod|opn,plbl|branch if address odd| 707 | | 1.2|brn|plbl|branch unconditional| 708 | | 1.7|bri|opn|branch indirect| 709 | | 1.3|bsw!|x,val,plbl|branch on switch value| 710 | | 8.2|btw|reg|convert bytes to words| 711 | | 2.14|bze|opn,plbl|branch if address zero| 712 | | 6.6|ceq|opw,opw,plbl|branch if characters equal| 713 | | 10.1|chk| | check stack overflow| 714 | | 5.17|chp| | integer portion of real accum| 715 | | 7.4|cmb|w|complement bit string| 716 | | 6.8|cmc|plbl,plbl|compare character strings| 717 | | 6.7|cne|opw,opw,plbl|branch if characters not equal| 718 | | 6.5|csc|x|complete store characters| 719 | | 5.18|cos| |cosine of real accum| 720 | | 8.8|ctb|w,val|convert character count to bytes| 721 | | 8.7|ctw|w,val|convert character count to words| 722 | | 8.10|cvd| |convert by division| 723 | | 8.9|cvm|plbl|convert by multiplication| 724 | | 11.1|dac|addr|define address constant| 725 | | 11.5|dbc|val|define bit string constant| 726 | | 2.4|dca|opn|decrement address by one word| 727 | | 1.17|dcv|opn|decrement value by one| 728 | | 11.2|dic|integer|define integer constant| 729 | | 11.3|drc|real|define real constant| 730 | | 11.4|dtc|dtext|define text (character) constant| 731 | | 4.5|dvi|ops|divide integer| 732 | | 5.6|dvr|ops|divide real| 733 | | 13.1|ejc| | eject assembly listing| 734 | | 14.2|end| |end of assembly| 735 | | 1.13|enp| | define end of procedure| 736 | | 1.6|ent!|val|define entry point| 737 | | 12.1|equ|eqop|define symbolic value| 738 | | 1.15|erb|int,text|assemble error code and branch| 739 | | 1.14|err|int,text|assemble error code| 740 | | 1.5|esw| |end of switch list for bsw| 741 | | 5.19|etx| |e to the power in the real accum| 742 | | 1.12|exi!|int|exit from procedure| 743 | | 12.2|exp| |define external procedure| 744 | | 6.10|flc|w|fold character to upper case| 745 | | 2.3|ica|opn|increment address by one word| 746 | | 3.4|icp| |increment code pointer| 747 | | 1.16|icv|opn|increment value by one| 748 | | 4.11|ieq|plbl|jump if integer zero| 749 | | 1.4|iff|val,plbl|specify branch for bsw| 750 | | 4.12|ige|plbl|jump if integer non-negative| 751 | | 4.13|igt|plbl|jump if integer positive| 752 | | 4.14|ile|plbl|jump if integer negative or zero| 753 | | 4.15|ilt|plbl|jump if integer negative| 754 | | 4.16|ine|plbl|jump if integer non-zero| 755 | | 4.9|ino|plbl|jump if no integer overflow| 756 | | 12.3|inp|ptyp,int|internal procedure| 757 | | 12.4|inr| |internal routine| 758 | | 4.10|iov|plbl|jump if integer overflow| 759 | | 8.5|itr| | convert integer to real| 760 | | 1.9|jsr|pnam|call procedure| 761 | | 6.3|lch|reg,opc|load character| 762 | | 2.15|lct|w,opv|load counter for loop| 763 | | 3.1|lcp|reg|load code pointer register| 764 | | 3.3|lcw|reg|load next code word| 765 | | 4.1|ldi|ops|load integer| 766 | | 5.1|ldr|ops|load real| 767 | | 1.8|lei|x|load entry point id| 768 | | 5.20|lnf| | natural logorithm of real accum| 769 | | 7.6|lsh|w,val|left shift bit string| 770 | | 7.8|lsx|w,(x)|left shift indexed| 771 | | 9.4|mcb| |move characterswords backwards| 772 | | 8.4|mfi!|opn,plbl|convert (IA) to address value| 773 | | 4.3|mli|ops|multiply integer| 774 | | 5.5|mlr|ops|multiply real| 775 | | 1.19|mnz|opn|move non-zero| 776 | | 1.1|mov|opv,opn|move| 777 | | 8.3|mti|opn|move address value to (IA)| 778 | | 9.1|mvc| |move characters| 779 | | 9.2|mvw| |move words| 780 | | 9.3|mwb| |move words backwards| 781 | | 4.8|ngi| |negate integer| 782 | | 5.9|ngr| |negate real| 783 | | 7.9|nzb|w,plbl|jump if not all zero bits| 784 | | 7.2|orb|opw,w|or bit strings| 785 | | 6.1|plc!|x,opv|prepare to load characters| 786 | | 1.10|PPM!|plbl|provide procedure exit parameter| 787 | | 1.11|prc|ptyp,val|define start of procedure| 788 | | 6.2|psc!|x,opv|prepare to store characters| 789 | | 5.10|req|plbl|jump if real zero| 790 | | 5.11|rge|plbl|jump if real positive or zero| 791 | | 5.12|rgt|plbl|jump if real positive| 792 | | 5.13|rle|plbl|jump if real negative or zero| 793 | | 5.14|rlt|plbl|jump if real negative| 794 | | 4.6|rmi|ops|remainder integer| 795 | | 5.15|rne|plbl|jump if real non-zero| 796 | | 5.8|rno|plbl|jump if no real overflow| 797 | | 5.7|rov|plbl|jump if real overflow| 798 | | 7.5|rsh|w,val|right shift bit string| 799 | | 7.7|rsx|w,(x)|right shift indexed| 800 | | 8.6|rti!|plbl|convert real to integer| 801 | | 1.22|rtn| |define start of routine| 802 | | 4.4|sbi|ops|subtract integer| 803 | | 5.4|sbr|ops|subtract reals| 804 | | 6.4|sch|reg,opc|store character| 805 | | 3.2|scp|reg|store code pointer| 806 | | 14.1|sec| |define start of assembly section| 807 | | 5.21|sin| |sine of real accum| 808 | | 5.22|sqr| |square root of real accum| 809 | | 1.20|ssl|opw|subroutine stack load| 810 | | 1.21|sss|opw|subroutine stack store| 811 | | 4.7|sti|ops|store integer| 812 | | 5.2|str|ops|store real| 813 | | 2.2|sub|opv,opn|subtract address| 814 | | 5.23|tan| |tangent of real accum| 815 | | 6.9|trc| |translate character string| 816 | | 13.2|ttl|text|supply assembly title| 817 | | 8.1|wtb|reg|convert words to bytes| 818 | | 7.3|xob|opw,w|exclusive or bit strings| 819 | | 1.18|zer|opn|zeroise integer location| 820 | | 7.11|zgb|opn|zeroise garbage bits| 821 | | 7.10|zrb|w,plbl|jump if all zero bits| 822 | 823 | ### MINIMAL Instructions 824 | 825 | 826 | The following descriptions assume the definitions - 827 | 828 | ``` 829 | zeroe equ 0 830 | unity equ 1 831 | ``` 832 | 833 | #### 1- Basic Instruction Set 834 | 835 | 1.1 MOV _opn,opv_ move one word value 836 | 837 | MOV causes the value of operand _opv_ to be set as the new contents of operand location _opn_. 838 | In the case where _opn_ is not an index register, any value which can normally occupy a 839 | memory word (including a part of a multiword real or integer value) can be transferred using MOV. 840 | If the target location _opn_ is an index register, then _opv_ must specify an appropriate one 841 | word value or operand containing such an appropriate value. 842 | 843 | 1.2 BRN _plbl_ unconditional branch 844 | 845 | BRN causes control to be passed to the indicated 846 | label in the program section. 847 | 848 | 1.3 BSW _x,val,plbl_ branch on switch value 849 | 850 | 1.4 IFF _val,plbl_ provide branch for switch 851 | 852 | ``` 853 | IFF val,_plbl_ ... 854 | ... 855 | ... 856 | ``` 857 | 858 | 1.5 ESW end of branch switch table 859 | 860 | 861 | BSW IFF,ESW provide a capability for a switched branch similar to a fortran computed goto. 862 | The _val_ on the BSW instruction is the maximum number of branches. The value in x ranges 863 | from zero up to but not including this maximum. each IFF provides a branch. 864 | 865 | _val_ must be less than that given on the bsw and control goes to _plbl_ if the value in x matches. 866 | If the value in x does not correspond to any of the IFF entries, then control passes to the _plbl_ 867 | on the BSW. 868 | 869 | The _plbl_ operand may be omitted if there are no values missing from the list. 870 | 871 | 872 | IFF and ESW may only be used in this contextxt. Execution of BSW may destroy the contents of _x_. 873 | 874 | The IFF entries may be in any order and since a translator may thus need to store and sort them, 875 | the comment field is restricted in length (sec 11). 876 | 877 | 1.6 ENT _val_ define program entry point 878 | 879 | The symbol appearing in the label field is defined to be a program entry point which can 880 | subsequently be used in conjunction with the BRI instruction, which provides the only 881 | means of entering the code. It is illegal to fall into code identified by an entry point. 882 | the entry symbol is assigned an address which need not be a multiple of CFP$B but which must 883 | be in the range 0 le CFP$L and the address must not lie within the address range of the 884 | allocated data area. Furthermore, addresses of successive entry points must be assigned 885 | in some ascending sequence so that the address comparison instructions can be used to test 886 | the order in which two entry points occur. The symbol _val_ gives an identifying value 887 | to the entry point which can be accessed with the LEI instruction. 888 | 889 | Note - subject to the restriction below, _val_ may be omitted if no such identification is 890 | needed i.e. If no LEI references the entry point. For this case, a translation optimisation 891 | is possible in which no memory need be reserved for a null identification which is never to 892 | be referenced, but only provided this is done so as not to interfere with the strictly ascending 893 | sequence of entry point addresses. To simplify this optimisation for all implementors, the 894 | following restriction is observed 895 | 896 |
897 | _val_ may only be omitted if the entry point is separated from a following 898 | entry point by a non-null MINIMAL code sequence. 899 |
900 | 901 | 902 | 903 | Entry point addresses are accessible only by use of literals (=_elbl_, section 7) or 904 | DAC constants (section 8-11.1). 905 | 906 | 1.7 BRI _opn_ branch indirect 907 | 908 | _opn_ contains the address of a program entry point (see ent). control is passed to the 909 | executable code starting at the entry point address. _opn_ is left unchanged. 910 | 911 | 1.8 LEI _x_ load entry point identification 912 | 913 | X contains the address of an entry point for which an identifying value was given on the the ENT line. 914 | LEI replaces the contents of _x_ by this value. 915 | 916 | 1.9 JSR _pnam_ call procedure _pnam_ 917 | 918 | 1.10 PPM _plbl_ provide exit parameter 919 | 920 | ``` 921 | PPM _plbl_ ... 922 | ... 923 | PPM _plbl_ ... 924 | ``` 925 | 926 | JSR causes control to be passed to the named procedure. _pnam_ is the label on a PRC statement 927 | elsewhere in the program section (see prc) or has been defined using an *exp* instruction. 928 | 929 | The PPM exit parameters following the call give names of program locations (_plbl_-s) to 930 | which alternative EXI returns of the called procedure may pass control. 931 | 932 | They may optionally be replaced by error returns (see err). the number of exit parameters 933 | following a JSR must equal the int in the procedure definition. 934 | 935 | The operand of PPM may be omitted if the corresponding EXI return is certain not to be taken. 936 | 937 | 1.11 PRC _ptyp,int_ define start of procedure 938 | 939 | The symbol appearing in the label field is defined to be the name of a procedure for use with 940 | JSR a procedure is a contiguous section of instructions to which control may be passed with 941 | a JSR instruction. 942 | 943 | This is the only way in which the instructions in a procedure may be executed. 944 | 945 | It is not permitted to fall into a 946 | procedure. All procedures should be named in section 0 947 | INP statements. 948 | 949 | _int_ is the number of exit parameters (PPM-s) to be used in JSR calls. 950 | 951 | There are three possibilities for _ptyp_, each consisting of a single letter as follows. 952 | 953 | 954 | - r recursive 955 | 956 | The return point (one or more words) is stored on the stack as though 957 | one or more MOV ...,-(XS ) 958 | 959 | - n non non-recursive 960 | 961 | The return point is to be stored either (1) in a local storage word 962 | associated with the procedure and not directly available to the 963 | program in any other manner or (2) on a subroutine link stack quite 964 | distinct from the MINIMAL stack addressed by XS . 965 | 966 | It is an error to use the stack for n-links, since procedure parameters 967 | or results may be passed via the stack. 968 | 969 | If method (2) is used for links, error exits (erb,err) from a 970 | procedure will necessitate link stack resetting. The 971 | SSL and SSS orders provided for this 972 | may be regarded as no- _ops_ for implementations using method 973 | (1). 974 | 975 | 976 | - either 977 | 978 | 979 | The return point may be stored in either manner according to efficiency requirements of the actual 980 | physical machine used for the implementation. 981 | 982 | Note that programming of _e_ type procedures must be independent of the actual implementation. 983 | 984 | The actual form of the return point is undefined. However, each word stored on the stack for 985 | an r-type call must meet the following requirements. 986 | 987 | 1 It can be handled as an address and placed in an index register. 988 | 989 | 990 | When used as an operand in an address comparison instruction, it must not appear to lie within 991 | the allocated data area. 992 | 993 | 2 It is not required to appear to lie within the program section. 994 | 995 | 1.12 EXI _int_ exit from procedure 996 | 997 | 998 | The PPM and ERR parameters following a JSR are numbered starting from 1. 999 | 1000 | EXI int causes control to be returned to the int-th such param. EXI 1 gives control to the _plbl_ 1001 | of the first PPM after the JSR if int is omitted, control is passed back past the last 1002 | exit parameter (or past the JSR if there are none). 1003 | 1004 | For _r and_ _e_ type procedures, the stack pointer XS must be set to its appropriate entry value 1005 | before executing an EXI instruction. 1006 | 1007 | In this case, EXI removes return points from the stack if any are stored there so that the 1008 | stack pointer is restored to its calling value. 1009 | 1010 | 1.13 ENP define end of procedure body 1011 | 1012 | 1013 | ENP delimits a procedure body and may not actually be executed, hence it must have no label. 1014 | 1015 | 1.14 ERR _int,text_ provide error return 1016 | 1017 | ERR may replace an exit parameter (PPM) in any procedure call. the int argument is a unique 1018 | error code in 0 to 899. 1019 | 1020 | The text supplied as the other operand is arbitrary text in the FORTRAN character set and may 1021 | be used in constructing a file of error messages for documenting purposes or for building a 1022 | direct access or other file of messages to be used by the error handling code. 1023 | 1024 | In the event that an EXI attempts to return control via an exit parameter to an ERR control is 1025 | instead passed to the first instruction in the error section (which follows the program section) 1026 | with the error code in WA. 1027 | 1028 | 1.15 ERB _int,text_ error branch 1029 | 1030 | This instruction resembles ERR except that it may occur at any point where a branch is permitted. 1031 | It effects a transfer of control to the error section with the error code in WA. 1032 | 1033 | 1.16 ICV _opn_ increment value by one 1034 | 1035 | ICV increments the value of the operand by unity. It is equivalent to ADD _opn_,=unity 1036 | 1037 | 1.17 DCV _opn_ decrement value by one 1038 | 1039 | DCV decrements the value of the operand by unity. It is equivalent to SUB _opn=unity_ 1040 | 1041 | 1.18 ZER _opn_ zeroise _opn_ 1042 | 1043 | ZER is equivalent to MOV =zeroe,_opn_ 1044 | 1045 | 1.19 MNZ _opn_ move non-zero to _opn_ 1046 | 1047 | 1048 | Any non-zero collectable value may used, for which the opcodes _bnz_ or _bze_ will branch/fail to branch. 1049 | 1050 | 1.20 SSL _opw_ subroutine stack load 1051 | 1052 | 1.21 SSS _opw_ subroutine stack store 1053 | 1054 | This pair of operations is provided to make possible the use of a local stack to hold subroutine 1055 | (subroutine) return links for n-type procedures. 1056 | 1057 | SSS stores the subroutine stack pointer in _opw_ and SSL loads the subroutine stack pointer from _opw_. 1058 | 1059 | By using SSS in the main program or on entry to a procedure which should regain control on occurrence of an 1060 | ERR or ERB and by use of SSL in the error processing sections the subroutine stack 1061 | pointer can be restored giving a link stack cleaned up ready for resumed execution. 1062 | 1063 | The form of the link stack pointer is undefined in MINIMAL (it is likely to be a private register 1064 | known to the translator) and the only requirement is that it should fit into a single full word. 1065 | 1066 | SSL and SSS are no-ops if no private link stack is not used. 1067 | 1068 | 1.22 RTN define start of routine 1069 | 1070 | 1071 | However it is entered by any type of conditional or unconditional branch (not by JSR). 1072 | 1073 | On termination it passes control by a branch (often BRI through a code word) or even permits control 1074 | to drop through to another routine. No return link exists and the end of a routine is not marked by 1075 | an explicit opcode (compare ENP). 1076 | 1077 | All routines must be named in section 0 INR statements. 1078 | 1079 | #### 2- Operations on One Word Integer Values (addresses) 1080 | 1081 | 1082 | 2.1 ADD _opn,opv_ 1083 | 1084 | Adds _opv_ to the value in _opn_ and stores the result in _opn_. Undefined if the result exceeds CFP$L . 1085 | 1086 | 2.2 SUB _opn,opv_ 1087 | 1088 | 1089 | Subtracts _opv_ from _opn_, and stores the result in _opn_. Undefined if the result is negative. 1090 | 1091 | 2.3 ICA _opn_ 1092 | 1093 | Increment address in _opn_. Equivalent to ADD _opn_,_unity_ 1094 | 1095 | 2.4 DCA _opn_ 1096 | 1097 | Decrement address in _opn_ equivalent to SUB _opn_,_unity_ 1098 | 1099 | 2.5 BEQ _opn,opv,plbl_ 1100 | 1101 | Branch to _plbl_ _opn_ eq _opv_ 1102 | 1103 | 1104 | 2.6 BNE _opn,opv,plbl_ 1105 | 1106 | Branch to _plbl_ _opn_ ne _opv_ 1107 | 1108 | 2.7 BGT _opn,opv,plbl_ 1109 | 1110 | 1111 | Branch to _plbl_ _opn_ gt _opv_ 1112 | 1113 | 2.8 BGE _opn,opv,plbl_ 1114 | 1115 | 1116 | Branch to _plbl_ _opn_ ge _opv_ 1117 | 1118 | 2.9 BLT _opn,opv,plbl_ 1119 | 1120 | Branch to _plbl_ _opn_ lt _opv_ 1121 | 1122 | 2.10 BLE _opn,opv,plbl_ 1123 | 1124 | Branch to _plbl_ _opn_ le _opv_ 1125 | 1126 | 2.11 BLO _opn,opv,plbl_ 1127 | 1128 | Equivalent to BLT or ble 1129 | 1130 | 2.12 BHI _opn,opv,plbl_ 1131 | 1132 | Equivalent to BGT or BGE 1133 | 1134 | 1135 | The above instructions compare two address values as unsigned integer values. The BLO and BHI 1136 | instructions are used in cases where the equal condition either does not occur or can result 1137 | either in a branch or no branch. 1138 | 1139 | This avoids inefficient translations in some implementations. 1140 | 1141 | 2.13 BNZ _opn,plbl_ 1142 | 1143 | Equivalent to BNE _opn_,=zeroe,_plbl_ 1144 | 1145 | 2.14 BZE _opn,plbl_ 1146 | 1147 | Equivalent to BEQ _opn_,=zeroe,_plbl_ 1148 | 1149 | 2.15 LCT _w,opv_ 1150 | 1151 | Load counter for BCT 1152 | 1153 | LCT loads a counter value for use with the BCT instruction. The value in _opv_ is the number of 1154 | loop operations to be executed. 1155 | 1156 | The value in _w_ after this operation is an undefined one word integer quantity. 1157 | 1158 | 2.16 BCT _w,plbl_ 1159 | 1160 | Branch and count 1161 | 1162 | BCT uses the counter value in w to branch the required number of times and then finally to fall 1163 | through to the next instruction. 1164 | 1165 | BCT can only be used following an appropriate LCT instruction. 1166 | 1167 | The value in _w_ after execution of BCT is undefined. 1168 | 1169 | 2.17 AOV _opn,opv,plbl_ 1170 | 1171 | ADD with carry test 1172 | 1173 | Adds _opv_ to the value in _opn_ and stores result in _opn_. 1174 | 1175 | Branches to _plbl_ result exceeds CFP$L with result in _opn_ undefined. cf. ADD 1176 | 1177 | 2.18 BEV _opn,plbl_ 1178 | 1179 | Branch even 1180 | 1181 | 2.19 BOD _opn,plbl_ 1182 | 1183 | Branch odd 1184 | 1185 | These operations are used only .cepp or .crpp is defined. 1186 | 1187 | On some implementations, a more efficient implementation is possible by noting 1188 | that address of blocks must always be a multiple of CFP$B. We call such addresses even. 1189 | 1190 | Thus return address on the stack (.crpp) and entry point addresses (.cepp) can be distinguished 1191 | from block addresses they are forced to be odd (not a multiple of CFP$B ). BEV and BOD branch 1192 | according as operand is even or odd, respectively. 1193 | 1194 | #### 3- Operations on the Code Pointer Register 1195 | 1196 | (CP) 1197 | 1198 | 1199 | The code pointer register provides a psuedo instruction counter for use in an interpretor. 1200 | It may be implemented as a real register or as a memory location, but in either case it is separate 1201 | from any other register. the value in the code pointer register is always a word address 1202 | (i.e. a one word integer which is a multiple of CFP$B ). 1203 | 1204 | 3.1 LCP _reg_ 1205 | 1206 | Load code pointer register 1207 | 1208 | This instruction causes the code pointer register to be set from the value in _reg_ which is unchanged 1209 | 1210 | 3.2 SCP _reg_ 1211 | 1212 | Store code pointer register this instruction loads the current value in the code pointer register into reg. 1213 | (CP ) is unchanged. 1214 | 1215 | 3.3 LCW _reg_ 1216 | 1217 | Load next code word 1218 | 1219 | This instruction causes the word pointed to by CP to be loaded into the indicated reg. The value 1220 | in CP is then incremented by one word. 1221 | 1222 | Execution of LCW may destroy XL . 1223 | 1224 | 3.4 ICP 1225 | 1226 | Increment CP by one word 1227 | 1228 | On machines with more than three index registers, CP can be treated simply as an index register. 1229 | In this case, the following equivalences apply: 1230 | 1231 | ``` 1232 | 1233 | CP _reg_ is like MOV reg,*CP* 1234 | CP _reg_ is like MOV *CP* ,_reg_ 1235 | LCW _reg_ is like MOV (CP )+,_reg_ 1236 | CP is like ICA *CP* 1237 | 1238 | ``` 1239 | 1240 | Since LCW is allowed to destroy XL , the following implementation using a work location CP 1241 | $$$ can also be used. 1242 | 1243 | ``` 1244 | CP _reg_ MOV reg,*CP* $$$ 1245 | 1246 | CP _reg_ MOV *CP* $$$,_reg_ 1247 | 1248 | LCW _reg_ MOV CP $$$,XL 1249 | MOV (XL )+,_reg_ 1250 | MOV XL ,CP $$$ 1251 | 1252 | iCP ICA *CP* $$$ 1253 | ``` 1254 | 1255 | #### 4- Operations on Signed Integer Values 1256 | 1257 | 1258 | 4.1 LDI _ops_ 1259 | 1260 | Load integer accumulator from _ops_ 1261 | 1262 | 4.2 ADI _ops_ 1263 | 1264 | ADD _ops_ to integer accumulator 1265 | 1266 | 4.3 MLI _ops_ 1267 | 1268 | Multiply integer accumulator by _ops_ 1269 | 1270 | 4.4 SBI _ops_ 1271 | 1272 | Subtract _ops_ from int accumulator 1273 | 1274 | 4.5 DVI _ops_ 1275 | 1276 | Divide integer accumulator by _ops_ 1277 | 1278 | 4.6 RMI _ops_ 1279 | 1280 | Set integer accumulator to `mod(intacc,_ops_)` 1281 | 1282 | 4.7 STI _ops_ 1283 | 1284 | Store integer accumulator at _ops_ 1285 | 1286 | 4.8 NGI 1287 | 1288 | Negate the value in the integer accumulator (change its sign) 1289 | 1290 | The equation satisfied by operands and results of DVI and RMI is 1291 | 1292 | ``` 1293 | div = qot * _ops_ + rem where 1294 | div = dividend in integer accumulator 1295 | qot = quotient left in IA by div 1296 | _ops_ = the divisor 1297 | rem = remainder left in IA by rmi 1298 | ``` 1299 | 1300 | The sign of the result of DVI is + (IA) and ( _ops_) have the same sign and is - 1301 | they have opposite signs. 1302 | 1303 | The sign of (IA) is always used as the sign of the result of `rem`. 1304 | 1305 | Assuming in each case that IA contains the number specified in parentheses and that seven and msevn 1306 | hold +7 and -7 resp. the algorithm is illustrated below. 1307 | 1308 | 1309 | ``` 1310 | (IA = 13) 1311 | DVI seven IA = 1 1312 | RMI seven IA = 6 1313 | DVI msevn IA = -1 1314 | RMI msevn IA = 6 1315 | (IA = -13) 1316 | DVI seven IA = -1 1317 | RMI seven IA = -6 1318 | DVI msevn IA = 1 1319 | RMI msevn IA = -6 1320 | ``` 1321 | 1322 | The above instructions operate on a full range of signed integer values. with the exception of LDI and 1323 | STI these instructions may cause integer overflow by attempting to produce an undefined or out of range 1324 | result in which case integer overflow is set, The result in (IA) is undefined and the following 1325 | instruction must be IOV or INO. 1326 | 1327 | Particular care may be needed on target machines having distinct overflow and divide by zero conditions. 1328 | 1329 | 4.9 INO _plbl_ 1330 | 1331 | Jump to _plbl_ if no integer overflow 1332 | 1333 | 4.10 IOV _plbl_ 1334 | 1335 | Jump to _plbl_ if integer overflow 1336 | 1337 | 1338 | These instructions can only occur immediately following an instruction which can cause integer overflow 1339 | (ADI, SBI MLI DVI RMI NGI) and test the result of the preceding instruction. 1340 | 1341 | IOV and INO may not have labels. 1342 | 1343 | 4.11 IEQ _plbl_ 1344 | 1345 | Jump to _plbl_ if (IA) eq 0 1346 | 1347 | 1348 | 4.12 IGE _plbl_ 1349 | 1350 | Jump to _plbl_ if (IA) ge 0 1351 | 1352 | 4.13 IGT _plbl_ 1353 | 1354 | Jump to _plbl_ if (IA) gt 0 1355 | 1356 | 4.14 ILE _plbl_ 1357 | 1358 | Jump to _plbl_ if (IA) le 0 1359 | 1360 | 1361 | 4.15 ILT _plbl_ 1362 | 1363 | Jump to _plbl_ if (IA) lt 0 1364 | 1365 | 4.16 INE _plbl_ 1366 | 1367 | Jump to _plbl_ if (IA) ne 0 1368 | 1369 | 1370 | The above conditional jump instructions do not change the contents of the accumulator. 1371 | 1372 | On a ones complement machine, it is permissible to produce negative zero in IA provided these instructions 1373 | operate correctly with such a value. 1374 | 1375 | #### 5- Operations on Real Values 1376 | 1377 | 5.1 LDR _ops_ 1378 | 1379 | Load real accumulator from _ops_ 1380 | 1381 | 5.2 STR _ops_ 1382 | 1383 | Store real accumulator at _ops_ 1384 | 1385 | 1386 | 5.3 ADR _ops_ 1387 | 1388 | ADD _ops_ to real accumulator 1389 | 1390 | 5.4 SBR _ops_ 1391 | 1392 | Subtract _ops_ from real accumulator 1393 | 1394 | 1395 | 5.5 MLR _ops_ 1396 | 1397 | Multiply real accumulator by _ops_ 1398 | 1399 | 5.6 DVR _ops_ 1400 | 1401 | Divide real accumulator by _ops_ 1402 | 1403 | If the result of any of the above operations causes underflow, the result yielded is 0.0. 1404 | 1405 | The result of any of the above operations is undefined or out of range, real overflow is set, 1406 | he contents of (RA) are undefined and the following instruction must be either ROV or RNO. 1407 | 1408 | Particular care may be needed on target machines having distinct overflow and divide by zero conditions. 1409 | 1410 | 5.7 ROV _plbl_ 1411 | 1412 | Jump to _plbl_ real overflow 1413 | 1414 | 5.8 RNO _plbl_ 1415 | 1416 | Jump to _plbl_ no real overflow 1417 | 1418 | These instructions can only occur immediately following an instruction which can cause real overflow 1419 | (ADR,SBR MLR DVR. 1420 | 1421 | 5.9 NGR 1422 | 1423 | Negate real accumulator (change sign) 1424 | 1425 | 5.10 REQ _plbl_ 1426 | 1427 | Jump to _plbl_ if (RA) eq 0.0 1428 | 1429 | 1430 | 5.11 RGE _plbl_ 1431 | 1432 | Jump to _plbl_ if (RA) ge 0.0 1433 | 1434 | 5.12 RGT _plbl_ 1435 | 1436 | Jump to _plbl_ if (RA) gt 0.0 1437 | 1438 | 1439 | 5.13 RLE _plbl_ 1440 | 1441 | Jump to _plbl_ if (RA) le 0.0 1442 | 1443 | 5.14 RLT _plbl_ 1444 | 1445 | Jump to _plbl_ if (RA ) lt 0.0 1446 | 1447 | 5.15 RNE _plbl_ 1448 | 1449 | Jump to _plbl_ if (RA) ne 0.0 1450 | 1451 | The above conditional instructions do not affect the value stored in the real accumulator. 1452 | 1453 | On a ones complement machine, it is permissible to produce negative zero in RA provided these 1454 | instructions operate correctly with such a value. 1455 | 1456 | 5.16 ATN 1457 | 1458 | Arctangent of real accumulator 1459 | 1460 | 5.17 CHP 1461 | 1462 | Integer portion of real accumulator 1463 | 1464 | 5.18 COS 1465 | 1466 | Cosine of real accumulator 1467 | 1468 | 5.19 ETX 1469 | 1470 | e to the power in the real accumulator 1471 | 1472 | 5.20 LNF 1473 | 1474 | Natural logorithm of real accumulator 1475 | 1476 | 5.21 SIN 1477 | 1478 | Sine of real accumulator 1479 | 1480 | 5.22 SQR 1481 | 1482 | square root of real accumulat 1483 | 1484 | 5.23 TAN 1485 | 1486 | Tangent of real accumulator 1487 | 1488 | 1489 | The above orders operate upon the real accumulator, and replace the contents of the accumulator 1490 | with the result. 1491 | 1492 | The result of any of the above operations is undefined or out of range, real overflow is set, 1493 | the contents of (RA) are undefined and the following instruction must be either ROV or RNO 1494 | 1495 | #### 6- Operations on Character Values 1496 | 1497 | 1498 | Character operations employ the concept of a character pointer which uses either index register XR or XL 1499 | (not XS ). 1500 | 1501 | A character pointer points to a specific character in a string of characters stored CFP$C chars to a word. 1502 | 1503 | The only operations permitted on a character pointer are LCH and SCH. In particular, a character pointer 1504 | may not even be moved with MOV 1505 | 1506 | 1507 | - restriction 1 1508 | 1509 | It is important when coding in MINIMAL to ensure that no action occurring between the initial use of 1510 | PLC or PSC and the eventual clearing of XL or XR on completion of character operations can initiate 1511 | a garbage collection. 1512 | 1513 | The latter of course could cause the addressed characters to be moved leaving the character pointers 1514 | pointing to rubbish. 1515 | 1516 | - restriction 2. 1517 | 1518 | A further restriction to be observed in code handling character strings, is that strings built dynamically 1519 | should be right padded with zero characters to a full word boundary to permit easy hashing and use 1520 | of CEQ or CNE in testing strings for equality. 1521 | 1522 | 1523 | 6.1 PLC _x,opv_ 1524 | 1525 | Prepare ch ptr n _x_for LCH, CMC, MCB, MVC, and TRC 1526 | 1527 | 6.2 PSC _x,opv_ 1528 | 1529 | Prepare character pointer for SCH MVC MCB 1530 | 1531 | _opv_ can be omitted it is zero. 1532 | 1533 | The character initially addressed is determined by the word address in _x_ and the integer offset _opv_. 1534 | 1535 | There is an automatic implied offset of CFP$F bytes. CFP$F is used to formally introduce into MINIMAL 1536 | a value needed in translating these opcodes which, since MINIMAL itself does not prescribe a string 1537 | structure in detail, depends on the choice of a data structure for strings in the MINIMAL program. 1538 | e.g. CFP$B = CFP$C = 3, CFP$F = 6, num01 = 1, XL points to a series of 4 words, abc/def/ghi/jkl, 1539 | then PLC XL ,=num01 points to h. 1540 | 1541 | 1542 | 6.3 LCH _reg,opc_ 1543 | 1544 | Load character into register 1545 | 1546 | 6.4 SCH _reg,opc_ 1547 | 1548 | Store character from _reg_ 1549 | 1550 | These operations are defined such that the character is right justified in register _reg_ with zero 1551 | bits to the left. 1552 | 1553 | After LCH, for example, it is legitimate to regard _reg_ as containing the ordinal integer 1554 | corresponding to the character. 1555 | 1556 | _opc_ is one of the following three possibilities. 1557 | 1558 | - (x) -- 1559 | 1560 | The character pointed to by the character pointer in x. the character pointer is not changed. 1561 | 1562 | - (x)+ -- 1563 | 1564 | Same character as (x) but the character pointer is incremented to point to the next character following 1565 | execution. 1566 | 1567 | - -(x) -- 1568 | 1569 | The character pointer is decremented before accessing the character so that the previous character 1570 | is referenced. 1571 | 1572 | 6.5 CSC _x_ 1573 | 1574 | Complete store characters 1575 | 1576 | This instruction marks completion of a PSC sch,SCH ...,sch sequence initiated by a PSC x instruction. 1577 | 1578 | No more SCH instructions using x should be obeyed until another PSC is obeyed. 1579 | 1580 | It is provided solely as an efficiency aid on machines without character orders since it permits use of 1581 | register buffering of chars in sch sequences. 1582 | 1583 | Where CSC is not a no-op, it must observe restriction 2. (e.g. in SPITBOL, *alocs* zeroises the last 1584 | word of a string frame prior to SCH sequence being started so CSC must not nullify this action.) 1585 | 1586 | The following instructions are used to compare two words containing CFP$C characters. 1587 | 1588 | Comparisons distinct from BEQ BNE are provided as on some target machines, the possibility of the 1589 | sign bit being set may require special action. 1590 | 1591 | Note that restriction 2 above, eases use of these orders in testing complete strings for equality, 1592 | since whole word tests are possible. 1593 | 1594 | 6.6 CEQ _opw,opw,plbl_ 1595 | 1596 | Jump to _plbl_ _opw_ eq _opw_ 1597 | 1598 | 6.7 CNE _opw,opw,plbl_ 1599 | 1600 | Jump to _plbl_ _opw_ ne _opw_ 1601 | 1602 | 6.8 CMC _plbl_,_plbl_ 1603 | 1604 | Compare characters 1605 | 1606 | CMC is used to compare two character strings. before 1607 | executing CMC registers are set up as follows. 1608 | 1609 | ``` 1610 | (XL) character ptr for first string 1611 | (XR) character pointer for second string 1612 | (WA) character count (must be .gt. zero) 1613 | ``` 1614 | 1615 | XL and XR should have been prepared by PLC control passes to first _plbl_ the 1616 | first string is lexically less than the second string, and to the 1617 | second _plbl_ the first string is lexically greater. 1618 | 1619 | Control passes to the following instruction the strings are identical. after 1620 | executing this instruction, the values of XR and XL are set to zero and the value in (WA) is 1621 | undefined. 1622 | 1623 | Arguments to CMC may be complete or partial strings, so making optimisation to use whole word comparisons 1624 | difficult (dependent in general on shifts and masking). 1625 | 1626 | 6.9 TRC 1627 | 1628 | Translate characters 1629 | 1630 | TRC is used to translate a character string using a supplied translation table. before executing *trc* the 1631 | registers are set as follows. 1632 | 1633 | ``` 1634 | (XL) char ptr to string to be translated 1635 | (XR) char ptr to translate table 1636 | (WA) length of string to be translated 1637 | ``` 1638 | 1639 | XL and XR should have been prepared by PLC the translate table consists of 1640 | CFP$A* contiguous characters giving the translations 1641 | of the CFP$A* characters in the alphabet. 1642 | 1643 | On completion, (XR ) and (XL ) are set to zero and (WA) is undefined. 1644 | 1645 | 6.10 FLC _w_ 1646 | 1647 | Fold character to upper case 1648 | 1649 | FLC is used only `.culc` is defined. the character code 1650 | value in _w_ is translated to upper case it corresponds to a lower case 1651 | character. 1652 | 1653 | #### 7- Operations on Bit String Values 1654 | 1655 | 7.1 ANB _w,opw_ 1656 | 1657 | And bit string values, result in _w_ 1658 | 1659 | 7.2 ORB _w,opw_ 1660 | 1661 | Or bit string values, result in _w_ 1662 | 1663 | 1664 | 7.3 XOB _w,opw_ 1665 | 1666 | Exclusive or bit string values, result in _w_ 1667 | 1668 | In the above operations, the logical connective is applied separately to each of the CFP$N bits. 1669 | 1670 | 7.4 CMB _w_ 1671 | 1672 | Complement all bits in _w_ 1673 | 1674 | 1675 | 7.5 RSH _w,val_ 1676 | 1677 | Right shift _w_ by _val_ bits 1678 | 1679 | 1680 | 7.6 LSH _w,val_ 1681 | 1682 | Left shift _w_ by _val_ bits 1683 | 1684 | 1685 | 7.7 RSX _w,(x)_ 1686 | 1687 | Right shift _w_ by number of bits in _x_ 1688 | 1689 | 1690 | 7.8 LSX _w,(x)_ 1691 | 1692 | Left shift _w_ by the number of bits in _x_ 1693 | 1694 | 1695 | The above shifts are logical shifts in which bits shifted out are lost 1696 | and zero bits supplied as required. The shift count is in the range 1697 | 0-CFP$N . 1698 | 1699 | 7.9 NZB w,_plbl_ 1700 | 1701 | Jump to _plbl_ w is not all zero bits. 1702 | 1703 | 7.10 ZRB w,_plbl_ 1704 | 1705 | Jump to _plbl_ w is all zero bits 1706 | 1707 | 1708 | 7.11 ZGB _opn_ 1709 | 1710 | Zeroise garbage bits 1711 | 1712 | _opn_ contains a bit string representing a word of characters 1713 | from a string or some function formed from such characters (e.g. as a 1714 | result of hashing). 1715 | 1716 | On a machine where the word size is not a multiple of the character size, some bits in _reg_ may be undefined. 1717 | 1718 | This opcode replaces such bits by the zero bit. ZGB is a no-op the word size is a multiple of the character size. 1719 | 1720 | 1721 | #### 8- Conversion Instructions 1722 | 1723 | 1724 | The following instructions provide for conversion between lengths in 1725 | bytes and lengths in words. 1726 | 1727 | 1728 | 8.1 WTB _reg_ 1729 | 1730 | Convert _reg_ from words to bytes. 1731 | 1732 | 1733 | That is, multiply by CFP$B . This is a no-op if CFP$B is one. 1734 | 1735 | 8.2 BTW _reg_ 1736 | 1737 | Convert _reg_ from bytes to words 1738 | by dividing _reg_ by CFP$B discarding the fraction. no-op CFP$B is one 1739 | 1740 | The following instructions provide for conversion of one word integer 1741 | values (addresses) to and from the full signed integer format. 1742 | 1743 | 8.3 MTI _opn_ 1744 | 1745 | The value of _opn_ (an address) is moved as a positive integer to the integer accumulator. 1746 | 1747 | 8.4 MFI _opn,plbl_ 1748 | 1749 | The value currently stored in the integer accumulator is moved to 1750 | _opn_ as an address it is in the range 0 to CFP$M inclusive. 1751 | 1752 | If the accumulator value is outside this range, then the result in _opn_ is 1753 | undefined and control is passed to _plbl_. 1754 | 1755 | MFI destroys the value of (IA) whether or not integer overflow is 1756 | signalled. _plbl_ may be omitted overflow is impossible. 1757 | 1758 | The following instructions provide for conversion between real values and integer values. 1759 | 1760 | 8.5 ITR 1761 | 1762 | Convert integer value in integer accumulator to real and store in real 1763 | accumulator (may lose precision in some cases) 1764 | 1765 | 8.6 RTI _plbl_ 1766 | 1767 | Convert the real value in RA to an integer and place result in 1768 | IA . Conversion is by truncation of the fraction - no rounding occurs. 1769 | 1770 | Jump to _plbl_ if RA out of range. *RA* is not changed in either case. 1771 | 1772 | _plbl_ may be omitted overflow is impossible. 1773 | 1774 | The following instructions provide for computing the length of storage 1775 | required for a text string. 1776 | 1777 | 8.7 CTW _w,val_ 1778 | 1779 | This instruction computes the sum (number of words required to store w characters) + (val). 1780 | The sum is stored in _w_. 1781 | 1782 | For example, CFP$C is 5, and WA contains 32, then CTW WA,2 gives a result of 9 in WA. 1783 | 1784 | 8.8 CTB w,val 1785 | 1786 | CTB is exactly like CTW except that the result is in bytes. it has the same effect as CTW w,_val_ WTB w 1787 | 1788 | The following instructions provide for conversion from integers to and from numeric digit characters 1789 | for use in numeric conversion routines. They employ negative integer values to allow for 1790 | proper conversion of numbers which cannot be complemented. 1791 | 1792 | 1793 | 8.9 CVM _plbl_ 1794 | 1795 | Convert by multiplication 1796 | 1797 | The integer accumulator, which is zero or negative, is multiplied by 1798 | 10. WB contains the character code for a digit. the 1799 | value of this digit is then subtracted from the result. 1800 | 1801 | The result is out of range, then control is passed to _plbl_ 1802 | with the result in (IA) undefined. execution of CVM leaves the result in (WB ) 1803 | undefined. 1804 | 1805 | 1806 | 8.10 CVD 1807 | 1808 | Convert by division 1809 | 1810 | The integer accumulator, which is zero or negative, is divided by 10. 1811 | the quotient (zero or negative) is replaced in the accumulator. The 1812 | remainder is converted to the character code of a digit and placed in 1813 | WA. For example, an operand of -523 gives a quotient of -52 and a 1814 | remainder in WA of CH$D3. 1815 | 1816 | #### 9- Block Move Instructions 1817 | 1818 | The following instructions are used for transferring data from one 1819 | area of memory to another in blocks. They can be implemented with the 1820 | indicated series of other macro-instructions, but more efficient 1821 | implementations will be possible on most machines. 1822 | 1823 | Note that in the equivalent code sequence shown below, a zero 1824 | value in WA will move at least one item, and may may wrap the counter 1825 | causing a core dump in some imple- mentations. Thus WA should be .gt. 1826 | 0 prior to invoking any of these block move instructions. 1827 | 1828 | 9.1 MVC 1829 | 1830 | Move characters 1831 | 1832 | 1833 | Before obeying this order WA,XL ,XR should have been set up, the latter two by PLC 1834 | PSC resp. MVC is equivalent to the sequence 1835 | 1836 | ``` 1837 | mov dumpb,WB 1838 | lct WA,WA 1839 | loopc lch WB,(XL)+ 1840 | sch WB,(XR)+ 1841 | bct WA,loopc 1842 | csc XR 1843 | mov WB,dumpb 1844 | 1845 | ``` 1846 | 1847 | The character pointers are bumped as indicated and the final value of WA is undefined. 1848 | 1849 | 1850 | 9.2 MVW 1851 | 1852 | move words 1853 | 1854 | MVW is equivalent to the sequence 1855 | 1856 | ``` 1857 | opw mov (XR)+,(XL)+ 1858 | dca WA WA = bytes to move 1859 | bnz WA,lo opw 1860 | 1861 | ``` 1862 | 1863 | Note that this implies that the value in WA is the length in bytes 1864 | which is a multiple of CFP$B . 1865 | 1866 | The initial addresses in XR ,XL are word addresses. 1867 | 1868 | As indicated, the final XR ,XL values point past the new and old regions of memory respectively. 1869 | 1870 | The final value of WA is undefined. WA,XL ,XR must be set up before obeying MVW 1871 | 1872 | 9.3 MWB 1873 | 1874 | Move words backwards 1875 | 1876 | 1877 | 1878 | MWB is equivalent to the sequence 1879 | 1880 | ``` 1881 | loopb mov -(XL),-(XR) 1882 | dca WA WA = bytes to move 1883 | bnz WA,loopb 1884 | ``` 1885 | 1886 | There is a requirement that the initial value in XL 1887 | be at least 256 less than the value in XR . this 1888 | allows an implementation in which chunks of 256 bytes are moved 1889 | forward (IBM 360, ICL 1900). 1890 | 1891 | The final value of WA is undefined. 1892 | 1893 | WA ,XL , XR must be set up before obeying MWB . 1894 | 1895 | 9.4 MCB 1896 | 1897 | 1898 | 1899 | Move characters backwards 1900 | 1901 | 1902 | MCB is equivalent to the sequence 1903 | 1904 | ``` 1905 | mov dumpb,WB 1906 | lct WA,WA 1907 | loopc lch WB,-(XL) 1908 | sch WB,-(XR) 1909 | bct WA,loopc 1910 | csc XR 1911 | mov WB,dumpb 1912 | ``` 1913 | 1914 | 1915 | There is a requirement that the initial value in XL 1916 | be at least 256 less than the value in XR . this 1917 | allows an implementation in which chunks of 256 bytes are moved 1918 | forward (IBM 360, ICL 1900). 1919 | 1920 | The final value of WA is undefined. WA,XL ,XR must be set up before 1921 | obeying MCB 1922 | 1923 | 1924 | #### 10- Operations Connected with the Stack 1925 | 1926 | The stack is an area in memory which is dedicated for use in 1927 | conjunction with the stack pointer register (XS ). As 1928 | previously described, it is used by the JSR and EXI 1929 | instructions and may be used for storage of any other data as 1930 | required. 1931 | 1932 | The stack builds either way in memory and an important restriction is 1933 | that the value in (XS ) must be the address of the 1934 | stack front at all times since some implementations may randomly 1935 | destroy stack locations beyond (XS ). 1936 | 1937 | The starting stack base address is passed in (XS ) at 1938 | The start of execution. During execution it is necessary to make sure 1939 | that the stack does not overflow. This is achieved by executing the 1940 | following instruction periodically. 1941 | 1942 | 10.1 CHK 1943 | 1944 | Check stack overflow 1945 | 1946 | After successfully executing CHK it is permissible to 1947 | use up to 100 additional words before issuing another chk thus 1948 | CHK need not be issued every time the stack is 1949 | expanded. In some implementations, the checking may be automatic and 1950 | CHK will have no effect. 1951 | 1952 | Following the above rule makes sure that the program 1953 | will operate correctly in implementations with no automatic check. 1954 | 1955 | Stack overflow occurs (detected either automatically or by a 1956 | CHK instruction), then control is passed to the stack overflow section (see program form). 1957 | 1958 | Note that this transfer may take place following any instruction which stores 1959 | data at a new location on the stack. After stack overflow, stack is 1960 | arbitrarily popped to give some space in which the error procedure may 1961 | operate. otherwise a loop of stack overflows may occur. 1962 | 1963 | #### 11- Data Generation Instructions 1964 | 1965 | 1966 | The following instructions are used to generate constant values in the 1967 | constant section and also to assemble initial values in the working 1968 | storage section. They may not appear except in these two sections. 1969 | 1970 | 11.1 DAC _addr_ 1971 | 1972 | Assemble address constant. 1973 | 1974 | Generates one word containing the specified one word integer value 1975 | (address). 1976 | 1977 | 1978 | 11.2 DIC _integer_ 1979 | 1980 | Generates an integer value which occupies CFP$I 1981 | consecutive words. 1982 | 1983 | The operand is a digit string with a required leading sign. 1984 | 1985 | 11.3 DRC _real_ 1986 | 1987 | Assembles a real constant which occupies CFP$R 1988 | consecutive words. 1989 | 1990 | The operand form must obey the rules for a FORTRAN 1991 | real constant with the extra requirement that a leading sign be 1992 | present. 1993 | 1994 | 1995 | 11.4 DTC _dtext_ 1996 | 1997 | Define _text_ constant. 1998 | 1999 | Text is started and ended with any character not contained in the 2000 | characters to be assembled. The constant occupies consecutive words as 2001 | dictated by the configuration parameter CFP$C . 2002 | 2003 | Any unused chars in the last word are right filled with zeros (i.e. the 2004 | character whose internal code is zero). The string contains a 2005 | sequence of letters, digits, blanks and any of the following special 2006 | characters. =,$.(\*)/+- 2007 | 2008 | 2009 | No other characters may be used in a _dtext_ operand. 2010 | 2011 | 11.5 DBC val 2012 | 2013 | Assemble bit string constant. 2014 | 2015 | The operand is a positive integer value which is interpreted in 2016 | binary, right justified and left filled with zero bits. Thus 5 would 2017 | imply the bit string value 00...101. 2018 | 2019 | #### 12- Symbol Definition Instructions 2020 | 2021 | The following instruction is used to define symbols in the definitions 2022 | section. It may not be used elsewhere. 2023 | 2024 | 12.1 EQU _eqop_ 2025 | 2026 | Define symbol 2027 | 2028 | The symbol which appears in the label field is defined to have the absolute value given by the _eqop_ operand. 2029 | A given symbol may be defined only once in this manner, and any symbols occuring in _eqop_ 2030 | must be previously defined. 2031 | 2032 | The following are the possibilities for _eqop_ 2033 | 2034 | 2035 | *_val_ 2036 | 2037 | the indicated value is used 2038 | 2039 | 2040 | - _val+val_ 2041 | 2042 | The sum of the two values is used. This sum must not exceed CFP$M 2043 | 2044 | - _val-val_ 2045 | 2046 | The difference between the two values (must be positive) is used. 2047 | 2048 | This format defines the label by using a value supplied by the MINIMAL 2049 | translator. Values are required for the 2050 | 2051 | 2052 | ``` 2053 | CFP$x (configuration parameters) 2054 | E$xxx (environment parameters) 2055 | CH$xx (character codes). 2056 | ``` 2057 | 2058 | In order for a translator to handle this format correctly the 2059 | definitions section must be consulted for details of required symbols 2060 | as listed at the front of the section. 2061 | 2062 | 2063 | The following instructions may be used to define symbols in the 2064 | procedure section. They may not be used in any other part of the 2065 | program. 2066 | 2067 | 12.2 *exp* 2068 | 2069 | Define external procedure 2070 | 2071 | *exp* defines the symbol appearing in the 2072 | label field to be the name of an external procedure which can be 2073 | referenced in a subsequent JSR instruction. 2074 | 2075 | The coding for the procedure is external to the coding of the source 2076 | program in this language. The code for external procedures may be 2077 | referred to collectively as the operating system interface, or more 2078 | briefly, osint, and will frequently be a separately compiled segment 2079 | of code loaded with SPITBOL to produce a complete system. 2080 | 2081 | 12.3 INP _ptyp_,int 2082 | 2083 | Define internal procedure 2084 | 2085 | INP defines the symbol appearing in the 2086 | label field to be the name of an internal procedure and gives its type 2087 | and number of exit parameters. 2088 | 2089 | The label can be referenced in JSR instructions and it must appear labelling a 2090 | PRC instruction in the program section. 2091 | 2092 | 12.4 INR 2093 | 2094 | Define internal routine 2095 | 2096 | INR defines the symbol appearing in the 2097 | label field to be the name of an internal routine. 2098 | 2099 | The label may be referenced in any type of branch order and it must appear labelling a 2100 | RTN instruction in the program section. 2101 | 2102 | ### 13 - Assembly Listing Layout Instruction 2103 | 2104 | 13.1 EJC 2105 | 2106 | Eject to next page 2107 | 2108 | 2109 | 13.2 TTL text 2110 | 2111 | Set new assembly title 2112 | 2113 | TTL implies an immediate eject of the assembly listing to print the new title. 2114 | 2115 | The use of TTL and EJC cards is such 2116 | that the program will list neatly the printer prints as many as 58 2117 | lines per page. In the event that the printer depth is less than this, 2118 | or the listing contains interspersed lines (such as actual generated 2119 | code), then the format may be upset. 2120 | 2121 | Lines starting with an asterisk are comment lines which cause no code 2122 | to be generated and may occur freely anywhere in the program. The 2123 | format for comment lines is given in section -15-. 2124 | 2125 | Lines starting with left set brace, '{', begin a block comment that 2126 | continues up to and includind the first following line that begins 2127 | with a right set brace, '}'. Any statements such as instructions or 2128 | conditional assembly within the body of the block comment will not be 2129 | recognized as such. 2130 | 2131 | #### 14 - Program Form 2132 | 2133 | 2134 | 2135 | The program consists of separate sections separated by 2136 | SEC operations. The sections must appear in the 2137 | following specified order. 2138 | 2139 | 2140 | 14.1 SEC 2141 | 2142 | 2143 | ``` 2144 | start of procedure section 2145 | 2146 | (procedure section) 2147 | 2148 | SEC start of definitions section 2149 | 2150 | (definitions section) 2151 | 2152 | SEC start of constant storage section 2153 | 2154 | (constant storage section) 2155 | 2156 | SEC start of working storage section 2157 | 2158 | (working storage section) 2159 | 2160 | SEC start of program section 2161 | 2162 | (program section) 2163 | 2164 | SEC start of stack overflow section 2165 | 2166 | (stack overflow section) 2167 | 2168 | SEC start of error section 2169 | 2170 | (error section) 2171 | 2172 | ``` 2173 | 2174 | 1 4.2 END 2175 | 2176 | End of assembly 2177 | 2178 | ### Section 10 - Program Form 2179 | 2180 | * procedure section 2181 | 2182 | 2183 | 2184 | The procedure section contains all the exp instructions for externally 2185 | available procedures and INP inr opcodes for internal 2186 | procedures,routines so that a single pass MINIMAL translator has 2187 | advance knowledge of procedure types when translating calls. 2188 | 2189 | 2190 | - definitions section 2191 | 2192 | 2193 | 2194 | The definitions section contains EQU instructions 2195 | which define symbols referenced later on in the program, constant and 2196 | work sections. 2197 | 2198 | - constant storage section 2199 | 2200 | 2201 | 2202 | The constant storage section consists entirely of constants assembled 2203 | with the DAC dic,DRC dtc,dbc 2204 | assembly operations. these constants can be freely referenced by the 2205 | program instructions. 2206 | 2207 | 2208 | 2209 | - working storage section 2210 | 2211 | The working storage section consists entirely of DAC 2212 | DIC, DRC,DBC, DTC instructions to define a fixed length work area. 2213 | The work locations in this area can be directly referenced in program instructions. 2214 | The area is initialized in accordance with the values assembled in the instructions. 2215 | 2216 | 2217 | 2218 | - program section 2219 | 2220 | The program section contains program instructions and associated 2221 | operations (such as PRC ENP ENT). 2222 | 2223 | 2224 | Control is passed to the first instruction in this section when 2225 | execution is initiated. 2226 | 2227 | - stack overflow section 2228 | 2229 | The stack overflow section contains instructions like the program 2230 | section. 2231 | 2232 | Control is passed to the first instruction in this section 2233 | following the occurrence of stack overflow, see CHK 2234 | instruction. 2235 | 2236 | - error section 2237 | 2238 | The error section contains instructions like the program section. 2239 | 2240 | Control is passed to the first instruction in this section when a 2241 | procedure exit corresponds to an error parameter (see err) or when an 2242 | ERB opcode is obeyed. 2243 | 2244 | The error code must clean up the main stack and cater for 2245 | the possibility that a subroutine stack may need clean up. 2246 | 2247 | ## OSINT 2248 | 2249 | Though not part of the MINIMAL source, it is useful to refer to the collection of initialisation 2250 | and *exp* routines as osint (operating system interface). 2251 | 2252 | Errors occurring within osint procedures are usually handled by making an error return. If this is 2253 | not feasible or appropriate, osint may use the MINIMAL error section to report errors directly by 2254 | branching to it with a suitable numeric error code in WA. 2255 | 2256 | ### Section 11 - Statement Format 2257 | 2258 | All labels are exactly five characters long and start with three 2259 | letters (abcdefghijklmnopqrstuvwxy$) followed by two letters or 2260 | digits. 2261 | 2262 | The letter z may not be used in MINIMAL symbols but $ is permitted. 2263 | 2264 | For implementations where $ may not appear in the target code , a 2265 | simple substitution of z for $ may thus be made without risk of 2266 | producing non-unique symbols. 2267 | 2268 | The letter z is however permitted in opcode mnemonics and in comments. 2269 | 2270 | MINIMAL statements are in a fixed format as follows. 2271 | 2272 | ``` 2273 | cols 1-5 label any (else blank) 2274 | 2275 | cols 6-7 always blank 2276 | 2277 | cols 8-10 operation mnemonic 2278 | 2279 | cols 11-12 blanks 2280 | 2281 | cols 13-28 operand field, terminated by a 2282 | blank. may occasionally 2283 | extend past column 28. 2284 | 2285 | cols 30-64 comment. always separated from the 2286 | operand field by at least one blank 2287 | may occasionally start after column 2288 | 30 the operand extends past 28. 2289 | a special exception occurs for the 2290 | IFF instruction, whose comment may 2291 | be only 20 characters long (30-49). 2292 | 2293 | cols 65 on unused 2294 | 2295 | 2296 | comment lines have the following format 2297 | 2298 | col 1 asterisk 2299 | 2300 | cols 2-7 blank 2301 | 2302 | cols 8-64 arbitrary text, restricted to the 2303 | fortran character set. 2304 | 2305 | 2306 | the fortran character set is a-z 0-9 =,$.(*)-/+ 2307 | ``` 2308 | ### Section 12 - Program Execution 2309 | 2310 | Execution of the program begins with the first instruction in the program section. 2311 | 2312 | In addition to the fixed length memory regions defined by the 2313 | assembly, there are two dynamically allocated memory regions as follows. 2314 | 2315 | 2316 | - data area 2317 | 2318 | 2319 | This is an area available to the program for general storage of data. Any data value 2320 | may be stored in this area except instructions. 2321 | 2322 | In some implementations, it may be possible to increase the size of this area dynamically 2323 | by adding words at the top end with a call to a system procedure. 2324 | 2325 | - stack area 2326 | 2327 | This region of memory holds the stack used for subroutine calls and other storage of one word 2328 | integer values (addresses). This is the stack associated with index register XS . 2329 | 2330 | The locations and sizes of these areas are specified by the values in the registers at the 2331 | start of program execution as follows. 2332 | 2333 | - (XS ) 2334 | 2335 | Address one past the stack base. For example, if XS is 23456, a d-stack will occupy words 23455,23454,... 2336 | whereas a u-stack will occupy 23457,23458,... 2337 | 2338 | - (XR) 2339 | 2340 | Address of the first word in the data area 2341 | 2342 | (XL) 2343 | 2344 | Address of the last word in the data area. 2345 | 2346 | - (WA) 2347 | 2348 | Initial stack pointer 2349 | 2350 | - (WB ,WC ,IA ,ra,CP ) 2351 | 2352 | There is no explicit way to terminate the execution of a program. This function is performed by an 2353 | appropriate system procedure referenced with the SYSEJ instruction. 2354 | 2355 | 2356 | ## SPITBOL Operating System Interface (OSINT) 2357 | 2358 | This section describes the operating system interface functions, mostly written in C, 2359 | that are used by MACRO SPITBOL for runtime support,doing input/output, loading external functions, 2360 | reading and writing save files, reading and writing load modules, and so forth. 2361 | 2362 | ### SYSAX -- after execution 2363 | 2364 | If the conditional assembly symbol .csax is defined, this routine 2365 | is called immediately after execution and before printing of execution 2366 | statistics or dump output. 2367 | 2368 | The purpose of call is for the implementor to determine and if the 2369 | call is not required it will be omitted if .csax is undefined. in this 2370 | case SYSAX need not be coded. 2371 | 2372 | ``` 2373 | JSR SYSAX call after execution 2374 | ``` 2375 | ### sysbs -- backspace file 2376 | 2377 | SYSBS is used to implement the snobol4 function backspace. 2378 | 2379 | If the conditional assembly symbol .cbsp is defined. the meaning 2380 | is system dependent. In general, backspace repositions the file one 2381 | record closer to the beginning of file, such that a subsequent read or 2382 | write will operate on the previous record. 2383 | 2384 | ``` 2385 | 2386 | (WA) pointer to FCBLK or zero 2387 | (XR) backspace argument (scblk pointer) 2388 | JSR sysbs call to backspace 2389 | PPM loc return here if file does not exist 2390 | PPM loc return here if backspace not allowed 2391 | PPM loc return here if i/o error 2392 | (WA,WB) destroyed 2393 | ``` 2394 | 2395 | The second error return is used for files for which backspace is 2396 | not permitted. For example, it may be expected files on character 2397 | devices are in this category. 2398 | 2399 | ### SYSBP exp 0 define external entry point 2400 | 2401 | SYSBP is not required in normal operation. It is 2402 | called as a breakpoint to assist in debugging. 2403 | 2404 | ``` 2405 | JSR SYSBP call to breakpoint 2406 | ``` 2407 | ### SYSBX -- before execution 2408 | 2409 | SYSBX exp 0 define external entry point 2410 | 2411 | Called after initial SPITBOL compilation and before commencing 2412 | execution in case osint needs to assign files or perform other 2413 | necessary services. osint may also choose to send a message to online 2414 | terminal (if any) indicating that execution is starting. 2415 | 2416 | ``` 2417 | JSR SYSBX call before execution starts 2418 | ``` 2419 | 2420 | ### SYSCI -- convert integer 2421 | 2422 | SYSCI is an optional osint routine that causes 2423 | SPITBOL to call SYSCI to convert integer values to 2424 | strings, rather than using the internal SPITBOL conversion code. 2425 | 2426 | This code may be less efficient on machines with hardware 2427 | conversion instructions and in such cases, It may be an advantage to 2428 | include SYSCI. The symbol .CNCI must be defined if 2429 | this routine is to be used. 2430 | 2431 | The rules for converting integers to strings are that positive 2432 | values are represented without any sign, and 2433 | 2434 | There are never any leading blanks or zeros, except in the case of 2435 | zero itself which is represented as a single zero digit. Negative 2436 | numbers are represented with a preceeding minus sign. There are never 2437 | any trailing blanks, and conversion cannot fail. 2438 | 2439 | ``` 2440 | (IA) value to be converted 2441 | JSR SYSCI call to convert integer value 2442 | (XL) pointer to pseudo-scblk with string 2443 | ``` 2444 | 2445 | ### SYSCB -- general string comparison function 2446 | 2447 | Provides string comparison determined by interface. used for 2448 | international string comparison. 2449 | 2450 | 2451 | ``` 2452 | (XR) character pointer for first string 2453 | (XL) character pointer for second string 2454 | (WB) character count of first string 2455 | (WA) character count of second string 2456 | JSR SYSCB call to SYSCB function 2457 | PPM loc string too long for SYSCB 2458 | PPM loc first string lexically gt second 2459 | PPM loc first string lexically lt second 2460 | --- strings equal 2461 | (XL) zero 2462 | (XR) destroyed 2463 | ``` 2464 | 2465 | ### SYSCR -- convert real 2466 | 2467 | SYSCR is an optional osint routine that causes 2468 | SPITBOL to call SYSCR to convert real values to 2469 | strings, rather than using the internal SPITBOL conversion code. 2470 | 2471 | This code may be desired on machines where the integer size is too 2472 | small to allow production of a sufficient number of significant 2473 | digits. The symbol .CNCR must be defined if this routine is to be 2474 | used. 2475 | 2476 | The rules for converting reals to strings are that positive values 2477 | are represented without any sign, and there are never any leading 2478 | blanks or zeros, except in the case of zero itself which is 2479 | represented as a single zero digit. Negative numbers are represented 2480 | with a preceeding minus sign. There are never any trailing blanks, or 2481 | trailing zeros in the fractional part. conversion cannot fail. 2482 | 2483 | ``` 2484 | (RA) value to be converted 2485 | (WA) no. of significant digits desired 2486 | (WB) conversion type: 2487 | negative for e-type conversion 2488 | zero for g-type conversion 2489 | positive for f-type conversion 2490 | (WC) character positions in result SCBLK 2491 | (XR) scblk for result 2492 | JSR SYSCR call to convert real value 2493 | (XR) result SCBLK 2494 | (WA) number of result characters 2495 | ``` 2496 | 2497 | ### SYSDC -- date check 2498 | 2499 | SYSDC is called to check that the expiry date for 2500 | a trial version of SPITBOL is unexpired. 2501 | 2502 | ``` 2503 | JSR SYSDC call to check date 2504 | return only if date is ok 2505 | ``` 2506 | 2507 | 2508 | ### SYSDM exp 0 define external entry point 2509 | 2510 | SYSDM is called by a SPITBOL program call of 2511 | DUMP(n) with n ge 4. Its purpose is to provide a core dump. n could 2512 | hold an encoding of the start adrs for dump and amount to be dumped 2513 | e.g. n = 256\*a + s , s = start adrs in kilowords, a = kilowords to 2514 | dump 2515 | 2516 | ``` 2517 | (XR) parameter n of call DUMP(n) 2518 | JSR SYSDM call to enter routine 2519 | 2520 | ``` 2521 | 2522 | ### SYSDT -- get current date 2523 | 2524 | SYSDT is used to obtain the current date. The date is returned as a character string in 2525 | any format appropriate to the operating system in use. It may also contain the current time of day. 2526 | 2527 | SYSDT is used to implement the SNOBOL4 function DATE(). 2528 | 2529 | ``` 2530 | (XR) parameter n of call date(n) 2531 | JSR SYSDT call to get date 2532 | (XL) pointer to block containing date 2533 | ``` 2534 | 2535 | The format of the block is like an SCBLK except that the first word need not be set. 2536 | The result is copied into SPITBOL dynamic memory on return. 2537 | 2538 | ### SYSEA -- inform osint of compilation and runtime errors 2539 | 2540 | Provides means for interface to take special actions on errors 2541 | 2542 | ``` 2543 | (WA) error code 2544 | (WB) line number 2545 | (WC) column number 2546 | (XR) system stage 2547 | (XL) file name (scblk) 2548 | JSR SYSEA call to SYSEA function 2549 | PPM loc suppress printing of error message 2550 | (XR) message to print (scblk) or 0 2551 | 2552 | ``` 2553 | 2554 | SYSEA may not return if interface chooses to retain control. 2555 | Closing files via the fcb chain will be the responsibility of the interface. 2556 | 2557 | All registers must be preserved 2558 | 2559 | ### SYSEF -- eject file 2560 | 2561 | SYSEF is used to write a page eject to a named file. It may only be used for files 2562 | where this concept makes sense. Note that SYSEF is not normally used for the standard 2563 | output file (see SYSEP). 2564 | 2565 | ``` 2566 | (WA) pointer to FCBLK> or zero 2567 | (XR) eject argument (scblk pointer) 2568 | JSR SYSEF call to eject file 2569 | PPM loc return here if file does not exist 2570 | PPM loc return here if inappropriate file 2571 | PPM loc return here if i/o error 2572 | ``` 2573 | 2574 | ### SYSEJ -- end of job 2575 | 2576 | SYSEF is used to write a page eject to a named file. It may only be used for files 2577 | where this concept makes sense. 2578 | 2579 | Note that SYSEF is not normally used for the standard output file (see SYSEP). 2580 | 2581 | ``` 2582 | (WA) pointer to FCBLK or zero 2583 | (XR) eject argument (scblk pointer) 2584 | JSR SYSEF call to eject file 2585 | PPM loc return here if file does not exist 2586 | PPM loc return here if inappropriate file 2587 | PPM loc return here if i/o error 2588 | ``` 2589 | 2590 | ### SYSEF -- end of job 2591 | 2592 | SYSEF is used to write a page eject to a named file. It may only be used for 2593 | files where this concept makes sense. 2594 | 2595 | Note that SYSEF is not normally used for the standard output file (see SYSEP). 2596 | 2597 | ``` 2598 | (WA) pointer to FCBLK or zero 2599 | (XR) eject argument (scblk pointer) 2600 | JSR SYSEF call to eject file 2601 | PPM loc return here if file does not exist 2602 | PPM loc return here if inappropriate file 2603 | PPM loc return here if i/o error 2604 | ``` 2605 | 2606 | ### SYSEJ -- end of job 2607 | 2608 | SYSEJ is called once at the end of execution to terminate the run. The significance of the 2609 | abend and code values is system dependent. In general, the code value should be made available 2610 | for testing, and the abend value should cause some post-mortem action such as a dump. 2611 | 2612 | Note that SYSEJ does not return to its caller. See SYSXI for details of FCBLK chain 2613 | 2614 | ``` 2615 | (WA) value of abend keyword 2616 | (WB) value of code keyword 2617 | (XL) zero or pointer to head of FCBLK chain 2618 | JSR SYSEJ call to end job 2619 | ``` 2620 | 2621 | The following special values are used as codes in (WB) 2622 | 2623 | ``` 2624 | 999 execution suppressed 2625 | 998 standard output file full or unavailable in a SYSXI 2626 | load module. in these cases (*wa*) contains the number 2627 | of the statement causing premature termination. 2628 | ``` 2629 | 2630 | ### SYSEM -- get error message text 2631 | 2632 | SYSEM is used to obtain the text of err, erb 2633 | calls in the source program given the error code number. It is allowed 2634 | to return a null string if this facility is unavailable. 2635 | 2636 | ``` 2637 | (WA) error code number 2638 | JSR SYSEM call to get text 2639 | (XR) text of message 2640 | ``` 2641 | 2642 | The returned value is a pointer to a block in SCBLK format except that the first 2643 | word need not be set. The string is copied into dynamic memory on return. 2644 | If the null string is returned either because SYSEM does not 2645 | provide error message texts or because WA is out of range, SPITBOL will print the 2646 | string stored in errtext keyword. 2647 | 2648 | ### SYSEN - endfile 2649 | 2650 | SYSEN is used to implement the snobol4 function endfile. The meaning is system dependent. 2651 | In general, endfile implies that no further i/o operations will be performed, 2652 | but does not guarantee this to be the case. The file should be closed after the 2653 | call, a subsequent read or write may reopen the file at the start or 2654 | it may be necessary to reopen the file via SYSIO. 2655 | 2656 | ``` 2657 | (WA) pointer to FCBLK or zero 2658 | (XR) endfile argument (scblk pointer) 2659 | JSR SYSEN call to endfile 2660 | PPM loc return here if file does not exist 2661 | PPM loc return here if endfile not allowed 2662 | PPM loc return here if i/o error 2663 | (WA,WB) destroyed 2664 | ``` 2665 | 2666 | The second error return is used for files for which endfile is not permitted. 2667 | For example, it may be expected that the standard input and output files are in this category. 2668 | 2669 | ### SYSEP -- eject printer page 2670 | 2671 | SYSEP is called to perform a page eject on the standard printer output file (corresponding to SYSPR output). 2672 | 2673 | ``` 2674 | JSR SYSEP call to eject printer output< 2675 | ``` 2676 | 2677 | ### SYSEX -- call external function 2678 | 2679 | SYSEX is called to pass control to an external function previously loaded with a call to SYSLD. 2680 | 2681 | ``` 2682 | (XS) pointer to arguments on stack 2683 | (XL) pointer to control block (efblk) 2684 | (WA) number of arguments on stack 2685 | JSR SYSEX call to pass control to function 2686 | PPM loc return here if function call fails 2687 | PPM loc return here if insufficient memory 2688 | PPM loc return here if bad argument type 2689 | (XS) popped past arguments 2690 | (XR) result returned 2691 | ``` 2692 | 2693 | The arguments are stored on the stack with the last argument at 0(XS). 2694 | On return, XS is popped past the arguments. 2695 | 2696 | The form of the arguments as passed is that used in the SPITBOL translator (see definitions 2697 | and data structures section). The control block format is also described (under EFBLK) in this section. 2698 | 2699 | There are two ways of returning a result: 2700 | 2701 | 2702 | Return a pointer to a block in dynamic storage. This block must be in exactly correct format, 2703 | including the first word. Only functions written with intimate knowledge of the system will return in this 2704 | way. 2705 | 2706 | String, integer and real results may be returned by pointing to a pseudo-block outside 2707 | dynamic memory. 2708 | 2709 | This block is in ICBLK, RCBLK or SCBLK format except that the first word will be overwritten 2710 | by a type word on return and so need not be correctly set. 2711 | 2712 | 2713 | Such a result is copied into main storage before proceeding. Unconverted results may similarly be 2714 | returned in a pseudo-block which is in correct format including type word recognisable by garbage 2715 | collector since block is copied into dynamic memory. 2716 | 2717 | 2718 | ### SYSFC -- file control block routine 2719 | 2720 | See also SYSIO 2721 | 2722 | Input and output have three arguments referred to as an 2723 | 2724 | `input(variable name,file arg1,file arg2)` 2725 | `output(variable name,file arg1,file arg2)` 2726 | 2727 | File *arg1* may be an integer or string used to identify an i/o channel. It is converted to a string for checking. 2728 | 2729 | The exact significance of file *arg2* is not rigorously prescribed but to improve portability, 2730 | The scheme described in the SPITBOL user manual should be adopted when possible. The preferred 2731 | form is 2732 | 2733 | A string "f,r,c,i,...,z" where _f_ is an optional file name which is placed first. remaining items 2734 | may be omitted or included in any order. 2735 | 2736 | _r_ is maximum record length 2737 | 2738 | _c_ is a carriage control character or character string 2739 | 2740 | _i_ is some form of channel identification used in the absence of _f_ to associate the variable 2741 | with a file allocated dynamically by jcl commands at SPITBOL load time. 2742 | 2743 | ,...,_z_ are additional fields. 2744 | 2745 | If , (comma) cannot be used as a delimiter, `.ciod` should be defined to introduce by conditional assembly 2746 | another delimiter (see 2747 | 2748 | ``` 2749 | iodel equ \* 2750 | 2751 | ``` 2752 | 2753 | early in definitions section). 2754 | 2755 | SYSFC is called when a variable is input or output associated to check file _arg1_ and file _arg2_ and to 2756 | report whether an FCBLK (file control block) is necessary and if so what size it should be. 2757 | 2758 | This makes it possible for SPITBOL rather than osint to allocate such a block in dynamic memory if 2759 | required or alternatively in static memory. 2760 | 2761 | The significance of an FCBLK , if one is requested, is entirely up to the system interface. 2762 | 2763 | The only restriction is that if the FCBLK should appear to lie in dynamic memory, pointers to it 2764 | will be met if SYSFC requests SPITBOL to provide an FCBLK). 2765 | 2766 | should be proper pointers to the start of a recognisable and garbage collectable block (this condition 2767 | An option is provided for osint to return a pointer in XL to an FCBLK which it privately allocated. 2768 | This pointer will be made available when i/o occurs later. Private FCBLKs may have arbitrary contents 2769 | and SPITBOL stores nothing in them. 2770 | 2771 | The requested size for an FCBLK in dynamic memory should allow a 2 word overhead for block type and length fields. 2772 | 2773 | Information subsequently stored in the remaining words may be arbitrary if an xnblk (external 2774 | non-relocatable block) is requested. 2775 | 2776 | If the request is for an_ xrblk_ (external relocatable block) the contents of words should be collectable 2777 | (i.e. any apparent pointers into dynamic should be genuine block pointers). 2778 | 2779 | These restrictions do not apply if an FCBLK is allocated outside dynamic or is not allocated at all. 2780 | 2781 | If an FCBLK is requested, its fields will be initialised to zero before entry to SYSIO with the exception 2782 | of words 0 and 1 in which the block type and length fields are placed for FCBLKs in dynamic memory only. 2783 | 2784 | For the possible use of SYSEJ and SYSXI, if FCBLKs are used, a chain is built so that they may all be 2785 | found - see SYSXI for details. 2786 | 2787 | 2788 | If both file _arg1_ and file _arg2_ are null, calls of SYSFC and SYSIO are omitted. 2789 | 2790 | If file _arg1_ is null (standard input/output file), SYSFC is called to check non-null file _arg2_ but any 2791 | request for an FCBLK will be ignored, since SPITBOL handles the standard files specially and cannot readily 2792 | keep FCBLK pointers for them.file _arg1_ is type checked by SPITBOL so further checking may be unneccessary 2793 | in many implementations. file _arg2_ is passed so that SYSFC may analyse and check it. however to assist in 2794 | this, SPITBOL also passes on the stack the components of this argument with file name, _f_ (otherwise null) 2795 | extracted and stacked first. 2796 | 2797 | The other fields, if any, are extracted as substrings, pointers to them are stacked and a count of all items 2798 | stacked is placed in WC. 2799 | 2800 | If an FCBLK was earlier allocated and pointed to via file _arg1_, SYSFC is also passed a pointer to this FCBLK. 2801 | 2802 | ``` 2803 | (XL) file arg1 scblk ptr (2nd arg) 2804 | (XR) filearg2 (3rd arg) or null 2805 | -(XS)...-(XS) scblks for $f$,$r$,$c$,... 2806 | (WC) no. of stacked scblks above 2807 | (WA) existing file arg1 FCBLK ptr or 0 2808 | (WB) 0/3 for input/output assocn 2809 | JSR SYSFC call to check need for FCBLK 2810 | PPM loc invalid file argument 2811 | PPM loc FCBLK already in use 2812 | (XS) popped (WC) times 2813 | (WA non zero) byte size of requested FCBLK 2814 | (WA=0,xl non zero) private FCBLK ptr in xl 2815 | (WA=XL=0) no FCBLK wanted, no private FCBLK 2816 | (WC) 0/1/2 request alloc of xrblk/xnblk 2817 | /static block for use as FCBLK 2818 | (WB) destroyed 2819 | ``` 2820 | 2821 | ### SYSGC -- inform interface of garbage collections 2822 | 2823 | Provides means for interface to take special actions prior to and after a garbage collection. 2824 | 2825 | Possible usages: 2826 | 2827 | * provide visible screen icon of garbage collection in progress. 2828 | 2829 | * inform virtual memory manager to ignore page access patterns during garbage collection. 2830 | Such accesses typically destroy the page working set accumulated by the program. 2831 | 2832 | * Inform virtual memory manager that contents of memory freed by garbage collection can be discarded. 2833 | 2834 | ``` 2835 | (XR) non-zero if beginning gc 2836 | =0 if completing gc 2837 | (WA) dnamb=start of dynamic area 2838 | (WB) dnamp=next available location 2839 | (WC) dname=last available location + 1 2840 | JSR SYSGC call to sysgc function 2841 | all registers preserved 2842 | ``` 2843 | 2844 | ### SYSHS -- give access to host computer features 2845 | 2846 | Provides means for implementing special features on different host computers. The only defined entry is 2847 | that where all arguments are null in which case SYSHS *SYSHS* returns an SCBLK containing name of computer, 2848 | name of operating system and name of site separated by colons. 2849 | 2850 | The SCBLK need not have a correct first field as this is supplied on copying string to dynamic memory. 2851 | 2852 | SPITBOL does no argument checking but does provide a single error return for arguments checked as erroneous 2853 | by osint. It also provides a single execution error return. 2854 | 2855 | If these are inadequate, use may be made of the minimal error section direct as described in 2856 | minimal documentation, section 10. 2857 | 2858 | 2859 | Several non-error returns are provided. the first corresponds to the defined entry or, for implementation 2860 | defined entries, any string may be returned. the others permit respectively, return a null result, return with a 2861 | result to be stacked which is pointed at by XR, and a return causing SPITBOL statement failure. 2862 | 2863 | If a returned result is in dynamic memory it must obey garbage collector rules. 2864 | 2865 | The only results copied on return are strings returned via PPM loc3 return. 2866 | 2867 | ``` 2868 | (WA) argument 1 2869 | (XL) argument 2 2870 | (XR) argument 3 2871 | (WB) argument 4 2872 | (WC) argument 5 2873 | JSR syshs call to get host information 2874 | PPM loc1 erroneous arg 2875 | PPM loc2 execution error 2876 | PPM loc3 SCBLK pointer in xl or 0 if unavailable 2877 | PPM loc4 return a null result 2878 | PPM loc5 return result in xr 2879 | PPM loc6 cause statement failure 2880 | PPM loc7 return string at xl, length wa 2881 | PPM loc8 return copy of result in xr 2882 | ``` 2883 | 2884 | ### SYSID -- return system identification 2885 | 2886 | This routine should return strings to head the standard printer output. the first string will be 2887 | appended to a heading line of the form 2888 | 2889 | ``` 2890 | MACRO SPITBOL version v.v 2891 | ``` 2892 | 2893 | Supplied by SPITBOL itself. v.v are digits giving the major version number and generally at least a 2894 | minor version number relating to osint should be supplied to give say 2895 | 2896 | ``` 2897 | MACRO SPITBOL version v.v(m.m) 2898 | ``` 2899 | 2900 | The second string should identify at least the machine and operating system. preferably it should include 2901 | the date and time of the run. Optionally the strings may include site name of the the implementor and/or 2902 | machine on which run takes place, unique site or copy number and other information as appropriate without 2903 | making it so long as to be a nuisance to users. the first words of the SCBLKs pointed at need not be 2904 | correctly set. 2905 | 2906 | 2907 | ``` 2908 | JSR sysid call for system identification 2909 | (XR) scblk pointer for addition to header 2910 | (XL) scblk pointer for second header 2911 | ``` 2912 | 2913 | ### SYSIF -- switch to new include file 2914 | 2915 | SYSIF is used for include file processing, both to 2916 | inform the interface when a new include file is desired, and when the 2917 | end of file of an include file has been reached and it is desired to 2918 | return to reading from the previous nested file. 2919 | 2920 | It is the responsibility of SYSIF to remember the 2921 | file access path to the present input file before switching to the new 2922 | include file. 2923 | 2924 | ``` 2925 | (XL) ptr to scblk or zero 2926 | (XR) ptr to vacant scblk of length cswin 2927 | (xr not used if xl is zero) 2928 | JSR sysif call to change files 2929 | PPM loc unable to open file 2930 | (XR) scblk with full path name of file 2931 | (xr not used if input xl is zero) 2932 | ``` 2933 | 2934 | Register XL points to an SCBLK containing the name of the include file to which the interface should 2935 | switch. Data is fetched from the file upon the next call to SYSRD. 2936 | 2937 | SYSIF may have the ability to search multiple 2938 | libraries for the include file named in (XL). It is 2939 | therefore required that the full path name of the file where the file 2940 | was finally located be returned in (XR). It is this 2941 | name that is recorded along with the source statements, and will 2942 | accompany subsequent error messages. 2943 | 2944 | Register XL is zero to mark conclusion of use of an include file. 2945 | 2946 | ### SYSIL -- get input record length 2947 | 2948 | SYSIL is used to get the length of the next input 2949 | record from a file previously input associated with a 2950 | SYSIO call. The length returned is used to establish 2951 | a buffer for a subsequent SYSIN call. 2952 | SYSIL also indicates to the caller if this is a 2953 | binary or text file. 2954 | 2955 | ``` 2956 | (WA) pointer to FCBLK or zero 2957 | JSR sysil call to get record length 2958 | (WA) length or zero if file closed 2959 | (WC) zero if binary, non-zero if text 2960 | ``` 2961 | 2962 | No harm is done if the value returned is too long since unused 2963 | space will be reclaimed after the SYSIN call. 2964 | 2965 | Note that it is the SYSIL call (not the 2966 | SYSIO call) which causes the file to be opened as 2967 | required for the first record input from the file. 2968 | 2969 | ### SYSIN -- read input record 2970 | 2971 | SYSIN is used to read a record from the file 2972 | which was referenced in a prior call to SYSIL (i.e. 2973 | these calls always occur in pairs). The buffer provided is an 2974 | SCBLK for a string of length set from the 2975 | SYSIL call. If the actual length read is less than 2976 | this, the length field of the SCBLK must be modified 2977 | before returning unless buffer is right padded with zeroes. 2978 | 2979 | It is also permissible to take any of the alternative returns after 2980 | SCBLK length has been modified. 2981 | 2982 | ``` 2983 | (WA) pointer to FCBLK or zero 2984 | (XR) pointer to buffer (scblk pointer) 2985 | JSR sysin call to read record 2986 | PPM loc endfile or no i/p file after SYSXI 2987 | PPM loc return here if i/o error 2988 | PPM loc return here if record format error 2989 | (WA,WB,WC) destroyed 2990 | ``` 2991 | 2992 | ### SYSIO -- input/output file association 2993 | 2994 | See also SYSFC. 2995 | 2996 | SYSIO is called in response to a snobol4 input or 2997 | output function call except when file _arg1_ and file 2998 | _arg2_ are both null. Its call always follows immediately 2999 | after a call of SYSFC. If SYSFC 3000 | requested allocation of an FCBLK, its address will be 3001 | in WA. for input files, non-zero values of _r_ 3002 | should be copied to WC for use in allocating input 3003 | buffers. If _r_ is defaulted or not implemented, WC 3004 | should be zeroised. 3005 | 3006 | Once a file has been opened, subsequent input(),output() calls in 3007 | which the second argument is identical with that in a previous call, 3008 | merely associate the additional variable name (first argument) to the 3009 | file and do not result in re-opening the file. 3010 | 3011 | In subsequent associated accesses to the file a pointer to any 3012 | FCBLK allocated will be made available. 3013 | 3014 | ``` 3015 | (XL) file arg1 scblk pointer (2nd arg) 3016 | (XR) file arg2 scblk pointer (3rd arg) 3017 | (WA) FCBLK pointer (0 if none) 3018 | (WB) 0 for input, 3 for output 3019 | JSR SYSIO call to associate file 3020 | PPM loc return here if file does not exist 3021 | PPM loc return if input/output not allowed 3022 | (XL) FCBLK pointer (0 if none) 3023 | (WC) 0 (for default) or max record lngth 3024 | (WA,WB) destroyed 3025 | ``` 3026 | 3027 | The second error return is used if the file named exists but 3028 | input/output from the file is not allowed. For example, the standard 3029 | output file may be in this category as regards input association. 3030 | 3031 | ### SYSLD -- load external function 3032 | 3033 | SYSLD is called in response to the use of the snobol4 load 3034 | function. The named function is loaded (whatever this means), and a 3035 | pointer is returned. the pointer will be used on subsequent calls to 3036 | the function (see SYSEX). 3037 | 3038 | ``` 3039 | (XR) pointer to function name (scblk) 3040 | (XL) pointer to library name (scblk) 3041 | JSR SYSLD call to load function 3042 | PPM loc return here if func does not exist 3043 | PPM loc return here if i/o error 3044 | PPM loc return here if insufficient memory 3045 | (XR) pointer to loaded code 3046 | ``` 3047 | 3048 | The significance of the pointer returned is up to the system 3049 | interface routine. The only restriction is that if the pointer is 3050 | within dynamic storage, it must be a proper block pointer. 3051 | 3052 | ### SYSMM -- get more memory 3053 | 3054 | SYSMM is called in an attempt to allocate more 3055 | dynamic memory. This memory must be allocated contiguously with the 3056 | current dynamic data area. 3057 | 3058 | The amount allocated is up to the system to decide. any value is 3059 | acceptable including zero if allocation is impossible. 3060 | 3061 | ``` 3062 | JSR SYSMM call to get more memory 3063 | (XR) number of additional words obtained 3064 | 3065 | ``` 3066 | 3067 | ### SYSMX -- supply *mXLen* 3068 | 3069 | Because of the method of garbage collection, no SPITBOL object is 3070 | allowed to occupy more bytes of memory than the integer giving the 3071 | lowest address of dynamic (garbage collectable) memory. 3072 | *mXLen* is the name used to refer to 3073 | this maximum length of an object and for most users of most 3074 | implementations, provided dynamic memory starts at an address of at 3075 | least a few thousand words, there is no problem. 3076 | 3077 | If the default starting address is less than say 10000 or 20000, 3078 | then a load time option should be provided where a user can request 3079 | that he be able to create larger objects. This routine informs SPITBOL 3080 | of this request if any. the value returned is either an integer 3081 | representing the desired value of 3082 | *mXLen* (and hence the minimum dynamic 3083 | store address which may result in non-use of some store) or zero if a 3084 | default is acceptable in which *mXLen* 3085 | is set to the lowest address allocated to dynamic store before 3086 | compilation starts. 3087 | 3088 | If a non-zero value is returned, this is used for keyword 3089 | maXLngth. Otherwise the initial low address of 3090 | dynamic memory is used for this keyword. 3091 | 3092 | ``` 3093 | JSR SYSMX call to get mxlen 3094 | (WA) either mxlen or 0 for default 3095 | ``` 3096 | 3097 | ### SYSOU -- output record 3098 | 3099 | SYSOU is used to write a record to a file previously 3100 | associated with a SYSIO call. 3101 | 3102 | ``` 3103 | (WA) pointer to FCBLK or 0 for terminal or 1 for output 3104 | (XR) record to be written (scblk) 3105 | JSR sysou call to output record 3106 | PPM loc file full or no file after SYSXI 3107 | PPM loc return here if i/o error 3108 | (WA,WB,WC) destroyed 3109 | ``` 3110 | 3111 | Note that it is the SYSOU call (not the 3112 | SYSIO call) which causes the file to be opened as 3113 | required for the first record output to the file. 3114 | 3115 | ### SYSPI -- print on interactive channel 3116 | 3117 | If SPITBOL is run from an online terminal, osint can request that 3118 | messages such as copies of compilation errors be sent to the terminal 3119 | (see SYSPP). if relevant reply was made by 3120 | SYSPP then SYSPI is called to send 3121 | such messages to the interactive channel. SYSPI is 3122 | also used for sending output to the terminal through the special 3123 | variable name, terminal. (XR) pointer to line 3124 | buffer (SCBLK) (*wa*) line length JSR 3125 | SYSPI call to print line PPM loc failure return 3126 | (*wa*,WB) destroyed 3127 | 3128 | ### SYSPL -- provide interactive control of SPITBOL 3129 | 3130 | Provides means for interface to take special actions, such as 3131 | interrupting execution, breakpointing, stepping, and expression 3132 | evaluation. These last three options are not presently implemented by 3133 | the code calling SYSPL. 3134 | 3135 | ``` 3136 | (WA) opcode as follows- 3137 | =0 poll to allow osint to interrupt 3138 | =1 breakpoint hit 3139 | =2 completion of statement stepping 3140 | =3 expression evaluation result 3141 | (WB) statement number 3142 | r_fcb zero or pointer to head of FCBLK chain 3143 | JSR syspl call to syspl function 3144 | PPM loc user interruption 3145 | PPM loc step one statement 3146 | PPM loc evaluate expression 3147 | --- resume execution 3148 | (WA) = new polling interval 3149 | ``` 3150 | 3151 | ### SYSPP -- obtain print parameters 3152 | 3153 | SYSPP is called once during compilation to obtain 3154 | parameters required for correct printed output format and to select 3155 | other options. it may also be called again after 3156 | SYSXI when a load module is resumed. in this case the 3157 | value returned in *wa* may be less than or equal to 3158 | that returned in initial call but may not be greater. 3159 | 3160 | 3161 | the information returned is - 3162 | 3163 | 3164 | line length in chars for standard print file 3165 | 3166 | no of lines/page. 0 is preferable for a non-paged device (e.g. 3167 | online terminal) in which case listing page throws are suppressed and 3168 | page headers resulting from -title,-stitl lines are kept short. 3169 | 3170 | an initial -nolist option to suppress listing unless the program 3171 | contains an explicit -list. 3172 | 3173 | options to suppress listing of compilation and/or execution stats 3174 | (useful for established programs) - combined with 3. gives possibility 3175 | of listing file never being opened. 3176 | 3177 | option to have copies of errors sent to an interactive channel in 3178 | addition to standard printer. 3179 | 3180 | option to keep page headers short (e.g. if listing to an online 3181 | terminal). 3182 | 3183 | an option to choose extended or compact listing format. in the 3184 | former a page eject and in the latter a few line feeds precede the 3185 | printing of each of-- listing, compilation statistics, execution 3186 | output and execution statistics. 3187 | 3188 | an option to suppress execution as though a -noexecute card were 3189 | supplied. 3190 | 3191 | an option to request that name /terminal/ be pre- associated to 3192 | an online terminal via SYSPI and 3193 | SYSRI 3194 | 3195 | an intermediate (standard) listing option requiring that page 3196 | ejects occur in source listings. redundant if extended option chosen 3197 | but partially extends compact option. 3198 | 3199 | option to suppress SYSID identification. 3200 | 3201 | 3202 | ``` 3203 | 3204 | JSR syspp call to get print parameters 3205 | (WA) print line length in chars 3206 | (WB) number of lines/page 3207 | (WC) bits value ...mlkjihgfedcba where 3208 | a = 1 to send error copy to int.ch. 3209 | b = 1 means std printer is int. ch. 3210 | c = 1 for -nolist option 3211 | d = 1 to suppress compiln. stats 3212 | 3213 | e = 1 to suppress execn. stats 3214 | f = 1/0 for extnded/compact listing 3215 | g = 1 for -noexecute 3216 | h = 1 pre-associate /terminal/ 3217 | 3218 | i = 1 for standard listing option. 3219 | j = 1 suppresses listing header 3220 | k = 1 for -print 3221 | l = 1 for -noerrors 3222 | m = 1 for -case 1 3223 | ``` 3224 | 3225 | ### SYSPR -- print line on standard output file 3226 | 3227 | SYSPR is used to print a single line on the 3228 | standard output file. 3229 | 3230 | ``` 3231 | (XR) pointer to line buffer (scblk) 3232 | (WA) line length 3233 | JSR SYSPR call to print line 3234 | PPM loc too much o/p or no file after SYSXI 3235 | (WA,WB) destroyed 3236 | ``` 3237 | 3238 | The buffer pointed to is the length obtained from the 3239 | SYSPP call and is filled out with trailing blanks. 3240 | the value in *wa* is the actual line length which may 3241 | be less than the maximum line length possible. there is no space 3242 | control associated with the line, all lines are printed single spaced. 3243 | 3244 | Note that null lines (*wa*=0) are possible in which 3245 | case a blank line is to be printed. 3246 | 3247 | The error exit is used for systems which limit the amount of 3248 | printed output. 3249 | 3250 | If possible, printing should be permitted after this 3251 | condition has been signalled once to allow for dump and other 3252 | diagnostic information. assuming this to be possible, SPITBOL may 3253 | make more SYSPR calls. if the error return occurs 3254 | another time, execution is terminated by a call of 3255 | SYSEJ with ending code 998. 3256 | 3257 | ### SYSRD -- read record from standard input 3258 | file 3259 | 3260 | SYSRD is used to read a record from the standard 3261 | input file. the buffer provided is an SCBLK for a 3262 | string the length of which in characters is given in 3263 | WC, this corresponding to the maximum length of 3264 | string which SPITBOL is prepared to receive. at compile time it 3265 | corresponds to xxx in the most recent `-inxxx` card (default 72) and at 3266 | execution time to the most recent ,*r* (record length) in the third 3267 | arg of an input() statement for the standard input file (default 80). 3268 | 3269 | If fewer than (WC) characters are read, the length field of the SCBLK must be adjusted before 3270 | returning unless the buffer is right padded with zeroes. 3271 | 3272 | It is also permissible to take the alternative return after such an adjustment has been made. 3273 | 3274 | SPITBOL may continue to make calls after an endfile return so this 3275 | routine should be prepared to make repeated endfile returns. 3276 | 3277 | ``` 3278 | (XR) pointer to buffer (scblk pointer) 3279 | (WC) length of buffer in characters 3280 | JSR sysrd call to read line 3281 | PPM loc endfile or no i/p file after SYSXI 3282 | or input file name change. if 3283 | the former,scblk length is zero. 3284 | if input file name change, length 3285 | is non-zero. caller should re-issue 3286 | sysrd to obtain input record. 3287 | (WA,WB,WC) destroyed 3288 | ``` 3289 | 3290 | ### SYSRI -- read record from interactive channel 3291 | 3292 | Reads a record from online terminal for SPITBOL variable, 3293 | terminal. if online terminal is unavailable then code the endfile 3294 | return only. 3295 | 3296 | The buffer provided is of length 258 characters. 3297 | SYSRI should replace the count in the second word of 3298 | the SCBLK by the actual character count unless buffer 3299 | is right padded with zeroes. 3300 | 3301 | It is also permissible to take the alternative return after 3302 | adjusting the count. 3303 | 3304 | The end of file return may be used if this makes 3305 | sense on the target machine (e.g. if there is an 3306 | eof character.) 3307 | 3308 | ``` 3309 | (XR) pointer to 258 char buffer (scblk pointer) 3310 | JSR sysri call to read line from terminal 3311 | PPM loc end of file return 3312 | (WA,WB,WC) may be destroyed 3313 | ``` 3314 | 3315 | ### SYSRW -- rewind file 3316 | 3317 | SYSRW is used to rewind a file i.e. reposition 3318 | the file at the start before the first record. the file should be 3319 | closed and the next read or write call will open the file at the 3320 | start. 3321 | 3322 | ``` 3323 | (WA) pointer to FCBLK or zero 3324 | (XR) rewind arg scblk pointer) 3325 | JSR sysrw call to rewind file 3326 | PPM loc return here if file does not exist 3327 | PPM loc return here if rewind not allowed PPM loc return here if i / o error 3328 | ``` 3329 | 3330 | ### SYSST -- set file pointer 3331 | 3332 | SYSST is called to change the position of a file pointer. this is accomplished in a system dependent manner, 3333 | and thus the 2nd and 3rd arguments are passed unconverted. 3334 | 3335 | ``` 3336 | (WA) FCBLK pointer 3337 | (WB) 2nd argument 3338 | (WC) 3rd argument 3339 | JSR SYSST call to set file pointer 3340 | PPM loc return here if invalid 2nd arg 3341 | PPM loc return here if invalid 3rd arg 3342 | PPM loc return here if file does not exist 3343 | PPM loc return here if set not allowed 3344 | PPM loc return here if i/o error 3345 | ``` 3346 | 3347 | ### SYSTM -- get execution time so far 3348 | 3349 | SYSTM is used to obtain the amount of execution time used so far since SPITBOL was given control. 3350 | the units are described as milliseconds in the SPITBOL output, but the exact meaning is system dependent. 3351 | where appropriate, this value should relate to processor rather than clock timing values. 3352 | 3353 | If the symbol `.ctm` is defined, the units are described as deciseconds (0.1 second). 3354 | 3355 | ``` 3356 | JSR systm call to get timer value 3357 | (IA) time so far in milliseconds 3358 | (deciseconds if .ctmd defined) 3359 | ``` 3360 | 3361 | ### SYSTT -- trace toggle 3362 | 3363 | Called by SPITBOL function trace() with no args to toggle the system trace switch. this permits tracing 3364 | of labels in SPITBOL code to be turned on or off. 3365 | 3366 | ``` 3367 | JSR systt call to toggle trace switch 3368 | ``` 3369 | 3370 | ### SYSUL -- unload external function 3371 | 3372 | SYSUL is used to unload a function previously loaded with a call to SYSLD. 3373 | 3374 | ``` 3375 | (XR) pointer to control block (efblk) 3376 | JSR SYSUL call to unload function 3377 | ``` 3378 | 3379 | The function cannot be called following a SYSUL call until another SYSLD call is made for the same function. 3380 | 3381 | The EFBLK contains the function code pointer and also a pointer to the vrblk containing the function name (see 3382 | definitions and data structures section). 3383 | 3384 | ### SYSXI -- exit to produce load module 3385 | 3386 | When SYSXI is called, XL contains either a string pointer or zero. In the former case, the string gives 3387 | the character name of a program. The intention is that SPITBOL execution should be terminated forthwith 3388 | and the named program loaded and executed. 3389 | 3390 | This type of chain execution is very system dependent and implementors may choose to omit it or find 3391 | it impossible to provide. 3392 | 3393 | If _(XL)_ is zero,ia contains one of the following 3394 | integers 3395 | 3396 | ``` 3397 | -1, -2, -3, -4 3398 | Create if possible a load module containing only the impure area of memory which needs to be 3399 | loaded with a compatible pure segment for subsequent executions. Version numbers to check compatibility 3400 | should be kept in both segments and checked on loading. To assist with this check, (XR) on 3401 | entry is a pointer to an SCBLK containing the SPITBOL major version number v.v (see SYSID). The file thus 3402 | created is called a save file. 3403 | 3404 | 0 If possible, return control to job control command level. The effect if available will be system dependent. 3405 | 3406 | +1, +2, +3, +4 3407 | Create if possible a load module from all of memory. It should be possible to load and execute 3408 | this module directly. 3409 | ``` 3410 | 3411 | In the case of saved load modules, the status of open files is not preserved and implementors may choose to 3412 | offer means of attaching files before execution of load modules starts or leave it to the user to include 3413 | suitable input(), output() calls in his program. SYSXI should make a note that no i/o channels, including 3414 | standard files, have files attached so that calls of SYSIN, SYSOU, SYSPR, 3415 | 3416 | SYSRD should fail unless new associations are made for the load module. at least in the case of the 3417 | standard output file, 3418 | 3419 | It is recommended that either the user be required to attach a file or that a default file is attached, 3420 | since the problem of error messages generated by the load module is otherwise severe.As a last resort, 3421 | if SPITBOL attempts to write to the standard output file and gets a reply indicating that such ouput is 3422 | unacceptable it stops by using an entry to SYSEJ with ending code 998. As described below, passing of 3423 | some arguments makes it clear that load module will use a standard output file. 3424 | 3425 | If use is made of FCBLKs for i/o association, SPITBOL builds a chain so that those in use may be found in 3426 | SYSXI and SYSEJ. The nodes are 4 words long. The third word contains link to next node or 0, and the 3427 | fourth word contains a FCBLK pointer. 3428 | 3429 | ``` 3430 | (XL) zero or scblk pointer to first argument 3431 | (XR) pointer to v.v scblk 3432 | (IA) signed integer argument 3433 | (WA) scblk pointer to second argument 3434 | (WB) 0 or pointer to head of FCBLK chain 3435 | JSR SYSXI call to exit 3436 | PPM loc requested action not possible 3437 | PPM loc action caused irrecoverable error 3438 | (WB,WC,IA,XR,XL,CP) should be preserved over call 3439 | (WA) 0 in all cases except sucessful 3440 | performance of exit(4) or exit(-4), 3441 | in which case 1 should be returned. 3442 | ``` 3443 | 3444 | Loading and running the load module or returning from jcl command level causes execution to resume at the 3445 | point after the error returns which follow the call of SYSXI. The value passed as exit argument is used 3446 | to indicate options required on resumption of load module. 3447 | 3448 | The values +1 or -1 require that on resumption, SYSID and SYSPP be called and a heading printed on the 3449 | standard output file. 3450 | 3451 | The values +2 or -2 indicate that SYSPP will be called but not SYSID and no heading will be put 3452 | on standard output file. 3453 | 3454 | Above options have the obvious implication that a standard o/p file must be provided for the load module. 3455 | 3456 | The values +3, +4, -3 or -4 indicate calls of neither SYSID nor SYSPP and no heading will be placed on 3457 | standard output file. 3458 | 3459 | The values +4 or -4 indicate that execution is to continue after creation of the save file or load module, 3460 | although all files will be closed by the SYSXI action. This permits the user to checkpoint long-running 3461 | programs while continuing execution. 3462 | 3463 | No return from SYSXI is possible if another program is loadednd entered. 3464 | -------------------------------------------------------------------------------- /spitbol-manual-v3.7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spitbol/spitbol-docs/2d4d67144b285c8a7bf1aeb1f8fdfbb2e8afc1b1/spitbol-manual-v3.7.pdf --------------------------------------------------------------------------------