Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.
|Comment:||Added more detail about file I/O limitations to the LIBC user documentation section of the CC8 manual. (What used to be the "stdio" section is now broken up into several sections at the same level.)|
|Downloads:||Tarball | ZIP archive | SQL archive|
|Timelines:||family | ancestors | descendants | both | trunk|
|Files:||files | file ages | folders|
|User & Date:||tangent 2019-02-13 19:12:06|
|19:13||Moved the "Strings are of Words, Not of Bytes or Characters" section of the CC8 user manual up within the document to be after the "Character Set" section, where it fits better. (This wasn't really possible back when the latter section was part of the stdio section.) check-in: 7f8d8bcff5 user: tangent tags: trunk|
|19:12||Added more detail about file I/O limitations to the LIBC user documentation section of the CC8 manual. (What used to be the "stdio" section is now broken up into several sections at the same level.) check-in: 23f92ab553 user: tangent tags: trunk|
|18:52||Rewrote the "Inline Assembly in the Native CC8 Compiler" section in the CC8 user manual after learning more about its behavior and limitations. check-in: 573aba2f6a user: tangent tags: trunk|
Changes to doc/cc8-manual.md.
101 101 disable them at run time with configuration directives. If you have 102 102 a PiDP-8/I and were expecting a strict PDP-8/I simulation underneath 103 103 that pretty front panel, we’re sorry to pop your bubble, but the 104 104 fact of the matter is that a PiDP-8/I is a Family-of-8 mongrel.) 105 105 106 106 * At build time, the OS/8 FORTRAN II/SABR subsystem must be available. 107 107 108 -* At run time, any [stdio](#stdio) operation involving file I/O 108 +* At run time, any [stdio](#fiolim) operation involving file I/O 109 109 assumes it is running atop OS/8. For instance, file name arguments 110 110 to [`fopen()`](#fopen) are passed to OS/8 for interpretation. 111 111 112 112 There is likely a subset of CC8-built programs which will run 113 113 independently of OS/8, but the bounds on that class of programs is not 114 114 currently clear to us. 115 115 ................................................................................ 527 527 528 528 The ISO C Standard does not define what the `is*()` functions do when 529 529 the passed character is not representable as `unsigned char`. Since this 530 530 C compiler [does not distinguish types](#typeless), our `is*()` 531 531 functions return false for any value outside of the ASCII range, 0-127. 532 532 533 533 534 -### <a id="stdio"></a>stdio 534 +### <a id="cset"></a>Character Set 535 535 536 536 The stdio implementation currently assumes US-ASCII 7-bit text I/O. 537 537 538 538 Input characters have their upper 5 bits masked off so that only the 539 539 lower 7 bits are valid in the returned 12 bit PDP-8 word. Code using 540 540 [`fgetc`](#fgetc) cannot be used on arbitrary binary data because its 541 541 “end of file” return case is indistinguishable from reading a 0 byte. ................................................................................ 546 546 implementation. Even if you are reading your files with some other code 547 547 which is capable of handling 8-bit data, there are further difficulties 548 548 such as a lack of functions taking an explicit length, like `fwrite()`, 549 549 which makes dealing with ASCII NUL difficult. You could write a NUL to 550 550 an output file with `fputc()`, but not with `fputs()`, since NUL 551 551 terminates the output string. 552 552 553 -The stdio implementation only allows one file to be open at a time for 554 -reading and one for writing. Since there is no input buffering to speak 555 -of in the stdio implementation, there is no need to close files opened 556 -for input, there being no resources to free. Together, those two facts 557 -explain why [the `fclose()` implementation](#fclose) takes no argument: 558 -it always closes the lone output file, if any. 559 - 560 -This means that to open multiple output files, you have to `fclose` each 561 -file before calling [`fopen("FILENA.ME", "w")`](#fopen) to open the next. 562 -To open multiple input files, simply call `fopen()` to open each 563 -subsequent file, implicitly closing the prior input file. 564 - 565 -The CC8 LIBC file I/O implementation is built atop the OS/8 FORTRAN II 566 -subsystem’s file I/O functions. This has some important implications in 567 -the documentation below: 568 - 569 -1. We have not tried to “hoist” descriptions of what the FORTRAN II 570 - subsystem does up into this documentation where that documentation 571 - is correct and complete already. It may be necessary for you to read 572 - the FORTRAN II documentation in the OS/8 manual to understand how 573 - the CC8 LIBC’s stdio file I/O functions behave in certain respects. 574 - 575 -2. Programs built with CC8 which use its file I/O functions are 576 - dependent upon OS/8. 577 - 578 - 579 -#### Ctrl-C Handling 553 + 554 +### <a id="fiolim"></a>File I/O Limitations 555 + 556 +Because LIBC’s stdio implementation is built atop the OS/8 FORTRAN II 557 +library, it only allows one file to be open at a time for reading and 558 +one for writing. OS/8’s underlying limit is 5 output files and 9 input 559 +files, which appears to be an accommodation specifically for its FORTRAN 560 +IV implementation, so it is possible that a future CC8 would be 561 +retargeted at FORTRAN IV to lift this limitation, but it would be a 562 +nontrivial amount of work. 563 + 564 +Meanwhile, we generally defer to the OS/8 FORTRAN II manual where it 565 +comes to documentation of these functions behavior. The only time we 566 +bring it up in this manual is when there is either a mismatch between 567 +expected C behavior and actual FORTRAN II behavior or between the way 568 +OS/8 FORTRAN II is documented and the way things actually work when it’s 569 +being driven by CC8. 570 + 571 +This underlying base has an important implication: programs built with 572 +CC8 which use its file I/O functions are dependent upon OS/8. That 573 +underlying base determines how file names are interpreted, what devices 574 +get used, etc. 575 + 576 +Because of this single-file limitation, the stdio functions operating on 577 +files do not take a `FILE*` argument as in Standard C, there being no 578 +need to specify which file is meant. Output functions use the one and 579 +only output file, and input functions use the one and only input file. 580 +Our [`fopen()`](#fopen) doesn’t return a `FILE*` because the caller 581 +doesn’t need one to pass to any of the other functions. That leaves only 582 +[`fclose()`](#fclose), which would be an ambiguous call without a 583 +`FILE*` argument if it wasn’t for the fact that OS/8 FORTRAN II doesn’t 584 +have an `ICLOSE` library function, there apparently being no resources 585 +to free on closing an input file. 586 + 587 +All of this means that to open multiple output files, you have to 588 +`fclose` each file before calling [`fopen("FILENA.ME", "w")`](#fopen) to 589 +open the next. To open multiple input files, simply call `fopen()` to 590 +open each subsequent file, implicitly closing the prior input file. 591 + 592 + 593 +### <a id="ctrlc"></a>Ctrl-C Handling 580 594 581 595 Unlike on modern operating systems, there is nothing like `SIGINT` in 582 596 OS/8, which means Ctrl-C only kills programs that explicitly check for 583 597 it. The keyboard input loop in the CC8 LIBC standard library does do 584 598 this. 585 599 586 600 The thing to be aware of is, this won’t happen while a program is stuck ................................................................................ 595 609 596 610 597 611 ### <a id="wordstr"></a>Strings are of Words, Not of Bytes or Characters 598 612 599 613 In several places, the Standard says a conforming C library is supposed 600 614 to operate on “bytes” or “characters,” at least according to [our chosen 601 615 interpretation][cppr]. Except for the text I/O restrictions called out 602 -[above](#stdio), LIBC operates on strings of PDP-8 words, not on these 616 +[above](#cset), LIBC operates on strings of PDP-8 words, not on these 603 617 modern notions of fixed 8-bit bytes or the ever-nebulous “characters.” 604 618 605 619 Because you may be used to the idea that string and memory functions 606 620 like [`memcpy()`](#memcpy) and [`strcat()`](#strcat) will operate on 607 621 bytes, we’ve marked all of these cases with a reference back to this 608 622 section. 609 623 ................................................................................ 764 778 765 779 **Standard Violations:** 766 780 767 781 * Does not take a `FILE*` argument. (See [`fopen()`](#fopen) for 768 782 justification.) 769 783 770 784 * Always closes the last-opened *output* file, only, there being 771 - [no point](#stdio) in explicitly closing input files in this 785 + [no point](#fiolim) in explicitly closing input files in this 772 786 implementation. 773 787 774 788 [f2fio]: https://archive.org/details/bitsavers_decpdp8os8_39414792/page/n700 775 789 776 790 777 791 ### <a id="fgets"></a>`fgets(s)` 778 792 ................................................................................ 1104 1118 that terminated the loop inside each function’s implementation. 1105 1119 1106 1120 * `fputs()` detects no I/O error conditions, and thus cannot return 1107 1121 EOF to signal an error. It always returns 0, whether an error 1108 1122 occurred or not. 1109 1123 1110 1124 * `fputs()` does not take a `FILE*` as its first parameter due to the 1111 - [implicit single output file](#stdio). 1125 + [implicit single output file](#fiolim). 1112 1126 1113 1127 1114 1128 ### <a id="revcpy"></a>`revcpy(dst, src, n)` 1115 1129 1116 1130 For non-overlapping buffers, has the same effect as 1117 1131 [`memcpy()`](#memcpy), using less efficient code. 1118 1132 ................................................................................ 1723 1737 variables. 1724 1738 1725 1739 It all has to be gathered in one pass, because this 1 kWord buffer 1726 1740 is written to a text file (`CASM.TX`) at the end of the [first compiler 1727 1741 pass](#ncpass), where it waits for the final compiler pass to read it 1728 1742 back in to be inserted into the output SABR code. Since LIBC’s 1729 1743 [`fopen()`](#fopen) is limited to a [single output file at a 1730 -time](#stdio) and it cannot append to an existing file, it’s got one 1744 +time](#fiolim) and it cannot append to an existing file, it’s got one 1731 1745 shot to write everything it collected. 1732 1746 1733 1747 This is one reason the CC8 LIBC has to be cross-compiled: its inline 1734 1748 assembly is over 6× the size of this buffer. 1735 1749 1736 1750 1737 1751 #### Incompatibilities