Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From 2a11db3ffe41df6d To 1bec0d528f671d99
2017-12-09
| ||
12:12 | Assorted improvements to the CC8 README check-in: 0760dcee6b user: tangent tags: trunk | |
01:25 | Rebuilt cc8.tu56 in case the buffer overrun in txt2ptp affected its content. check-in: 2a11db3ffe user: tangent tags: trunk | |
2017-12-08
| ||
23:38 | Double size of obuf. Worst case of "need one more output buffer character space to accomodate adding \r before \n" check-in: 18fb7d3bb4 user: poetnerd tags: trunk | |
2017-10-20
| ||
00:09 | Clarified example commentary in the U/W FOCAL supplement check-in: 066aaa6b7c user: tangent tags: trunk | |
2017-10-19
| ||
21:25 | 44 Patches, all but one verified against source. The one un-verified one is for FRTS.SV, which is recommended. I just cant figure out how to build FRTS from source to verify it. mkos8 successfully applies them all. patch_list.txt names all patches, comments out non-recommended ones and says why. check-in: 1bec0d528f user: poetnerd tags: trunk | |
2017-10-18
| ||
20:41 | Reverted Unix -> DOS line ending change for src/*.in: autosetup blindly assumes Unix line endings and emits mixed line endings when *.in has DOS line endings as it passes input CRs through on lines it doesn't touch and fails to include a CR on the lines it rewrites. The symptom is that you get a confusing compiler error in gpio-common.c. check-in: 860fd189d5 user: tangent tags: trunk | |
Deleted .agignore.
|
| < < |
Changes to .fossil-settings/crlf-glob.
1 2 3 4 5 | examples/*.fc src/*.[ch] src/*.in | > > > > < < < < < | 1 2 3 4 5 6 7 8 9 10 11 | cc8/*.[ch] cc8/*.pa cc8/*.sb examples/*.fc src/*.[ch] src/*.in src/PDP8/pdp8_*.[ch] src/PDP8/pidp8i.c.in |
Deleted .ignore.
|
| < |
Changes to COPYING.md.
1 2 3 4 5 6 7 | # Licenses The PiDP-8/I software distribution is an agglomeration of software from multiple sources. Several different licenses apply to its parts. This file guides you to those individual licenses. | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | # Licenses The PiDP-8/I software distribution is an agglomeration of software from multiple sources. Several different licenses apply to its parts. This file guides you to those individual licenses. ## SIMH License Most of the files in this software distribution are released under the terms of the SIMH license, a copy of which typically appears at the top of each file it applies to. This includes not only SIMH proper but also several files written by PiDP-8/I software project contributors who chose to license their contributions under the same license. For a few files, textual inclusion of the license inside the file itself was impractical, so this license is applied by reference to [a file included with the distribution][sl]. [sl]: https://tangentsoft.com/pidp8i/doc/trunk/SIMH-LICENSE.md ## PiDP-8/I Design Files The PiDP-8/I design files in [`hardware/pidp8i`][hwp] were released under the Creative Commons [Attribution-NonCommercial-ShareAlike 4.0 International][ccl] license [on the mailing list][pdp8il] by their author, Oscar Vermeulen. [ccl]: https://creativecommons.org/licenses/by-nc-sa/4.0/ [hwp]: https://tangentsoft.com/pidp8i/dir?name=hardware/pdp8i&ci=trunk [pdp8il]: https://groups.google.com/d/msg/pidp-8/bcIH9uEB_kU/zg9uho7NDAAJ ## autosetup License The `configure` script and the contents of the `autosetup` directory are released under the FreeBSD license given in [`autosetup/LICENSE`][as]. [as]: https://tangentsoft.com/pidp8i/doc/trunk/autosetup/LICENSE ## palbart License The `palbart` program and its manual page are released under the terms of the license given in [`palbart/LICENSE.md`][pl]. [pl]: https://tangentsoft.com/pidp8i/doc/trunk/palbart/LICENSE.md ## OS/8 License The OS/8 media images included with this software distribution are released under the Digital License Agreement presented in [`media/os8/LICENSE.md`][dla]. [dla]: https://tangentsoft.com/pidp8i/doc/trunk/media/os8/LICENSE.md ## Other DEC Software The other files in the [`media`][md] and [`examples`][ed] directories that originate from Digital Equipment Corporation are believed to fall under the [public domain license][pdp8pd] DEC released all their PDP-8 software under after it stopped being ecomonmically viable. Documented releases for specific software (e.g. TSS/8) may be difficult to come by, however. [md]: https://tangentsoft.com/pidp8i/dir?ci=trunk&name=media [ed]: https://tangentsoft.com/pidp8i/dir?ci=trunk&name=examples ## ETOS License ETOS was a commercial product produced outside of DEC. No public documented declaration of license is known to be available for it, but we have [a third-hand report][el] that its creators are fine with ETOS being redistributed. [el]: http://mailman.trailing-edge.com/pipermail/simh/2017-January/016169.html |
Changes to ChangeLog.md.
1 2 | # PiDP-8/I Changes | | | > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > | | < < < < < < < < | < < < | | | | | | | > > > > > > | > > > | > > > | | < > | > > > > > > | < > > > > | < | | | | | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | # PiDP-8/I Changes ## Version 2017.10.eh? — The "Languages and Custom OS/8 Disk Packs" release * All prior versions were shipping `os8.rk05`, a "Field Service Diagnostic" OS/8 disk pack image with uncertain provenance, configuration, and modification history. We have replaced that with a script run at build time that programmatically assembles a set of clean OS/8 RK05 disk images from original DEC binary distribution DECtapes, other primary source media, and the user's chosen configuration options. This provides the following features and benefits as compared to the old `os8.rk05`: - U/W FOCAL V4E is installed on SYS: by default. Start with our [U/W FOCAL Manual Supplement for the PiDP-8/I][uwfs], then follow links from there to further information. The primary linked source is the [U/W FOCAL Manual][uwfm] by Jim van Zee (creator of U/W FOCAL) converted from scanned and OCR'd PDF form to Markdown format, which Fossil renders nicely for us on the web. This is a fascinating programming language, well worth studying! - Ian Schofield's CC8 OS/8 C compiler is installed on `SYS:` by default. Also merged in his `cc8` cross-compiler and his hand-rolled OS/8 distribution, `media/os8/cc8.rk05`. See [the CC8 `README`][cc8rm] for details. - MACREL macro assembler is installed by default. - DCP disassembler is installed by default. - John Comeau's CHECKMO-II chess program is installed by default. - By default, SIMH no longer folds lowercase input and output to uppercase. Instead, we apply patches to OS/8's command processor and its BASIC implementation to up-case input, since neither OS/8 nor BASIC can cope with lowercase input. All other programs are left to fend for themselves, which often works out fine. U/W FOCAL, Adventure, TECO, etc. all handle lowercase input to some extent, and all can emit lowercase text if given it. With the prior SIMH settting, you could not use lowercase at all. This change has been slightly controversial, so we have two alternative modes that can be selected at `configure` time: - No patches and no case-folding in SIMH. Lowercase I/O is allowed, but neither SIMH nor OS/8 nor its programs will second-guess your input, even if that means some programs will fail when given lowercase input. If you need to engage CAPS LOCK to make the program do the right thing, you are expected to be aware enough to do this. The argument in favor of this approach is that this is what a real PDP-8 system running this software would have done if sent lowercase input. - Revert to the prior releases' behavior: no patches, and SIMH does automatic case-folding for you, so you only get uppercase, even when you type lowercase text. Programs that emit lowercase text (e.g. Adventure) appear to be sending uppercase instead. This option is in fact historically accurate. Essentially, this configuration makes SIMH pretend that your terminal is only capable of uppercase text, which was very common in the PDP-8's day: the uppercase-only Teletype Model 33 ASR was the most common terminal type on PDP-8s. Our new default is historically inaccurate, but we think it the new behavior is the least likely to unpleasantly surprise end users. Pick your poison. - The `INIT.TX` message displayed by default on OS/8 boot is now more informative than the old `FIELD SERVICE PDP-8 DIAGNOSTIC SYSTEM` message. Those that do not want any boot message can disable it at configuration time. - All of the above features can be disabled if not wanted, as can several features present on the old `os8.rk05` disk: Adventure, FORTRAN IV, FORTRAN II, Kermit-12, and the BASIC game and demo programs. You can disable these features individually or you can disable all of them with the new `configure --os8-minimal` feature, which gets you a nearly bare-bones OS/8 installation with lots of spare disk space with which you can do what *you* want. - Replaced the mismatched FORTRAN compiler and runtime with matched versions from the distribution DECtapes, and ensured that Adventure runs under this version of the FORTRAN Run Time System (FRTS). At various points in the past, either FORTRAN or Adventure has been broken. - Repaired several broken BASIC programs on RKB0: by going back to primary sources. Either the `os8.rk05` disk image was corrupted at some point or it is an image of a real RK05 disk pack that was corrupted, causing several of these BASIC programs to not run properly. - The `*.MU` and music player files are left off of `RKB0:` by default, since they apparently do not cause sufficient RFI on the PiDP-8/I hardware to be picked up by normal AM radios. This saves space for things that *do* work. - No longer installing the `VTEDIT` macros for TECO by default. Although some may enjoy this alternative way of running TECO, it was decided that we should offer stock TECO by default for its historical value. If you want VTEDIT back, it can be re-enabled with a `configure` script option. - Added configure-time options to disable all of the above new features and most of the features that were present on the original `os8.rk05` disk as well. You can create a completely stripped-down OS/8 disk image, one with all features enabled, or anything in between. - In the old `os8.rk05` disk image, both `SYS:` and `DSK:` were set to `RKA0:`, which meant that to address anything on `RKB0:`, you had to specify the device path explicitly or manually change the default in OS/8 with an `ASSIGN RKB0 DSK` command or similar. In the new disk pack, programs run with the OS/8 `R` command are |
︙ | ︙ | |||
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | prior version as we found the ability to mount two tapes very helpful, particularly during the `mkos8` build process. The difference in the `RESORC` output between the versions is: Old: RKA0,RKB0,RKA1,RKB1, RXA0,RXA1,DTA0,DTA1,TTY,LPT,PTP,PTR New: RKA0,RKB0,RKA1,RKB1,RKA2,RKB2,RXA0, DTA0,DTA1,TTY,LPT,PTP,PTR This automatic OS/8 media build feature was suggested by Jonathan Trites who wrote the initial version of the script that is now called `libexec/mkos8`. That script was then extended and factored into its current form by Bill Cattey and Warren Young. Warren thinks Bill did most of the hard work in the items above. The source media used by the `mkos8` script comes from many sources and was curated for the PiDP-8/I project by Bill Cattey. See the [OS/8 media README][os8rm] for more details. See the [the top-level `README`][tlrm] for information on modifying the default OS/8 configuration. Pretty much everything above can be disabled if it's enabled by default, and vice versa. | > > > > | | | | | < > | | | < < < < < | | | | | | < < < < < < | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | | | > | < < | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | prior version as we found the ability to mount two tapes very helpful, particularly during the `mkos8` build process. The difference in the `RESORC` output between the versions is: Old: RKA0,RKB0,RKA1,RKB1, RXA0,RXA1,DTA0,DTA1,TTY,LPT,PTP,PTR New: RKA0,RKB0,RKA1,RKB1,RKA2,RKB2,RXA0, DTA0,DTA1,TTY,LPT,PTP,PTR - TODO: Added the `os8` script to add and remove features from the built OS/8 binary disk image after it is initially built. In a primitive sort of way, this is "[apt][apt] for OS/8." This automatic OS/8 media build feature was suggested by Jonathan Trites who wrote the initial version of the script that is now called `libexec/mkos8`. That script was then extended and factored into its current form by Bill Cattey and Warren Young. Warren thinks Bill did most of the hard work in the items above. The source media used by the `mkos8` script comes from many sources and was curated for the PiDP-8/I project by Bill Cattey. See the [OS/8 media README][os8rm] for more details. See the [the top-level `README`][tlrm] for information on modifying the default OS/8 configuration. Pretty much everything above can be disabled if it's enabled by default, and vice versa. * We now build an OS/8 RK05 source code disk image containing the contents of the OS/8 source distribution DECtapes for the convenience of those who would like to work with the OS/8 source code in a more convenient fashion than attaching and detaching the *ten* TU56 tape image files. files between SIMH paper tape format and plain POSIX ASCII text files. This program was written to ease the movement of FOCAL program text between SIMH and its host OS, but they should prove useful for other similar tasks. * Added a new "blinkenlights" demo program that drives SIMH from the outside, running a TECO macro under OS/8 which calculates *pi* to about 20 digits at a very slow rate, producing a display that manages to land somewhere between the random default display of [Deeper Thought][dt2vk] and the clear, boring patterns of our preexisting IF=5 demo script. This script, called `bin/teco-pi-demo`, is also included as a demonstration of how an end-user program can reuse the technology that we developed to automatically build the custom OS/8 disk images described above to achieve different ends. Perhaps you have some other program you'd like to run within SIMH in an automated fashion? This shows one way how, and demonstrates a pre-built and tested set of tools for achieving it. * Fixed the order of initialization in the GPIO setup code for the James L-W serial mod case. Fix by Dylan McNamee. * The helper program that selects which boot script to run when the PiDP-8/I boots based on the IF switch settings broke at some point in the past, apparently because it was using its own idiosyncratic GPIO handling code, and thus did not track our evolving GPIO handling methods. Now it shares the same code used by `pidp8i-sim` and `pidp8i-test`, so it works properly again. * The SysV init script that starts `pidp8i-sim` under GNU Screen on the PiDP-8/I now sets the working directory to `$prefix/share/media` on start, so relative paths given to SIMH commands (e.g. `ATTACH`) are more likely to do what you want. In prior releases, you generally had to give absolute paths to attach media and such because CWD would be set somewhere unhelpful. * Updated for Raspbian Squeeze, released in September 2017. It should still run on Raspbian Jessie, however. * Assorted portability improvements. * **TODO** * Write `PEP001.FC` and wiki article explaining it * Write `PEP001.F4` and wiki article explaining it * Write `PEP001.F2` and wiki article explaining it * Write `PEP001.C` and wiki article explaining it * Write a doc explaining how `teco-pi-demo` works, and by extension, how to use `class simh`. * Fix all Immediate, High, and Medium priority [Bugs](/bugs) * Implement all Immediate and High priority [Features](/features) [apt]: https://linux.die.net/man/8/apt [cc8rm]: https://tangentsoft.com/pidp8i/doc/trunk/cc8/README.md [dt2vk]: https://github.com/VentureKing/Deeper-Thought-2 [os8rm]: https://tangentsoft.com/pidp8i/doc/trunk/media/os8/README.md [uwfm]: https://tangentsoft.com/pidp8i/doc/trunk/doc/uwfocal-manual.md [uwfs]: https://tangentsoft.com/pidp8i/doc/trunk/doc/uwfocal-manual-supp.md ## Version 2017.04.04 |
︙ | ︙ | |||
1141 1142 1143 1144 1145 1146 1147 | In particular, the software now builds under Mac OS X, though it does not yet run properly. (The modified SimH PDP-8 simulator currently misbehaves if the PiDP-8/I panel is not present. Fixing this is on the radar.) * Fixed a bunch of bugs! | | | 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 | In particular, the software now builds under Mac OS X, though it does not yet run properly. (The modified SimH PDP-8 simulator currently misbehaves if the PiDP-8/I panel is not present. Fixing this is on the radar.) * Fixed a bunch of bugs! [tlrm]: https://tangentsoft.com/pidp8i/doc/trunk/README.md [dupatch]: https://groups.google.com/forum/#!topic/pidp-8/fmjt7AD1gIA [dudis]: https://tangentsoft.com/pidp8i/tktview?name=e06f8ae936 [wiki]: https://tangentsoft.com/pidp8i/wcontent [ex]: https://tangentsoft.com/pidp8i/doc/trunk/examples/README.md [art]: https://tangentsoft.com/pidp8i/dir?c=trunk&name=labels [tix]: https://tangentsoft.com/pidp8i/tickets |
︙ | ︙ |
Changes to HACKERS.md.
︙ | ︙ | |||
42 43 44 45 46 47 48 | $ sudo make install Fossil is also available for all common desktop platforms. One of [the official binaries][fbin] may work on your system. If you're getting binaries from a third party, be sure it is Fossil 2.1 or higher. | | | | | | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | $ sudo make install Fossil is also available for all common desktop platforms. One of [the official binaries][fbin] may work on your system. If you're getting binaries from a third party, be sure it is Fossil 2.1 or higher. [fbin]: http://fossil-scm.org/index.html/uv/download.html [dvcs]: http://en.wikipedia.org/wiki/Distributed_revision_control [fbook]: http://www.fossil-scm.org/schimpf-book/home [fml]: http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/fossil-users [fossil]: http://fossil-scm.org/ [fqsg]: http://fossil-scm.org/index.html/doc/trunk/www/quickstart.wiki [ggml]: https://groups.google.com/forum/#!forum/pidp-8 Fossil Anonymous Access ---- To clone the code repository anonymously, say: |
︙ | ︙ | |||
147 148 149 150 151 152 153 | Fossil Developer Access ---- If you have a developer account on tangentsoft.com's Fossil instance, just add your username to the URL like so: | | < < < < < < | | | | | | < | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | Fossil Developer Access ---- If you have a developer account on tangentsoft.com's Fossil instance, just add your username to the URL like so: $ fossil clone http://username@tangentsoft.com/pidp8i pidp8i.fossil Fossil will ask you for the password for `username` on the remote Fossil instance, and it will offer to remember it for you. If you let it remember the password, operation from then on is scarcely different from working with an anonymous clone, except that on checkin, your changes will be sync'd back to the repository on tangentsoft.com if you're online at the time. If you're working offline, Fossil will still do the checkin locally, and it will sync up with the central repoisitory after you get back online. It is best to work on a branch when unable to use Fossil's autosync feature, as you are less likely to have a sync conflict when attempting to send a new branch to the central server than in attempting to merge your changes to the tip of trunk into the current upstream trunk, which |
︙ | ︙ | |||
370 371 372 373 374 375 376 | Please make your patches or experimental branch bundles against the tip of the current trunk. PiDP-8/I often drifts enough during development that a patch against a stable release may not apply to the trunk cleanly otherwise. [osil]: https://opensource.org/licenses | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | Please make your patches or experimental branch bundles against the tip of the current trunk. PiDP-8/I often drifts enough during development that a patch against a stable release may not apply to the trunk cleanly otherwise. [osil]: https://opensource.org/licenses [repo]: http://tangentsoft.com/pidp8i/ [simhl]: https://tangentsoft.com/pidp8i/doc/trunk/SIMH-LICENSE.md [viral]: https://en.wikipedia.org/wiki/Viral_license The PiDP-8/I Software Project Code Style Rules ---- |
︙ | ︙ |
Changes to Makefile.in.
︙ | ︙ | |||
34 35 36 37 38 39 40 | # authorization from those authors. ######################################################################## # Git commit ID of the latest version of the SIMH 4 project on GitHub # that has been merged into this source base. SGCID=17903827bdb294f7e60d4c7f172bd6a1a71dfbd5 | < < < | | < | | < < < < < < < < < < < < < < < < < < < < < | < < < | | | < < < < | < | | | | < | | | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | # authorization from those authors. ######################################################################## # Git commit ID of the latest version of the SIMH 4 project on GitHub # that has been merged into this source base. SGCID=17903827bdb294f7e60d4c7f172bd6a1a71dfbd5 CFLAGS = @CFLAGS@ -Wno-unused-result -Wno-parentheses @BUILDMODE@ \ -DUSE_READER_THREAD -DHAVE_DLOPEN=so -DPIDP8I -DSIM_ASYNCH_IO \ -DHAVE_REGEX_H -DHAVE_GLOB -DSIM_GIT_COMMIT_ID=$(SGCID) \ -D_GNU_SOURCE -U__STRICT_ANSI__ \ -I @srcdir@/src -I @srcdir@/src/PDP8 -I src SIM = bin/pidp8i-sim BINS = bin/palbart $(SIM) bin/pidp8i-test bin/ptp2txt libexec/scanswitch @CC8_CROSS@ # lib/pidp8i/dirs.py is generated by Autosetup, so it needs different # handling than the other libraries for the out-of-tree build case. PIDP8I_DIRS = lib/pidp8i/dirs.py PIDP8I_DIN = @srcdir@/$(PIDP8I_DIRS).in SIMH_PY_SRC = @srcdir@/lib/simh.py MKOS8 = @srcdir@/libexec/mkos8 MKOS8_LIB = lib/mkos8 MKOS8_PY = \ $(MKOS8_LIB)/__init__.py \ $(MKOS8_LIB)/argparser.py MKOS8_PY_SRC = $(addprefix @srcdir@/,$(MKOS8_PY)) MKOS8_SRCS = $(MKOS8) $(MKOS8_PY_SRC) $(PIDP8I_DIN) $(SIMH_PY_SRC) BUILDDIRS = bin libexec obj/PDP8 INSTDIRS = bin etc lib/mkos8 lib/pidp8i libexec share/boot share/media share/include share/man/man1 SIM_OBJS = \ obj/gpio-common.o \ obj/PDP8/pdp8_df.o \ obj/PDP8/pdp8_cpu.o \ obj/PDP8/pdp8_clk.o \ obj/PDP8/pdp8_ct.o \ obj/PDP8/pdp8_dt.o \ obj/PDP8/pdp8_fpp.o \ |
︙ | ︙ | |||
129 130 131 132 133 134 135 | obj/sim_serial.o \ obj/sim_sock.o \ obj/sim_tape.o \ obj/sim_timer.o \ obj/sim_tmxr.o \ obj/sim_video.o | | | | | | | | | | | | | | | | < < < < < < < < < < < < < | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | obj/sim_serial.o \ obj/sim_sock.o \ obj/sim_tape.o \ obj/sim_timer.o \ obj/sim_tmxr.o \ obj/sim_video.o CC8_OBJS = \ obj/code8.o \ obj/data.o \ obj/error.o \ obj/expr.o \ obj/function.o \ obj/gen.o \ obj/io.o \ obj/lex.o \ obj/main.o \ obj/preproc.o \ obj/primary.o \ obj/stmt.o \ obj/sym.o \ obj/while.o ifeq (@BUILD_DEEPER_THOUGHT@, 1) BINS += bin/deeper endif LIBS = -lm -ldl -lpthread |
︙ | ︙ | |||
183 184 185 186 187 188 189 | BOOTSCRIPTS := $(subst obj/,boot/,$(BOOTSCRIPTS)) \ boot/1.script \ boot/5.script # List of *.in files from auto.def file, except for this present file # (Makefile.in) which is handled separately. This list should only # change when the list of "make-template" calls in auto.def changes. | | | < < < < < < < < < < < < < < < | < < < < > > > > | > > > > > | | < < < < | > | | | | < > < < | < < < | < < | < | < < < < < < | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | BOOTSCRIPTS := $(subst obj/,boot/,$(BOOTSCRIPTS)) \ boot/1.script \ boot/5.script # List of *.in files from auto.def file, except for this present file # (Makefile.in) which is handled separately. This list should only # change when the list of "make-template" calls in auto.def changes. # # If the first file listed below changes, change the AUTOREBUILD rule # near the end of this file to match! INFILES = \ @srcdir@/bin/pidp8i.in \ @srcdir@/boot/0.script.in \ @srcdir@/boot/2.script.in \ @srcdir@/boot/3.script.in \ @srcdir@/boot/4.script.in \ @srcdir@/boot/6.script.in \ @srcdir@/boot/7.script.in \ @srcdir@/boot/cc8.script.in \ @srcdir@/boot/run.script.in \ @srcdir@/etc/pidp8i-init.in \ @srcdir@/etc/sudoers.in \ @srcdir@/media/os8/init.tx.in \ @srcdir@/src/gpio-common.c.in \ @srcdir@/src/PDP8/pidp8i.c.in \ @srcdir@/tools/simh-update.in \ $(PIDP8I_DIN) PRECIOUS_INFILES = \ @srcdir@/Makefile.in \ @srcdir@/cc8/Makefile.in \ @srcdir@/examples/Makefile.in \ @srcdir@/src/Makefile.in \ @srcdir@/src/PDP8/Makefile.in OUTFILES := $(subst @srcdir@/,,$(INFILES)) OUTFILES := $(subst .in,,$(OUTFILES)) PRECIOUS_OUTFILES := $(subst @srcdir@/,,$(PRECIOUS_INFILES)) PRECIOUS_OUTFILES := $(subst .in,,$(PRECIOUS_OUTFILES)) OS8_BIN_RK05 = bin/os8v3d-bin.rk05 OS8_SRC_RK05 = @OS8_SRC_RK05@ OS8_RK05S = $(OS8_BIN_RK05) $(OS8_SRC_RK05) CLTXT = /boot/cmdline.txt .PHONY: all tags .PRECIOUS: $(PRECIOUS_OUTFILES) all: $(OUTFILES) $(PRECIOUS_OUTFILES) $(BUILDDIRS) $(BINS) $(BOOTSCRIPTS) $(LISTINGS) $(ASM_PTS) $(FC_EX_PTS) $(PAL_EX_PTS) $(OS8_RK05S) clean: @rm -f $(BINS) $(BOOTSCRIPTS) $(ASM_PTS) $(PAL_EX_PTS) $(LISTINGS) \ $(OUTFILES) $(OS8_RK05S) \ bin/*.save \ tags \ obj/*.d \ obj/*.o \ obj/*.log \ obj/PDP8/*.d \ @srcdir@/examples/*.err @-rmdir -p $(BUILDDIRS) 2> /dev/null || true distclean: clean @rm -f $(PRECIOUS_OUTFILES) \ config.log \ autosetup/jimsh0 \ src/config.h ctags tags: ctags -R @srcdir@/src @srcdir@/lib @srcdir@/libexec/mkos8 ifeq (@HAVE_PROG_CSCOPE@, 1) @cscope -bR -s@srcdir@ endif install: all instdirs @echo Installing to @prefix@... @# Install files into those dirs and set their perms for f in $(BINS) ; do @INSTALL@ -m 755 -D -s $$f @prefix@/$$f ; done ( cd @prefix@/bin ; ln -f ptp2txt txt2ptp ) @INSTALL@ -m 755 @srcdir@/bin/pidp8i @prefix@/bin @(test -x /sbin/setcap && \ for f in @prefix@/bin/pidp8i-* ; do \ /sbin/setcap 'cap_sys_nice=eip' $$f ; \ done \ ) || true test -e @MEDIADIR@/os8/os8.rk05 || $(MAKE) mediainstall @# If this is a Debian-type system, install needed helper programs @test -x /usr/bin/apt-get -a ! -h /media/usb && apt-get -y install usbmount || true @test -x /usr/bin/apt-get -a ! -x /usr/bin/screen && apt-get -y install screen || true @# Disable competing services if this is a Raspberry Pi @(test -x /bin/systemctl && /bin/systemctl disable deeper || true) @(test -x /bin/systemctl && /bin/systemctl disable pidp8 || true) @# Install the init script if this system is systemd based. @INSTALL@ -m 755 @srcdir@/etc/pidp8i-init @prefix@/etc @( test -w /etc/init.d -a -x /bin/systemctl && \ ln -sf @ABSPREFIX@/etc/pidp8i-init /etc/init.d/pidp8i && \ /bin/systemctl enable pidp8i \ ) || true @# Give the install user permission to use GPIO if done on a Pi @grep -q '^gpio:' /etc/group && usermod -a -G gpio @INSTUSR@ || true |
︙ | ︙ | |||
341 342 343 344 345 346 347 | @( test -z "@PCB_SERIAL_MOD_ANY@" -a -r $(CLTXT) && ! -w $(CLTXT) && \ cp -p $(CLTXT) "$(CLTXT)"_orig && \ sed -e 's/console\=[a-zA-Z0-9]+,[0-9]+ //' \ -e 's/kgdboc\=[a-zA-Z0-9]+,[0-9]+ //' -i $(CLTXT) \ ) || true @# Install CC8 stuff if built | | < | | | < | > | < < < | | | < | < | | | < < < < < < < < | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | @( test -z "@PCB_SERIAL_MOD_ANY@" -a -r $(CLTXT) && ! -w $(CLTXT) && \ cp -p $(CLTXT) "$(CLTXT)"_orig && \ sed -e 's/console\=[a-zA-Z0-9]+,[0-9]+ //' \ -e 's/kgdboc\=[a-zA-Z0-9]+,[0-9]+ //' -i $(CLTXT) \ ) || true @# Install CC8 stuff if built test -n "@CC8_CROSS@" && \ @INSTALL@ -m 755 bin/cc8 @prefix@/bin && \ @INSTALL@ -m 644 cc8/include/* @prefix@/share/include @# Install palbart stuff @INSTALL@ -m 755 bin/palbart @prefix@/bin @INSTALL@ -m 644 @srcdir@/palbart/palbart.1 @prefix@/share/man/man1 @# Install mkos8 and its dependencies @INSTALL@ -m 775 -g @INSTGRP@ $(MKOS8) @prefix@/libexec @( cd @srcdir@ ; \ for f in $(MKOS8_PY) ; do \ @INSTALL@ -m 644 -g @INSTGRP@ -D @srcdir@/$$f @prefix@/$$f ; \ @INSTALL@ -m 644 -g @INSTGRP@ -D @srcdir@/$${f}c @prefix@/$${f}c ; \ done \ ) @sed -e 's#^build =.*$$#build = "@ABSPREFIX@"#' \ -e 's#^src =.*$$#src = "@ABSPREFIX@"#' \ < $(PIDP8I_DIRS) > @prefix@/$(PIDP8I_DIRS) @chgrp @INSTGRP@ @prefix@/$(PIDP8I_DIRS) instdirs: for d in $(INSTDIRS) ; do @INSTALL@ -m 755 -d @prefix@/$$d ; done mediainstall: instdirs @echo "[Re]installing OS and program media..." @cd @srcdir@ ; \ find media \( \ -name \*.bin -o \ -name \*.dsk -o \ -name \*.rk05 -o \ -name \*.tu56 \ \) -exec @INSTALL@ -D -m 664 -o @INSTUSR@ -g @INSTGRP@ {} @ABSPREFIX@/share/{} \; @INSTALL@ -m 644 -o @INSTUSR@ -g @INSTGRP@ bin/os8v3d-*.rk05 @ABSPREFIX@/share/media/os8 @INSTALL@ -m 664 -o @INSTUSR@ -g @INSTGRP@ boot/*.script @BOOTDIR@ reconfig: @AUTOREMAKE@ release: all @srcdir@/tools/mkrel run: $(OS8_BIN_RK05) $(SIM) $(SIM) boot/run.script simh-update simh-update-f: @@srcdir@/tools/simh-update $(subst simh-update,,$@) test-mkos8: tools/test-mkos8 |
︙ | ︙ | |||
423 424 425 426 427 428 429 | # timestamp always changes from one run to the next. (Until computers # get fast enough to do a complete re-configure in under a second, # anyway!) The thing is, we only want the RK05 bin media rebuilt when # the configure --*-os8-* options change. *That* is when we care about # the updated init.tx file, not before. We needn't even make it an # order-only prereq because configure and the INFILES rules above ensure # that it always exists. | | < < < | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | # timestamp always changes from one run to the next. (Until computers # get fast enough to do a complete re-configure in under a second, # anyway!) The thing is, we only want the RK05 bin media rebuilt when # the configure --*-os8-* options change. *That* is when we care about # the updated init.tx file, not before. We needn't even make it an # order-only prereq because configure and the INFILES rules above ensure # that it always exists. OS8_BIN_SRCS = $(MKOS8_SRCS) \ @srcdir@/media/os8/al-*-ba-*.tu56 \ @srcdir@/media/os8/subsys/*.tu56 $(OS8_BIN_RK05): $(OS8_BIN_SRCS) | $(SIM) $(MKOS8)@MKOS8_OPTS@ bin # Also build an OS/8 source disk, as a convenience to avoid the # need to mount up the 7 source tapes in succession. # # Using an order-only dependency for the simulator and the bin disk: we # only need *a* version of each, they don't have to be recent! OS8_SRC_SRCS = $(MKOS8_SRCS) \ @srcdir@/media/os8/al-*-sa-*.tu56 $(OS8_SRC_RK05): $(OS8_SRC_SRCS) | $(SIM) $(OS8_BIN_RK05) $(MKOS8)@MKOS8_OPTS@ src # Rule for compiling *.c to *.o and autogenerating dependency info. # Explained at http://scottmcpeak.com/autodepend/autodepend.html # # Reflect any changes here into near-duplicate below! obj/%.o: @srcdir@/src/%.c $(CC) -c $(CFLAGS) @srcdir@/src/$*.c -o obj/$*.o $(CC) -MM $(CFLAGS) @srcdir@/src/$*.c > obj/$*.d @mv -f obj/$*.d obj/$*.d.tmp @sed -e 's|.*:|obj/$*.o:|' < obj/$*.d.tmp > obj/$*.d @sed -e 's/.*://' -e 's/\\$$//' < obj/$*.d.tmp | fmt -1 | \ sed -e 's/^ *//' -e 's/$$/:/' >> obj/$*.d @rm -f obj/$*.d.tmp # Near-duplicate of above rule for those *.c files generated from *.c.in # files in the srcdir. Needed when building out-of-tree. obj/%.o: src/%.c $(CC) -c $(CFLAGS) src/$*.c -o obj/$*.o $(CC) -MM $(CFLAGS) src/$*.c > obj/$*.d @mv -f obj/$*.d obj/$*.d.tmp @sed -e 's|.*:|obj/$*.o:|' < obj/$*.d.tmp > obj/$*.d @sed -e 's/.*://' -e 's/\\$$//' < obj/$*.d.tmp | fmt -1 | \ sed -e 's/^ *//' -e 's/$$/:/' >> obj/$*.d @rm -f obj/$*.d.tmp # Another near-duplicate for the PDP-8 simulator. First set above # doesn't catch these. obj/PDP8/%.o: @srcdir@/src/PDP8/%.c $(CC) -c -w $(CFLAGS) @srcdir@/src/PDP8/$*.c -o obj/PDP8/$*.o $(CC) -MM -w $(CFLAGS) @srcdir@/src/PDP8/$*.c > obj/PDP8/$*.d @mv -f obj/$*.d obj/$*.d.tmp @sed -e 's|.*:|obj/$*.o:|' < obj/$*.d.tmp > obj/$*.d @sed -e 's/.*://' -e 's/\\$$//' < obj/$*.d.tmp | fmt -1 | \ sed -e 's/^ *//' -e 's/$$/:/' >> obj/$*.d @rm -f obj/$*.d.tmp # Another near-duplicate for CC8, since it's off in a different subdir obj/%.o: @srcdir@/cc8/cross/%.c $(CC) -c -w $(CFLAGS) @srcdir@/cc8/cross/$*.c -o obj/$*.o $(CC) -MM -w $(CFLAGS) @srcdir@/cc8/cross/$*.c > obj/$*.d @mv -f obj/$*.d obj/$*.d.tmp @sed -e 's|.*:|obj/$*.o:|' < obj/$*.d.tmp > obj/$*.d @sed -e 's/.*://' -e 's/\\$$//' < obj/$*.d.tmp | fmt -1 | \ sed -e 's/^ *//' -e 's/$$/:/' >> obj/$*.d @rm -f obj/$*.d.tmp # Rule for building PAL assembly language programs in asm/*.pal. obj/%.lst bin/%-pal.pt: @srcdir@/asm/%.pal bin/palbart bin/palbart -lr $< || cat obj/$*.err mv @srcdir@/asm/$*.lst obj mv @srcdir@/asm/$*.rim bin/$*-pal.pt |
︙ | ︙ | |||
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | # Rules for making aliases of named example programs translated to boot # scripts as special numbered boot scripts boot/1.script: boot/hs-rim-loader.script ln -f $< $@ boot/5.script: boot/ac-mq-blinker.script ln -f $< $@ $(BUILDDIRS): mkdir -p $@ $(SIM): $(SIM_OBJS) obj/gpio-@LED_DRIVER_MODULE@ls.o $(CC) -o $@ $^ $(LIBS) bin/cc8: $(CC8_OBJS) $(CC) -o $@ $^ $(LIBS) | > > > > < < < < < < < < < < < < < < < < < < < < | | < < < < | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | # Rules for making aliases of named example programs translated to boot # scripts as special numbered boot scripts boot/1.script: boot/hs-rim-loader.script ln -f $< $@ boot/5.script: boot/ac-mq-blinker.script ln -f $< $@ bin/palbart: @srcdir@/palbart/palbart.c $(CC) -Wall -Wno-strict-prototypes @BUILDMODE@ $< -o $@ $(CC) -MM $< -o obj/palbart.d $(BUILDDIRS): mkdir -p $@ $(SIM): $(SIM_OBJS) obj/gpio-@LED_DRIVER_MODULE@ls.o $(CC) -o $@ $^ $(LIBS) bin/cc8: $(CC8_OBJS) $(CC) -o $@ $^ $(LIBS) bin/pidp8i-test: obj/test.o obj/gpio-nls.o obj/gpio-common.o $(CC) -o $@ $^ $(LIBS) -lncurses bin/ptp2txt: obj/ptp2txt.o $(CC) -o $@ $^ ln -f bin/ptp2txt bin/txt2ptp bin/txt2ptp: bin/ptp2txt ln -f bin/ptp2txt bin/txt2ptp bin/deeper: obj/deeper.o obj/gpio-@LED_DRIVER_MODULE@ls.o obj/gpio-common.o $(CC) -o $@ $^ $(LIBS) libexec/scanswitch: obj/scanswitch.o obj/gpio-nls.o obj/gpio-common.o $(CC) -o $@ $^ $(LIBS) # Reconfigure whenever one of the *.in or autosetup files changes unless # this is "make clean". ifeq ($(findstring clean,$(MAKECMDGOALS)),) media/os8/init.tx: $(INFILES) $(PRECIOUS_INFILES) @AUTODEPS@ @AUTOREMAKE@ && $(MAKE) endif # Rebuild simulator if the version string tool changes, since its output # may have changed. src/gpio-common.c: @srcdir@/tools/version -include $(SIM_OBJS:.o=.d) $(CC8_OBJS:.o=.d) obj/scanswitch.d |
Changes to README.md.
1 2 3 4 5 6 7 8 | # Getting Started with the PiDP-8/I Software ## Prerequisites * A Raspberry Pi with the 40-pin GPIO connector. That rules out the first-generation Raspberry Pi model A and B boards which had a 26-pin GPIO connector. | | > > > > > > | < < < < | < < < | < | < < | < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < | < < < < | < | < < | < < < < < < < < < < < < < < | | | | < < < | < | | < | < < < > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | # Getting Started with the PiDP-8/I Software ## Prerequisites * A Raspberry Pi with the 40-pin GPIO connector. That rules out the first-generation Raspberry Pi model A and B boards which had a 26-pin GPIO connector. * An SD card containing Raspbian or something sufficiently close. This software is currently tested with the Jessie Lite distribution. Ideally, you will install a fresh OS image onto an unused SD card rather than use this software to modify an existing OS installation, but there is currently no known hard incompatibilty that prevents you from integrating this software into an existing OS. * This software distribution, unpacked somewhere convenient within the Raspberry Pi filesystem. Unlike with the [upstream 2015.12.15 release][upst], this present release of the software should *not* be unpacked into `/opt/pidp8`. I recommend that you unpack it into `$HOME/src`, `/usr/local/src` or similar, but it really doesn't matter where you put it, as long as your user has full write access to that directory. * A working C compiler and other standard Linux build tools, such as `make(1)`. On Debian type systems — including Raspbian — you can install such tools with `sudo apt install build-essential` <a name="configuring"></a> ## Configuring, Building and Installing This software distribution builds and installs in the same way as most other Linux/Unix software these days. The short-and-sweet is: $ ./configure && make && sudo make install If you've checked out a new version of the source code and the `make` step fails, try redoing the `configure` step. Sometimes changes made to the source code invalidate prior `make` dependencies, which are implicitly repaired by the `configure` script. <a name="options"></a> ### Configure Script Options You can change a few things about the way the software is built and installed by giving options to the `configure` script: <a name="prefix"></a> #### --prefix Perhaps the most widely useful `configure` script option is `--prefix`, which lets you override the default installation directory, `/opt/pidp8i`. You could make it install the software under your home directory on the Pi with this command: $ ./configure --prefix=$HOME/pidp8i && sudo make install Although this is installing to a directory your user has write access to, you still need to install via `sudo` because the installation process does other things that do require `root` access. <a name="lowercase"></a> #### --lowercase The American Standards Association (predecessor to ANSI) delivered the second major version of the ASCII character encoding standard the same year the first PDP-8 came out, 1965. The big new addition? Lowercase. That bit of history means that when the PDP-8 was new, lowercase was a |
︙ | ︙ | |||
284 285 286 287 288 289 290 | getting the software to work as you expect when built in this mode, try enabling CAPS LOCK. [sa]: http://homepage.cs.uiowa.edu/~jones/pdp8/faqs/#charsets [tty]: https://tangentsoft.com/pidp8i/wiki?name=OS/8+Console+TTY+Setup | | | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | getting the software to work as you expect when built in this mode, try enabling CAPS LOCK. [sa]: http://homepage.cs.uiowa.edu/~jones/pdp8/faqs/#charsets [tty]: https://tangentsoft.com/pidp8i/wiki?name=OS/8+Console+TTY+Setup <a name="nls"></a> #### --no-lamp-simulator If you build the software on a multi-core host, the PDP-8/I simulator is normally built with the [incandescent lamp simulator][ils] feature, which drives the LEDs in a way that mimics the incandescent lamps used in the original PDP-8/I. (We call this the ILS for short.) This feature currently takes too much CPU power to run on anything but a multi-core Raspberry Pi, currently limited to the Pi 2 and Pi 3 series. If you configure the software on a single-core Pi — models A+, B+, and Zero — the simulator uses the original low-CPU-usage LED driving method instead. (a.k.a. NLS for short, named after this configuration option.) Those on a multi-core host who want this low-CPU-usage LED driving method can give the `--no-lamp-simulator` option to `configure`. This method not only uses less CPU, which may be helpful if you're trying to run a lot of background tasks on your Pi 2 or Pi 3, it can also be helpful when the CPU is [heavily throttled][thro]. <a name="serial-mod"></a> #### --serial-mod If you have done [Oscar's serial mod][sm1] to your PiDP-8/I PCB and the Raspberry Pi you have connected to it, add `--serial-mod` to the `configure` command above. If you do not give this flag at `configure` time with these hardware modifications in place, the front panel will not work correctly, and trying to run the software may even crash the Pi. If you give this flag and your PCBs are *not* modified, most of the hardware will work correctly, but several lights and switches will not work correctly. <a name="alt-serial-mod"></a> #### --alt-serial-mod This flag is for an [alternative serial mod by James L-W][sm2]. It doesn't require mods to the Pi, and the mods to the PiDP-8/I board are different from Oscar's. This flag changes the GPIO code to work with these modifications to the PiDP-8/I circuit design. |
︙ | ︙ | |||
353 354 355 356 357 358 359 | Note that this is different from `--disable-os8-cc8`, which disables the *native OS/8* C compiler. They are two different C compilers: one runs outside the SIMH PDP-8 simulator and the other runs inside the simulator under OS/8. | | | | | | | | < < < | < < | | | < < < < | < < < < < < < < < | | | | | < | | | | | | | | < < < < < > > > > | | < | < | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | Note that this is different from `--disable-os8-cc8`, which disables the *native OS/8* C compiler. They are two different C compilers: one runs outside the SIMH PDP-8 simulator and the other runs inside the simulator under OS/8. <a name="disable-os8"></a> #### --disable-os8-\* Several default components of the OS/8 RK05 disk image used by boot options IF=0 and IF=7 can be left out to save space and build time: * **--disable-os8-advent** — Leave out the Adventure game. * **--disable-os8-ba** - Leave out the BASIC games and demos which come from DEC's book "101 BASIC Computer Games." These are normally installed to `RKB0:` as `*.BA`, thus the option's name. (We considered naming it `--disable-os8-basic-games-and-demos`, but that's too long, and it can't be `--disable-os8-basic` because that implies that it is the OS/8 BASIC subsystem that is being left out, which is not even currently an option.) * **--disable-os8-chess** — Leave out John Comeau's CHECKMO-II chess implementation. * **--disable-os8-cc8** - Leave out Ian Schofield's native OS/8 CC8 compiler normally installed to `RKA0:` * **--disable-os8-crt** — Suppress the [console rubout behavior][tty] enabled while building the OS/8 binary RK05 disk image. You probably only want to do this if you have attached a real teletype to your PiDP-8/I, and thus do not want video terminal style rubout processing. * **--disable-os8-focal** - Do not install any version of FOCAL on the OS/8 system disk. This option sets `--disable-os8-uwfocal` and overrides `--enable-os8-focal69`, both discussed below. * **--disable-os8-fortran-ii** - Leave the FORTRAN II compiler out. * **--disable-os8-fortran-iv** - Leave the FORTRAN IV compiler out. * **--disable-os8-init** - Generate `SYS:INIT.TX` but do not display it on OS/8 boot. Rather than disable the default on-boot init message, you may want to edit `media/os8/init.tx.in` to taste and rebuild. * **--disable-os8-k12** - Leave out the Kermit-12 implementation normally installed to `RKA0:` * **--disable-os8-macrel** - Leave the MACREL assembler out. * **--disable-os8-src** - Do not build the `os8v3d-src.rk05` disk image from the OS/8 source tapes. This is not controlled by `--os8-minimal` because that only affects `os8v3d-bin.rk05`. * **--disable-os8-uwfocal** - Leave out the U/W FOCAL V4E programming environment normally installed to `RKA0:`. Note that the default installation only installs `UWF16K.SV`, not the rest of the files on `media/os8/subsys/uwfocal*.tu56`. There is much more to explore here, but we cannot include it in the default installation set because that would overrun OS/8's limitation on the number of files on a volume. <a name="enable-os8"></a> #### --enable-os8-\* There are a few file sets not normally installed to the OS/8 RK05 disk image used by boot options IF=0 and IF=7. You can install them with the following options: * **--enable-os8-music** — The `*.MU` files and the player program for it are not normally installed to the built OS/8 binary RK05 disk image because the Raspberry Pi reportedly does not emit eufficient RFI at AM radio frequencies when running these programs to cause audible music on a typical AM radio, the very point of these demos. Until a way is found around this problem — what, low RFI is a *problem* now? — this option will default to "off". * **--enable-os8-vtedit** — This option installs a default-run macro pack called VTEDIT which causes the OS/8 version of TECO to run in full-screen mode and to react to [several special keyboard commands](/wiki?name=Using+VTEDIT) not normally recognized by TEDO. This feature is currently disabled because it is not yet fully tested by the person in charge of the OS/8 disk building process. It may remain disabled after that because it changes the behavior of the `TECO` command in OS/8, which violates the expectations of people expecting a historically accurate TECO experience. On the other hand, people don't go to a ren fair and expect to experience the historical ubiquity of typhoid fever either, so we might change our mind on this. * **--enable-os8-focal69** — Because the default installation includes U/W FOCAL, we have chosen to leave FOCAL 69 out by default to save space on the O/S 8 system disk. You can give this option to install this implementation alongside U/W FOCAL, or you can couple this option with `--disable-os8-uwfocal` to reverse our choice of which FOCAL implementation to install by default. |
︙ | ︙ | |||
528 529 530 531 532 533 534 | #### --help Run `./configure --help` for more information on your options here. | | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | #### --help Run `./configure --help` for more information on your options here. <a name="overwrite-setup"></a> ## Overwriting the Local Simulator Setup When you run `sudo make install` step on a system that already has an existing installation, it purposely does not overwrite two classes of files: 1. **The binary PDP-8 media files**, such as the RK05 disk image that |
︙ | ︙ | |||
554 555 556 557 558 559 560 | (Gollum!) One common reason this may be the case is that you've damaged your local configuration and want to start over. Another common case is that the newer software you're installing contains changes that you want to reflect into your local configuration. You have several options here: | | | < | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | (Gollum!) One common reason this may be the case is that you've damaged your local configuration and want to start over. Another common case is that the newer software you're installing contains changes that you want to reflect into your local configuration. You have several options here: 1. If you just want to reflect upstream PDP-8 simulator configuration file changes into your local versions, you can hand-edit the installed simulator configuration scripts to match the changes in the newly-generated `boot/*.script` files under the build directory. 2. If the upstream change is to the binary PDP-8 media image files and you're unwilling to overwrite them wholesale, you'll have to mount both versions of the media image files under the PDP-8 simulator and copy the changes over by hand. 3. If your previously installed binary OS media images — e.g. the OS/8 RK05 disk image that the simulator boots from by default — are precious but the simulator configuration scripts aren't precious, you can just copy the generated `boot/*.script` files from the build directory into the installation directory, `$prefix/share/boot`. (See the `--prefix` option above for the meaning of `$prefix`.) 4. If neither your previously installed simulator configuration files nor the binary media images are precious, you can force the installation script to overwrite them both with a `sudo make mediainstall` command after `sudo make install`. Beware that this is potentially destructive! If you've made changes to your PDP-8 operating systems or have saved files to your OS system disks, this option will overwrite those changes! <a name="testing"></a> ## Testing You can test your PiDP-8/I LED and switch functions with these commands: $ sudo systemctl stop pidp8i $ pidp8i-test You may have to log out and back in before the second command will work, since the installation script modifies your normal user's `PATH` the first time you install onto a given system. It is important to stop the PiDP-8/I simulator before running the test program, since both programs need exclusive access to the LEDs and switches on the front panel. After you are done testing, you can start the PiDP-8/I simulator back up with: $ sudo systemctl start pidp8i See [its documentation][test] for more details. <a name="using"></a> ## Using the Software For the most part, this software distribution works like the upstream [2015.12.15 distribution][usd]. Its [documentation][prj] therefore describes this software too, for the most part. The largest user-visible difference between the two software distributions is that all of the shell commands affecting the software were renamed to include `pidp8i` in their name: 1. To start the simulator: |
︙ | ︙ | |||
736 737 738 739 740 741 742 | what else you can do with the simulator command language, or read the [SIMH Users' Guide][sdoc]. 5. To shut the simulator down from the Raspbian command line: $ sudo systemctl stop pidp8i | | | > | | | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | what else you can do with the simulator command language, or read the [SIMH Users' Guide][sdoc]. 5. To shut the simulator down from the Raspbian command line: $ sudo systemctl stop pidp8i There are [other major differences][mdif] between the upstream distribution and this one. See that linked wiki article for details. ## License Copyright © 2016-2017 by Warren Young. This document is licensed under the terms of [the SIMH license][sl]. [prj]: https://tangentsoft.com/pidp8i/ [upst]: http://obsolescence.wixsite.com/obsolescence/pidp-8 [sm1]: http://obsolescence.wixsite.com/obsolescence/2016-pidp-8-building-instructions [sm2]: https://groups.google.com/d/msg/pidp-8/-leCRMKqI1Q/Dy5RiELIFAAJ [usd]: http://obsolescence.wixsite.com/obsolescence/pidp-8-details [dt2]: https://github.com/VentureKing/Deeper-Thought-2 [sdoc]: https://tangentsoft.com/pidp8i/uv/doc/simh/main.pdf [prj]: http://obsolescence.wixsite.com/obsolescence/pidp-8 [test]: https://tangentsoft.com/pidp8i/doc/trunk/doc/pidp8i-test.md [thro]: https://tangentsoft.com/pidp8i/doc/trunk/README-throttle.md [mdif]: https://tangentsoft.com/pidp8i/wiki?name=Major+Differences [sl]: https://tangentsoft.com/pidp8i/doc/trunk/SIMH-LICENSE.md [ils]: https://tangentsoft.com/pidp8i/wiki?name=Incandescent+Lamp+Simulator |
Changes to RELEASE-PROCESS.md.
1 2 3 4 5 | # PiDP-8/I Software Release Process This documents the process for producing release versions of the software. | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 | # PiDP-8/I Software Release Process This documents the process for producing release versions of the software. ## Update ChangeLog.md Trawl the Fossil timeline for user-visible changes since the last release, and write them up in user-focused form into the `ChangeLog.md` file. If a regular user of the software cannot see a given change, it shouldn't go in the `ChangeLog.md`; let it be documented via the |
︙ | ︙ |
Changes to auto.def.
︙ | ︙ | |||
29 30 31 32 33 34 35 | # authorization from those authors. ######################################################################## define defaultprefix /opt/pidp8i use cc use cc-lib | < < < < < < < < | | | | | | | | | | | < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | # authorization from those authors. ######################################################################## define defaultprefix /opt/pidp8i use cc use cc-lib options { alt-serial-mod => "use GPIO drive scheme suitable for James L-W's serial mod method" cc8-cross=1 => "do not build the cc8 cross-compiler on the host" debug-mode => "create a debug build (default is release)" lowercase: => "select how lowercase input is to be handled" no-lamp-simulator => "use simple LED driver instead of incandescent lamp simulator" os8-advent=1 => "add the game of ADVENT to built OS/8 RK05 image" os8-ba=1 => "leave *.BA BASIC games and demos off built OS/8 RK05 disk image" os8-cc8=1 => "leave the native OS/8 CC8 compiler off the built OS/8 RK05 disk image" os8-crt=1 => "set CRT-style rubout processing in built OS/8 KR05 image" os8-chess=1 => "leave the CHECKMO-II game of chess off built OS/8 RK05 image" os8-dcp=1 => "install DCP Disassembler executables to built OS/8 RK05 image" os8-focal=1 => "leave FOCAL 69 and U/W FOCAL off the built OS/8 RK05 image" os8-focal69 => "add FOCAL 69 to the built OS/8 RK05 image" os8-fortran-ii=1 => "leave FORTRAN II off the built OS/8 RK05 image" os8-fortran-iv=1 => "leave FORTRAN IV off the built OS/8 RK05 image" os8-init=1 => "suppress the OS/8 INIT message on boot: start with a bare . prompt" os8-k12=1 => "leave 12-bit Kermit off built OS/8 RK05 disk image" os8-macrel=1 => "leave MACREL assembler off the build OS/8 RK05 image" os8-minimal => "disable all --enable-os8-* options, giving minimal OS/8 bin disk" os8-music => "add *.MU files to built OS/8 RK05 disk image" os8-src=1 => "don't build os8v3d-src.rk05 from OS/8 source tapes" os8-uwfocal=1 => "leave U/W FOCAL (only) off the built OS/8 RK05 image" os8-vtedit => "add the TECO VTEDIT setup to built OS/8 RK05 image" serial-mod => "use GPIO drive scheme suitable for Oscar Vermeulen's serial mod method" throttle: => "override the throttle values in the boot scripts" } if {[opt-bool alt-serial-mod]} { msg-result "GPIO drive adjusted for James L-W's serial mods to the PiDP-8/I PCB." define PCB_SERIAL_MOD_JLW define PCB_SERIAL_MOD_ANY } if {[opt-bool serial-mod]} { |
︙ | ︙ | |||
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | if {[opt-bool debug-mode]} { msg-result "Creating a debuggable build." define BUILDMODE {-O0 -g} } else { msg-result "Creating a release build." define BUILDMODE {-O2} } set lv [opt-val lowercase] if {$lv == ""} { set lv "auto" } if {$lv == "auto"} { define SIMH_PASS_LOWERCASE } elseif {$lv == "pass"} { define SIMH_PASS_LOWERCASE append mkos8_opts " --disable-lcmod" } elseif {$lv == "upper"} { append mkos8_opts " --disable-lcmod" } else { user-error "Legal values for --lowercase are {auto,pass,upper}." } msg-result "Lowercase handling set to '$lv' mode." | > > > > > > > > > > > | | | > > > | > > > > > > > > | > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | if {[opt-bool debug-mode]} { msg-result "Creating a debuggable build." define BUILDMODE {-O0 -g} } else { msg-result "Creating a release build." define BUILDMODE {-O2} } set mkos8_opts "" set lv [opt-val lowercase] if {$lv == ""} { set lv "auto" } if {$lv == "auto"} { define SIMH_PASS_LOWERCASE } elseif {$lv == "pass"} { define SIMH_PASS_LOWERCASE append mkos8_opts " --disable-lcmod" } elseif {$lv == "upper"} { append mkos8_opts " --disable-lcmod" } else { user-error "Legal values for --lowercase are {auto,pass,upper}." } msg-result "Lowercase handling set to '$lv' mode." set os8min [opt-bool os8-minimal] if {$os8min || ![opt-bool os8-advent]} { msg-result "Will not add game of ADVENT to the OS/8 RK05 disk image." append mkos8_opts " --disable-advent" } if {$os8min || ![opt-bool os8-ba]} { msg-result "Will not add BASIC games and demos to the OS/8 RK05 disk image." append mkos8_opts " --disable-ba" } if {$os8min || ![opt-bool os8-cc8]} { msg-result "Will not add CC8 to the OS/8 RK05 disk image." append mkos8_opts " --disable-cc8" } if {$os8min || ![opt-bool os8-chess]} { msg-result "Will not add game of CHESS to the OS/8 RK05 disk image." append mkos8_opts " --disable-chess" } if {$os8min || ![opt-bool os8-crt]} { msg-result "Will not add BASIC games and demos to the OS/8 RK05 disk image." append mkos8_opts " --disable-crt" } if {$os8min || ![opt-bool os8-dcp]} { msg-result "Will not add DCP disassembler to the OS/8 RK05 disk image." append mkos8_opts " --disable-dcp" } if {$os8min || ![opt-bool os8-focal]} { msg-result "Will not add FOCAL 69 or U/W FOCAL to the OS/8 RK05 disk image." append mkos8_opts " --disable-focal" } elseif {[opt-bool os8-focal69] && ![opt-bool os8-uwfocal]} { msg-result "Adding FOCAL 69 to the OS/8 RK05 disk image instead of U/W FOCAL." append mkos8_opts " --enable-focal69 --disable-uwfocal" } elseif {[opt-bool os8-focal69] && [opt-bool os8-uwfocal]} { msg-result "Adding both FOCAL 69 and U/W FOCAL to the OS/8 RK05 disk image." append mkos8_opts " --enable-focal69" ;# default --enable-uwfocal } else { msg-result "Adding U/W FOCAL to the OS/8 RK05 disk image instead of FOCAL 69." } if {$os8min || ![opt-bool os8-fortran-ii]} { msg-result "Will not add FORTRAN II compiler to the OS/8 RK05 disk image." append mkos8_opts " --disable-fortran-ii" } if {$os8min || ![opt-bool os8-fortran-iv]} { msg-result "Will not add FORTRAN IV compiler to the OS/8 RK05 disk image." append mkos8_opts " --disable-fortran-iv" } if {$os8min || ![opt-bool os8-k12]} { msg-result "Will not add Kermit-12 to the OS/8 RK05 disk image." append mkos8_opts " --disable-k12" } if {$os8min || ![opt-bool os8-macrel]} { msg-result "Will not add MACREL assembler to the OS/8 RK05 disk image." append mkos8_opts " --disable-macrel" } if {!$os8min && [opt-bool os8-music]} { msg-result "Will add music files to the OS/8 RK05 disk image." append mkos8_opts " --enable-music" } else { msg-result "Will not add music files to the OS/8 RK05 disk image." } if {!$os8min && [opt-bool os8-vtedit]} { msg-result "Will add VTEDIT setup to the OS/8 RK05 disk image." append mkos8_opts " --enable-vtedit" } if {$os8min || ![opt-bool os8-init]} { msg-result "Suppressing the INIT message on OS/8 boot." append mkos8_opts " --disable-init" } if {[opt-bool os8-src]} { msg-result "Building os8v3d-src.rk05 from OS/8 source tapes." define OS8_SRC_RK05 bin/os8v3d-src.rk05 } else { msg-result "Will not build os8v3d-src.rk05 from OS/8 source tapes." define OS8_SRC_RK05 {} } define MKOS8_OPTS $mkos8_opts # Force a rebuild of the OS/8 media if the option set changed. if {![file exists "obj"]} { file mkdir "obj" } write-if-changed "obj/mkos8.opts" $mkos8_opts { file delete -force bin/os8v3d-bin.rk05 msg-result "mkos8 options changed; will rebuild OS/8 disk images." |
︙ | ︙ | |||
298 299 300 301 302 303 304 305 306 307 308 309 310 311 | } else { user-error "No install(1) type program found; install GNU Coreutils." } msg-result "Found GNU install(1) program as [get-define INSTALL]." # If we have cscope here, we'll use it in the "tags" target define HAVE_PROG_CSCOPE [cc-check-progs cscope] # Remember the name and primary group of the user who installed this, since # we want to give that group write privileges to some files when they're # installed, and we want them to own the screen(1) session. set instgrp [exec id -grn] set instusr [exec id -urn] if {$instusr == "root"} { | > > > > > | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | } else { user-error "No install(1) type program found; install GNU Coreutils." } msg-result "Found GNU install(1) program as [get-define INSTALL]." # If we have cscope here, we'll use it in the "tags" target define HAVE_PROG_CSCOPE [cc-check-progs cscope] # Canonicalize some paths which may be relative and generate others from them define ABSPREFIX [file-normalize [get-define prefix]] define BOOTDIR "[get-define ABSPREFIX]/share/boot" define MEDIADIR "[get-define ABSPREFIX]/share/media" # Remember the name and primary group of the user who installed this, since # we want to give that group write privileges to some files when they're # installed, and we want them to own the screen(1) session. set instgrp [exec id -grn] set instusr [exec id -urn] if {$instusr == "root"} { |
︙ | ︙ | |||
342 343 344 345 346 347 348 | # mask a real problem that needs to be diagnosed. set tool "tools/version" set cmd "$srcdir/$tool" set status [catch {exec $cmd} version] if {$status != 0} { # The most likely cause for tools/version to fail is that the repo # file has become disassociated from the local checkout directory. | | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | # mask a real problem that needs to be diagnosed. set tool "tools/version" set cmd "$srcdir/$tool" set status [catch {exec $cmd} version] if {$status != 0} { # The most likely cause for tools/version to fail is that the repo # file has become disassociated from the local checkout directory. set sql "select value from vvar where name=\"repository\"" set cmd "fossil sql --no-repository $srcdir/.fslckout '$sql'" set status [catch {exec /bin/sh -c $cmd} path] if {$status != 0} { user-error "Fossil doesn't seem to work here. Is it installed?\nCMD: $cmd" } elseif {[file exists $path]} { user-error "$tool failed to get checkout version from $path" } else { |
︙ | ︙ | |||
397 398 399 400 401 402 403 | # Build Deeper Thought if we find it here if {[file exists "[get-define srcdir]/src/deeper.c"]} { set ls [string toupper "[get-define LED_DRIVER_MODULE]ls"] msg-result "Found Deeper Thought; building it against $ls GPIO module" define BUILD_DEEPER_THOUGHT 1 } | < < < < < < < < < < < < < < > > < < < | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | # Build Deeper Thought if we find it here if {[file exists "[get-define srcdir]/src/deeper.c"]} { set ls [string toupper "[get-define LED_DRIVER_MODULE]ls"] msg-result "Found Deeper Thought; building it against $ls GPIO module" define BUILD_DEEPER_THOUGHT 1 } # Write outputs. # # NOTE: If you change the list of files here, change INFILES in # Makefile.in, too. make-config-header src/config.h \ -auto {ENABLE_* HAVE_* PACKAGE_* SIZEOF_*} \ -bare {ILS_MODE PCB_*} make-template Makefile.in make-template bin/pidp8i.in make-template boot/0.script.in make-template boot/2.script.in make-template boot/3.script.in make-template boot/4.script.in make-template boot/6.script.in make-template boot/7.script.in make-template boot/cc8.script.in make-template boot/run.script.in make-template cc8/Makefile.in make-template etc/pidp8i-init.in make-template etc/sudoers.in make-template examples/Makefile.in make-template lib/pidp8i/__init__.py.in make-template lib/pidp8i/dirs.py.in make-template media/os8/init.tx.in make-template src/Makefile.in make-template src/gpio-common.c.in make-template src/PDP8/Makefile.in make-template src/PDP8/pidp8i.c.in make-template tools/simh-update.in exec chmod +x "$builddir/tools/simh-update" |
Changes to autosetup/autosetup.
︙ | ︙ | |||
73 74 75 76 77 78 79 | # options is a list of known options set autosetup(options) {} # optset is a dictionary of option values set by the user based on getopt set autosetup(optset) {} # optdefault is a dictionary of default values for options set autosetup(optdefault) {} set autosetup(optionhelp) {} | < | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | # options is a list of known options set autosetup(options) {} # optset is a dictionary of option values set by the user based on getopt set autosetup(optset) {} # optdefault is a dictionary of default values for options set autosetup(optdefault) {} set autosetup(optionhelp) {} set autosetup(showhelp) 0 # Parse options use getopt # At the is point we don't know what is a valid option # We simply parse anything that looks like an option |
︙ | ︙ | |||
393 394 395 396 397 398 399 | #string match \n* $desc if {$header ne ""} { lappend autosetup(optionhelp) $header "" set header "" } # A multi-line description lappend autosetup(optionhelp) $opthelp $desc | < | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | #string match \n* $desc if {$header ne ""} { lappend autosetup(optionhelp) $header "" set header "" } # A multi-line description lappend autosetup(optionhelp) $opthelp $desc incr i 2 } } } # @module-options optionlist # |
︙ | ︙ |
Deleted bin/.agignore.
|
| < < |
Deleted bin/.ignore.
|
| < |
Changes to bin/teco-pi-demo.
︙ | ︙ | |||
32 33 34 35 36 37 38 | # authorization from those authors. ######################################################################## # Bring in just the basics so we can bring in our local modules import os import sys sys.path.insert (0, os.path.dirname (__file__) + '/../lib') | < < < < | < < | < < < < < < < < < < | < < | | < < < < < < < < < < < < < < < < < < | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # authorization from those authors. ######################################################################## # Bring in just the basics so we can bring in our local modules import os import sys sys.path.insert (0, os.path.dirname (__file__) + '/../lib') # Other core modules we need import time # Our local modules from pidp8i import * from simh import * #### main ############################################################## def main (): # Start TECO in the simulator s = simh (dirs.build) s.set_logfile (os.fdopen (sys.stdout.fileno (), 'w', 0)) s.send_cmd ("att rk0 bin/os8v3d-bin.rk05") s.send_cmd ("boot rk0") s.os8_send_cmd ('\.', "R TECO") # The macro we'll send: http://www.iwriteiam.nl/HaPi_TECO_macro.html macro = [ 'GZ0J\UNQN"E 40UN \' BUH BUV HK', 'QN< J BUQ QN*10/3UI', 'QI< \+2*10+(QQ*QI)UA B L K QI*2-1UJ QA/QJUQ', 'QA-(QQ*QJ)-2\ 10@I// -1%I >', 'QQ/10UT QH+QT+48UW QW-58"E 48UW %V \' QV"N QV^T \' QWUV QQ-(QT*10)UH >', 'QV^T @^A/', '/HKEX', ] |
︙ | ︙ | |||
115 116 117 118 119 120 121 | # Send last line of macro sans CR, followed by two Esc characters to # start it running. s.os8_send_str (last) # not os8_send_line! s.os8_send_ctrl ('[') s.os8_send_ctrl ('[') | < < < < < < < < < < < < < < < < < < < < < < < < | | < | | | < < < < < < < < < < < < < < < < < < < < < < | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | # Send last line of macro sans CR, followed by two Esc characters to # start it running. s.os8_send_str (last) # not os8_send_line! s.os8_send_ctrl ('[') s.os8_send_ctrl ('[') # Let macro run for a bit, then pop out to SIMH and throttle it down # to a rate suitable for a blinkenlights demo and let it go. time.sleep (0.1) s.os8_send_ctrl ('e') s.send_cmd ('set throttle 1/17') s.send_cmd ('cont') s.spin () # never exits if __name__ == "__main__": main() |
Changes to boot/0.script.in.
︙ | ︙ | |||
37 38 39 40 41 42 43 | @else ; The software was configured with --lowercase=upper, meaning the user ; wants lowercase text to be forced to uppercase. This is bidirectional, ; affecting both input to the simulated PDP-8 and output from it. set tti ksr @endif | | | 37 38 39 40 41 42 43 44 45 | @else ; The software was configured with --lowercase=upper, meaning the user ; wants lowercase text to be forced to uppercase. This is bidirectional, ; affecting both input to the simulated PDP-8 and output from it. set tti ksr @endif att rk0 @MEDIADIR@/os8/os8v3d-bin.rk05 boot rk0 |
Added boot/cc8.script.in.
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ; This script initializes a populated OS/8 environment on an ; RK05 cartridge disk pack. That's 10 whole megabytes, so big ; the OS requires that you split it into two partitions in order ; to address the whole disk! These are: ; ; SYS: which conyains all of the OS/8 system files and CC8 ; DSK: which contains all of the user files ; reset echo Loading the CC8 OS/8 environment from the RK05 cartridge disk... set tti 7b set cpu 32k set cpu noidle @SET_THROTTLE@ att rk0 @MEDIADIR@/os8/cc8.rk05 boot rk0 |
Changes to boot/run.script.in.
︙ | ︙ | |||
11 12 13 14 15 16 17 | @if SIMH_PASS_LOWERCASE set tti 7b @else set tti ksr @endif | | | 11 12 13 14 15 16 17 18 19 | @if SIMH_PASS_LOWERCASE set tti 7b @else set tti ksr @endif att rk0 bin/os8v3d-bin.rk05 boot rk0 |
Added cc8/Makefile.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | ######################################################################## # Makefile.in - Processed by autosetup's configure script to generate # an intermediate GNU make(1) file for building the PiDP-8/I software # from within its cc8/ subdirectory. # # The resulting Makefile will redirect simple "make" calls to the top # level as well as the major top-level targets (e.g. "make clean") but # purposefully will not redirect anything like an installation or "run # the system" type target. Its only purpose is to help out those who # are working on CC8 from within this directory. If you need to work # on the wider system, do it from the project's top level. # # If you are seeing this at the top of a file called Makefile and you # intend to make edits, do that in Makefile.in. Saying "make" will then # re-build Makefile from that modified Makefile.in before proceeding to # do the "make" operation. # # Copyright © 2017 Warren Young # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS LISTED ABOVE BE LIABLE FOR ANY CLAIM, # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT # OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the names of the authors above # shall not be used in advertising or otherwise to promote the sale, # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## all clean ctags distclean tags reconfig: cd @builddir@; make $@ |
Added cc8/README.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | # A Minimal Implementation of C for the DEC PDP-8 Processor ## Introduction The C language and its derivatives are now the industry standard for the development of operating systems and utilities. The language has evolved significantly since its initial specification in 1972. At this time, the PDP-7 was used for the initial implementation and the compiler ported to a number of other systems including the PDP-11. Also, the first glimmerings of Unix appeared following a re-write of the assembly language version in C and the rest is of course history. The PDP-8 was introduced by DEC in 1965 at the same time as the PDP-7 with the intention of being a small and cheap processor that could be used in a variety of environments. From this simple machine, the modern desktop device has evolved which I am using to type this document. Nonetheless, far from fading into obscurity, there is a very active group of enthusiasts who have looked to implementing the PDP-8 on modern hardware and the thanks to Oscar Vermuelen and others, we can all have a PDP8/I to play with. With this in mind, I thought it was time to have a modern language compiler running on the PDP-8 which as far as I can tell, the last native compiler developed for the PDP-8 was Pascal in 1979 by Heinz Stegbauer. In more recent times, one cross-compiler has been developed by Vince Slyngstad and updated by Paolo Maffei based on Ron Cain’s Small C using a VM approach. [This code][sms] is most certainly worth examining, and I am delighted to acknowledge this work as I have used some of the C library code in this project. [sms]: http://so-much-stuff.com/pdp8/C/C.php Finally, I would refer the reader to Fabrice Bellard’s OTCC. It is this bit of remarkable software that suggested that there may be a chance to implement a native PDP-8 compiler. Developing a native compiler for the PDP-8 is not an easy task as this processor has a very limited address space and no hardware stack. And, although the option exists to write the whole thing in assembly language as has been the case for Pascal and Algol, this project has explored the option of writing the compiler itself in C. To this end, 2 compilers have been written. Firstly, a cross-compiler based again on Ron Cain’s Small-C which is used to compile the native OS/8 compiler and library. As yet, the native compiler has rather limited functionality and will not compile itself. The cross-compiler will compile itself but produces an enormous (28K) assembler file which cannot be run on the PDP-8. # The Cross-Compiler The code for this is in the `cross` subdirectory, and is built along with the top-level PiDP-8/I software. As above, this is based upon Ron Cain’s Small-C compiler, and the reader is directed to the extensive documentation available on the web. The key file is the code generator section in `code8.c`. This is used to generate SABR (Symbolic Assembler for Binary Relocatable programmes) assembly output which is normally used as the second pass of the OS/8 FORTRAN II system. You use this cross-compiler to compile the 3 components of the OS/8 C compiler: 1. `n8.c` → `n8.s`: The parser/tokeniser section of the compiler 2. `p8.c` → `p8.s`: The token to SABR code converter section. 3. `libc.c` → `libc.s`: The C library used by both of the above via the `libc.h` include file. When you build and run this cross-compiler on a POSIX type system such as the Raspbian PiDP-8/I environment, the resulting `*.s` files will have LF-only line endings. You may need to run these files through a `unix2dos` type utility in order to produce the CRLF line endings that OS/8's SABR assembler expects, depending on how you get those `*.s` files into OS/8 as `*.SB`. The `*.SB` files may be assembled under OS/8: .COMP N8.SB .COMP LIBC.SB .COMP P8.SB This will create the `*.RL` files for the linking loader (`LOADER.SV`). The cross-compiler has some non-standard features to enable the interface between the main programme and the C library. This constitutes a compile time linkage system to allow for standard and vararg functions to be called in the library. The 3 SABR files generated from the source files as above may then be separately downloaded, compiled, loaded and linked under OS/8. Each of these SABR files generates just less than 4K of relocatable code as `N8.RL`, `P8.RL` and `LIBC.RL`. These are linked in pairs under OS/8 to create the 2 native OS/8 compiler phases: Phase 1: Link `N8.RL` and `LIBC.RL` to be saved as `CC1.SV` Phase 2: Link `P8.RL` and `LIBC.RL` to be saved as `CC2.SV` The commands are as follows, with `$` being an Escape keypress: .R LOADER *N8,LIBC/I$ .SAVE SYS CC1 .R LOADER P8,LIBC/I/O$ .SAVE SYS CC2 N8 (`CC1.SV`) terminates by chaining to `CC2.SV` to complete the process of generating a final SABR file. Several of the C programs in this distribution reference a PAL assembly initialization routine `cc8/include/init.pa`, which is symlinked into each directory that uses it. It defines some low-level subroutines, initializes the environment for the programs, and calls into the LIBC initialization code. If you are going to compile these programs with the OS/8 native compiler, you will need to copy `init.pa` into the OS/8 environment as well. The same goes for `cc8/include/libc.h`, which defines the mappings between the familiar C library routine names and their underlying implementation names. The linking loader determines the core layout of each of the pairs of `.RL` files as above. Typically this is as follows: **Field 0:** FOTRAN library utility functions and OS/8 I/O system **Field 1:** Reserved for the programme’s runtime stack/globals/literals. **Field 2:** Usually the primary programme ... either N8 or P8. **Field 3:** Usually the LIBC library. In all, each phase of the native OS/8 compiler will use 16K of core. ## The Native Compiler This compiler is built and linked as above. The final two files generated are `CC1.SV` and `CC2.SV`. These should be on the OS/8 system device. (`SYS:`) The compiler expects the source file in C to be in `CC.CC` on the default user device. (`DSK:`) In addition, you will need to file `HEADER.SB` on the default user device. This is used by `CC2.SV`. I suggest you use the provided RK05 image as this has the `SYS:` and `DSK:` partitions configured as required and include a linked copy of the compiler and some example programs. To try it out: Boot OS/8 from the included RK05 image with: $ bin/pidp8i-sim boot/cc8.script Note that this is a different version of OS/8 than the one currently distributed in the IF=0, IF=3, and IF=7 positions in the PiDP-8/I boot scheme. It is version V3Q (up from V3D) and it is configured to smash lowercase input to uppercase only in the OS/8 command processor. Lowercase input in the text editor will be saved as lowercase. With this special CC8 OS/8 environment running, you can enter a C programme in lower case via the editor. Before getting into the text editor, try building a copy of one of the example programs: .COPY CC.CC<PS.CC Run with: .R CC1 Then: .COMP CC.SB Then: .R LOADER *CC,LIBC/G And hope for the best!!!! ## GOVERNMENT HEALTH WARNING **You are hereby warned**: the native OS/8 compiler does not contain any error checking whatsoever. If the source files contain an error, you will either receive a compile time warning while compiling the CC.SB file or a runtime crash. Any error will not give you any hint as to the cause. It is worth noting that GCC uses some 100’s of K for error checking. The app has only 3K to create a token list from CC.CC that could run directly in a suitable VM. If your programme does not work, check it carefully or test it with gcc in the sure knowledge that you would need a roomful of magnetic core memory to do this! The native OS/8 compiler implements a very limited version of C which is nonetheless Turing complete. You could see it more as a simple scripting system. It is actually typeless in that everything is a 12 bit integer and any variable/array can interpreted as `int`, `char` or pointer. However, all variables, functions and arrays must be declared `int`. 1. There must be an `int main()` which appears as the last function. 2. Arrays and variables may be local or global (implied static). 3. Arrays may only be single indexed. See `PS.CC` for an example. 4. Do not attempt to scope variables within a function. e.g. `for (int i=...` 5. The only allowed digraphs are `++`, `--` (postfix only) and `==`. 6. Comparison operators compare signed. Result is boolean true = -1. 7. The `&`, ¦ and `!` operators are bitwise. 8. See `libc.h` for allowed libc functions. There are 31. 9. `atoi` is non-standard: `int atoi(char *,int *)`, returning the length of the numeric string. 10. `fopen` is implemented as `void fopen(char *filename, char *mode)`. The filename must be upper case. Mode is either "w" or "r". * Only 1 input file and 1 output may be open at any one time * `fclose()` only closes the output file. * Call `fopen` to open a new input file. The current file does not need to be closed. * `fprintf`, `fputc`, and `fputs` are as expected. * `fgets` is implemented. It will read and retain CR/LF. It returns a null string on EOF. * `fscanf` is not implemented. Read a line with `fgets()` and then call `sscanf` on it. * `feof` is not implemented; `fgetc` and `fgets` will return a null on EOF. 11. `scanf` is not implemented; use `gets` then `sscanf` 12. `printf` is as expected. See `libc.c` for the allowed format specifiers: `%d`, `%s` etc. Length and width.precision formatting is supported. 13. Pointers are as expected. Do not try `*(<expr>)`. This does not work. 14. `struct` is not supported. 15. Double precision `int`, `float` etc. are not supported. If you need to do heavy duty maths, use Fortran. 16. The stack, which includes all globals and literals, is only 4k. Stack overflow is not detected. 17. Recursion is implemented. See `FIB.CC`. 18. Literals have to be included in the 4K limit programme area. These are copied into the stack at run time. This is due to the fact that ‘COMMON’ storage cannot be initialised. 19. There is no option for `#include` files. The available Libc functions are implicitly declared and listed in `libc.h` and `p8.c`. As a result, there is no arglist checking. Examine `libc.c` for details. ## OS/8 Specifics 1. I strongly suggest you limit I/O to text files. 2. Don’t forget to handle form feed. See `c8.c` 3. For some obscure reason, always open the input file first, then the output file. I suspect a fault in `libc.c`. Examine the code!!!! (Every trick in the book.) ## Preprocessor The compiler distribution includes a pre-processor file (`c8.c` → `CC0.SV`). This is a stub and merely asks for a filename and calls the compiler chain. This file may be extended and used to process `#define` `#include`, etc. Compile using the cross-compiler to `c8.s`, copy to `C8.SB` under OS/8 on your PDP-8 target system, then: .COMP C8.SB .R LOADER *C8,LIBC/I/O$ .SAVE SYS CC0 .R CC0 > enter filename and press Return .COMP CC.SB .R LOADER *CC,LIBC/G if no file I/O; or... *CC,LIBC/I/O/G ...if using file I/O Try the examples in `*.CC` on `DSK:`. I personally like `PS.CC`, Pascal’s triangle. This version does not require factorials, which are a bit out of range for 12 bits!! Try it with: .R CC0 >PS.CC .COMP CC.SB .R LOADER *CC,LIBC/G ## Conclusion This is a somewhat limited manual which attempts to give an outline of a very simple compiler for which I apologise as the source code is obscure and badly commented. However, the native OS/8 compiler/tokeniser (`n8.c`) is only 600 lines which is a nothing in the scale of things these days. However, I hope this project gives some insight into compiler design and code generation strategies to target a most remarkable computer. I would also like to give credit to the builders of OS/8 and in particular the FORTRAN II system which was never designed to survive the onslaught of this kind of modern software. Don’t expect too much! This compiler will not build this week’s bleeding edge kernel. But, it may be used to build any number of useful utility programs for OS/8. ## License This document is under the [GNU GPLv3 License][gpl], copyright © May and June 2017 by [Ian Schofield][ian], with minor updates by [Warren Young][wy] in July 2017. [gpl]: https://www.gnu.org/licenses/gpl.html [ian]: mailto:Isysxp@gmail.com [wy]: https://tangentsoft.com/ |
Added cc8/cross/README.md.
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | This directory contains the sources for the CC8 cross-compiler, which is based on Ron Cain's Small-C system. It is built by the top-level build system as `bin/cc8` and is installed to `$prefix/bin/cc8`. Call it as: cc8 myfile.c The compiler does not have any consequential command line options. The output file is `myfile.s` which is in SABR assembly code, intended to be assembled within the PiDP-8/I OS/8 environment. See the `test` subdirectory and [the top-level README][/doc/trunk/cc8/README.md] for further details. |
Added cc8/cross/code8.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | /* File code8080.c: 2.2 (84/08/31,10:05:09) */ /*% cc -O -c % * */ #define unix #include <stdio.h> #include "defs.h" #include "data.h" #include <string.h> /* Define ASNM and LDNM to the names of the assembler and linker respectively */ /* * Some predefinitions: * * INTSIZE is the size of an integer in the target machine * BYTEOFF is the offset of an byte within an integer on the * target machine. (ie: 8080,pdp11 = 0, 6809 = 1, * 360 = 3) * This compiler assumes that an integer is the SAME length as * a pointer - in fact, the compiler uses INTSIZE for both. */ #define INTSIZE 1 #define BYTEOFF 0 /* * print all assembler info before any code is generated * */ header () { outstr ("/ Small C PDP8 Coder (1.0:27/1/99)"); nl(); FEvers(); nl (); ol ("OPDEF ANDI 0400"); ol ("OPDEF TADI 1400"); ol ("OPDEF ISZI 2400"); ol ("OPDEF DCAI 3400"); ol ("OPDEF JMSI 4400"); ol ("OPDEF JMPI 5400"); ol ("OPDEF MQL 7421"); ol ("OPDEF MQA 7701"); ol ("OPDEF MQO 7501"); ol ("OPDEF SWP 7521"); ol ("OPDEF CDF1 6211"); ol ("OPDEF CDF0 6201"); ol ("OPDEF RIF 6224"); ol ("OPDEF CAF0 6203"); ol ("OPDEF BSW 7002"); ol ("OPDEF CAM 7621"); ol ("/"); } nl () { outbyte (EOL); /* outbyte (10); */ } initmac() { defmac("cpm\t1"); defmac("I8080\t1"); defmac("RMAC\t1"); defmac("smallc\t1"); } galign(t) int t; { return(t); } /* * return size of an integer */ intsize() { return(INTSIZE); } /* * return offset of ls byte within word * (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3) */ byteoff() { return(BYTEOFF); } /* * Output internal generated label prefix */ olprfix() { ot("CC"); } /* * Output a label definition terminator */ col () { outbyte (','); } /* * begin a comment line for the assembler * */ comment () { outbyte ('/'); } /* * Emit user label prefix */ prefix () { } /* Stkbase output stack base->literals =stkp+2 ... ie 202(8) =130(10) + sizeof(globals) */ stkbase() { ot("GBL"); } /* * print any assembler stuff needed after all code * */ trailer () { // ot("\tENTRY "); // outbyte('M'); // printlabel (litlab); // nl(); outbyte('M'); printlabel (litlab); col(); ot("\t0"); nl(); ol("\tCDF1"); ot("\tTAD L"); printlabel (litlab); nl(); ol ("\tSNA CLA / Any literals to push?"); ot ("\tJMP I M"); printlabel (litlab); nl(); ot("\tTAD X"); printlabel (litlab); nl(); ol ("\tDCA JLC"); outbyte('D'); printlabel (litlab); col(); ol("CDF0"); ot("\tTADI JLC"); nl(); ol ("\tJMSI PSH"); ol ("\tCLA"); ol ("\tISZ JLC"); ot("\tISZ L"); printlabel (litlab); nl(); ot("\tJMP D"); printlabel (litlab); nl(); ot ("\tJMP I M"); printlabel (litlab); nl(); ol("CCEND,\t0"); ol ("END"); } /* * function prologue */ prologue (sym) char *sym; { } /* * text (code) segment */ gtext () { /* ol ("cseg"); */ } /* * data segment */ gdata () { /* ol ("dseg"); */ } /* * Output the variable symbol at scptr as an extrn or a public */ ppubext(scptr) char *scptr; { if (scptr[STORAGE] == STATIC) return 0; // ot (scptr[STORAGE] == EXTERN ? "extrn\t" : "public\t"); // prefix (); // outstr (scptr); // nl(); } /* * Output the function symbol at scptr as an extrn or a public */ fpubext(scptr) char *scptr; { /* if (scptr[STORAGE] == STATIC) return; // ot (scptr[OFFSET] == FUNCTION ? "public\t" : "extrn\t"); // prefix (); // outstr (scptr); // nl (); */ } /* * Output a decimal number to the assembler file */ onum(num) int num; { outdec(num); /* pdp11 needs a "." here */ } /* * fetch a static memory cell into the primary register getmem (sym) char *sym; { int adr; ol ("\tCLA"); immd3 (); adr=glint(sym)+128; onum(glint(sym)+128); nl(); ol("\tDCA JLC"); ol("\tTADI JLC"); }*/ getmem (sym) char *sym; { int adr; ol ("\tCLA"); immd4 (); adr=glint(sym)+128; onum(glint(sym)+128); nl(); } /* * fetch a static memory cell into the primary register (pre-increment*/ getincmem (sym) char *sym; { int adr; ol ("\tCLA"); adr=glint(sym)+128; ot ("\tISZI ("); onum(adr); nl(); immd4 (); onum(adr); nl(); } /* * fetch the address of the specified symbol into the primary register * */ getloc (sym) char *sym; { ol("\tCLA"); ol("\tTAD STKP"); if (sym[STORAGE] == LSTATIC) { immd3 (); printlabel(-1-glint(sym)); nl(); } else { if (stkp-glint(sym)==0) outstr("/"); immd3 (); outdec (stkp-glint(sym)); nl (); } } /* * store the primary register into the specified static memory cell * putmem (sym) char *sym; { ol("\tMQL"); immd3 (); onum(glint(sym)+128); nl(); ol("\tDCA JLC"); ol("\tMQA"); ol("\tDCAI JLC"); ol("\tTADI JLC"); } */ putmem (sym) char *sym; { ot("\tDCAI ("); onum(glint(sym)+128); nl(); immd4 (); onum(glint(sym)+128); nl(); } /* * store the specified object type in the primary register * at the address on the top of the stack * */ putstk (typeobj) char typeobj; { ol("\tJMSI PTSK"); stkp = stkp + INTSIZE; } /* * fetch the specified object type indirect through the primary * register into the primary register * */ indirect (typeobj) char typeobj; { ol("\tDCA JLC"); /* ol("\tCDF1"); */ ol("\tTADI JLC"); } /* * fetch the specified object type indirect through the primary * register into the primary register (pre-increment) * */ incdirect (typeobj) char typeobj; { ol("\tDCA JLC"); ol("\tISZI JLC"); ol("\tTADI JLC"); } /* * swap the primary and secondary registers * */ swap () { ol ("\tSWP"); } /* * Clear primary reg */ cpri() { ol("\tCLA"); } /* * print partial instruction to get an immediate value into * the primary register * */ immed () { ol ("\tCLA"); ot ("\tTAD ("); } immd2 () { ol ("\tCLA"); ot ("\tTAD "); } immd3 () { ot ("\tTAD ("); } immd4 () { ot("\tTADI ("); } /* * push the primary register onto the stack * */ gpush () { ol ("\tJMSI PSH"); stkp = stkp - INTSIZE; } /* * pop the top of the stack into the secondary register * */ gpop () { ol ("\tJMSI POP"); stkp = stkp + INTSIZE; } /* * swap the primary register and the top of the stack * */ swapstk () { ol ("\tMQL"); gpop(); ol ("\tSWP"); gpush(); ol ("\tSWP"); } /* * call the specified subroutine name * varag is allowed for libc functions using a v prefix. In this case, the arg count+1 is pushed onto the stack as well. * For the actual routine, the declaration should be a single arg eg printf(int args) in this case, the value of args is the count and &args-args point to the first arg in the caller's list. */ gcall (sname,nargs) char *sname; int *nargs; { char tm[10]; if (strstr(sname,"vlibc")) { immed(); sname++; outdec(*nargs); outstr("\t/ PUSH ARG COUNT"); nl(); ol("\tJMSI PSH"); stkp = stkp - INTSIZE; (*nargs)++; } if (strstr(sname,"libc")) { strcpy(tm,sname); immed(); outstr(tm+4); nl(); ol("\tMQL"); ol("\tCALL 1,LIBC"); ol("\tARG STKP"); ol("\tCDF1"); /* Make sure DF is correct */ return 0; } ol("\tCPAGE 2"); ol("\tJMSI PCAL"); ot ("\t"); outstr (sname); nl (); } stri() { ol("\tDCAI 10"); } iinit() { ol("\tCIA;CMA"); ol("\tDCA 10"); } /* * return from subroutine * */ gret (sym) char *sym; { ol ("\tJMPI POPR"); } /* * perform subroutine call to value on top of stack * */ callstk () { immed (); outstr ("$+5"); nl (); swapstk (); ol ("pchl"); stkp = stkp + INTSIZE; } /* * jump to specified internal label number * */ jump (label) int label; { ot ("\tJMP\t"); printlabel (label); nl (); } /* * test the primary register and jump if false to label * */ testjump (label, ft) int label, ft; { if (ft) ol ("\tSZA"); else ol ("\tSNA"); jump (label); } casejump() { ol("\tTAD TMP"); ol("\tSNA CLA"); } /* * print pseudo-op to define a byte * */ defbyte () { ot ("\t"); } /* * print pseudo-op to define storage * */ defstorage () { ot ("COMMN\t"); } /* * print pseudo-op to define a word * */ defword () { ot ("\t"); } /* * modify the stack pointer to the new value indicated * */ modstk (newstkp) int newstkp; { int k; k = galign(stkp-newstkp); if (k == 0) return (newstkp); if (k>0 && k<5) { while (k--) ol ("\tISZ STKP"); return (newstkp); } ol ("\tMQL"); immd3 (); outdec (k); nl (); ol ("\tTAD STKP"); ol ("\tDCA STKP"); swap (); return (newstkp); } /* * multiply the primary register by INTSIZE */ gaslint () { } /* * divide the primary register by INTSIZE */ gasrint() { } /* * Case jump instruction */ gjcase() { ol ("\tCIA"); ol ("\tDCA TMP"); } /* * add the primary and secondary registers * if lval2 is int pointer and lval is not, scale lval */ gadd (lval,lval2) int *lval,*lval2; { /* if (lval==0) ol("\tCIA");*/ ol("\tDCA JLC"); ol("\tJMSI POP"); ol("\tMQA"); ol("\tTAD JLC"); stkp = stkp + INTSIZE; } /* * subtract the primary register from the secondary * */ gsub () { ol("\tCIA"); ol("\tDCA JLC"); ol("\tJMSI POP"); ol("\tMQA"); ol("\tTAD JLC"); stkp = stkp + INTSIZE; } /* * multiply the primary and secondary registers * (result in primary) * */ gmult () { ol("\tDCA JLC"); ol("\tJMSI POP"); ol("\tMQA"); ol("\tCALL 1,MPY"); ol("\tARG JLC"); ol("\tCDF1"); stkp = stkp + INTSIZE; } /* * divide the secondary register by the primary * (quotient in primary, remainder in secondary) * */ gdiv () { ol("\tDCA JLC"); ol("\tJMSI POP"); ol("\tMQA"); ol("\tCALL 1,DIV"); ol("\tARG JLC"); ol("\tCDF1"); stkp = stkp + INTSIZE; } /* * compute the remainder (mod) of the secondary register * divided by the primary register * (remainder in primary, quotient in secondary) * */ gmod () { ol("\tDCA JLC"); ol("\tJMSI POP"); ol("\tMQA"); ol("\tCALL 1,DIV"); ol("\tARG JLC"); ol("\tCALL 1,IREM"); ol("\tARG 0"); ol("\tCDF1"); stkp = stkp + INTSIZE; } /* * inclusive 'or' the primary and secondary registers * */ gor () { ol("\tJMSI POP"); ol("\tMQA"); stkp = stkp + INTSIZE; } /* * exclusive 'or' the primary and secondary registers * */ gxor () { gpop(); gcall ("?xor"); } /* * 'and' the primary and secondary registers * */ gand () { ol("\tDCA JLC"); ol("\tJMSI POP"); ol("\tMQA"); ol("\tAND JLC"); stkp = stkp + INTSIZE; } /* * arithmetic shift right the secondary register the number of * times in the primary register * (results in primary register) * */ gasr () { int lbl; lbl=getlabel(); ol("\tCIA"); ol("\tJMSI POP"); gnlabel(lbl); ol("\tSWP"); ol("\tCLL RAR"); ol("\tSWP"); ol("\tIAC"); ol("\tSZA"); jump(lbl); ol("\tSWP"); stkp = stkp + INTSIZE; } /* * arithmetic shift left the secondary register the number of * times in the primary register * (results in primary register) * */ gasl () { int lbl; lbl=getlabel(); ol("\tCIA"); ol("\tJMSI POP"); gnlabel(lbl); ol("\tSWP"); ol("\tCLL RAL"); ol("\tSWP"); ol("\tIAC"); ol("\tSZA"); jump(lbl); ol("\tSWP"); stkp = stkp + INTSIZE; } /* * two's complement of primary register * */ gneg () { ol("\tCIA"); } /* * logical complement of primary register * */ glneg () { ol("\tSNA CLA"); ol("\tCMA"); } /* * one's complement of primary register * */ gcom () { ol("\tCMA"); } /* * Convert primary value into logical value (0 if 0, 1 otherwise) * */ gbool () { ol("\tSZA CLA"); ol("\tIAC"); } /* * increment the primary register by 1 if char, INTSIZE if * int */ ginc (lval) int lval[]; { ol ("\tIAC"); /* if (lval[2] == CINT) // ol ("inx\th"); */ } /* * Shortened INC */ gisz (lval) int *lval; { int adr; char *sym=lval[0]; if (lval[1]) { ol ("\tISZI JLC"); return 0; } ot ("\tISZI ("); adr=stkp-glint(sym); // if (lval[STORAGE] == PUBLIC) adr=glint(sym)+128; onum(adr); nl(); } /* * decrement the primary register by one if char, INTSIZE if * int */ gdec (lval) int lval[]; { ol ("\tTAD (-1"); /* if (lval[2] == CINT) // ol("dcx\th"); */ } /* * following are the conditional operators. * they compare the secondary register against the primary register * and put a literl 1 in the primary if the condition is true, * otherwise they clear the primary register * */ /* * equal * */ geq () { ol("\tCIA"); ol("\tTADI STKP"); gpop(); ol("\tSNA CLA"); ol("\tCMA"); } /* * not equal * */ gne () { gpop(); ol("\tCIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); } /* * less than (signed) * */ glt () { gpop(); ol("\tCIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); ol("\tAND (2048"); } /* * less than or equal (signed) * */ gle () { gpop(); ol("\tCIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); ol("\tSNA"); ol("\tCLA CMA"); ol("\tAND (2048"); } /* * greater than (signed) * */ ggt () { gpop(); ol("\tSWP"); ol("\tCIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); ol("\tAND (2048"); } /* * greater than or equal (signed) * */ gge () { gpop(); ol("\tSWP"); ol("\tCIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); ol("\tSNA"); ol("\tCLA CMA"); ol("\tAND (2048"); } /* * less than (unsigned) * */ gult () { gpop(); ol("\tCLL CIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); ol("\tSNL CLA"); ol("\tIAC"); } /* * less than or equal (unsigned) * */ gule () { gpop(); ol("\tCLL CIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); ol("\tSNL CLA"); ol("\tIAC"); } /* * greater than (unsigned) * */ gugt () { gpop(); ol("\tCLL CIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); ol("\tSNA SZL CLA"); ol("\tIAC"); } /* * greater than or equal (unsigned) * */ guge () { gpop(); ol("\tSWP"); ol("\tCLL CIA"); ol("\tDCA JLC"); ol("\tMQA"); ol("\tTAD JLC"); ol("\tSNL CLA"); ol("\tIAC"); } inclib() { #ifdef cpm return("B:"); #endif #ifdef unix return(""); #endif } /* Squirrel away argument count in a register that modstk doesn't touch. */ gnargs(d) int d; { /* ot ("mvi\ta,"); // onum(d); // nl (); */ } assemble(s) char *s; { #ifdef ASNM char buf[100]; strcpy(buf, ASNM); strcat(buf, " "); strcat(buf, s); buf[strlen(buf)-1] = 's'; return(system(buf)); #else return(0); #endif } link() { #ifdef LDNM fputs("I don't know how to link files yet\n", stderr); #else return(0); #endif } |
Added cc8/cross/ctype.h.
> | 1 | /* Nothing needed in this file */ |
Added cc8/cross/data.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /* File data.c: 2.2 (84/11/27,16:26:13) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" /* storage words */ char symtab[SYMTBSZ]; char *glbptr, *rglbptr, *locptr; int ws[WSTABSZ]; int *wsptr; int swstcase[SWSTSZ]; int swstlab[SWSTSZ]; int swstp; char litq[LITABSZ]; int litptr; char macq[MACQSIZE]; int macptr; char line[LINESIZE]; char mline[LINESIZE]; int lptr, mptr, gsize; /* miscellaneous storage */ int nxtlab, litlab, stkp, argstk, ncmp, errcnt, glbflag, ctext, cmode, lastst, inbreak; FILE *input, *input2, *output; FILE *inclstk[INCLSIZ]; int inclsp; char fname[20]; FILE *bfile; char quote[2]; unsigned char *cptr; int *iptr; int fexitlab; int iflevel, skiplevel; int errfile; int sflag; int cflag; int errs; int aflag; |
Added cc8/cross/data.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* File data.h: 2.2 (84/11/27,16:26:11) */ /* storage words */ extern char symtab[]; extern char *glbptr, *rglbptr, *locptr; extern int ws[]; extern int *wsptr; extern int swstcase[]; extern int swstlab[]; extern int swstp; extern char litq[]; extern int litptr; extern char macq[]; extern int macptr; extern char line[]; extern char mline[]; extern int lptr, mptr, gsize; /* miscellaneous storage */ extern int nxtlab, litlab, stkp, argstk, ncmp, errcnt, glbflag, ctext, cmode, lastst, inbreak; extern FILE *input, *input2, *output, *bfile; extern FILE *inclstk[]; extern int inclsp; extern char fname[]; extern char quote[]; extern char *cptr; extern int *iptr; extern int fexitlab; extern int iflevel, skiplevel; extern int errfile; extern int sflag; extern int cflag; extern int errs; extern int aflag; |
Added cc8/cross/defs.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | /* File defs.h: 2.1 (83/03/21,02:07:20) */ #define FOREVER for(;;) #define FALSE 0 #define TRUE 1 #define NO 0 #define YES 1 /* miscellaneous */ #define EOS 0 #define EOL 10 #define BKSP 8 #define CR 13 #define FFEED 12 #define TAB 9 /* symbol table parameters */ #define SYMSIZ 14 #define SYMTBSZ 2800 #define NUMGLBS 150 #define STARTGLB symtab #define ENDGLB (STARTGLB+NUMGLBS*SYMSIZ) #define STARTLOC (ENDGLB+SYMSIZ) #define ENDLOC (symtab+SYMTBSZ-SYMSIZ) /* symbol table entry format */ #define NAME 0 #define IDENT 9 #define TYPE 10 #define STORAGE 11 #define OFFSET 12 /* system-wide name size (for symbols) */ #define NAMESIZE 20 #define NAMEMAX 20 /* possible entries for "ident" */ #define VARIABLE 1 #define ARRAY 2 #define POINTER 3 #define FUNCTION 4 /* possible entries for "type" */ #define CCHAR 1 #define CINT 2 /* possible entries for storage */ #define PUBLIC 1 #define AUTO 2 #define EXTERN 3 #define STATIC 4 #define LSTATIC 5 #define DEFAUTO 6 /* "do"/"for"/"while"/"switch" statement stack */ #define WSTABSZ 100 #define WSSIZ 7 #define WSMAX ws+WSTABSZ-WSSIZ /* entry offsets in "do"/"for"/"while"/"switch" stack */ #define WSSYM 0 #define WSSP 1 #define WSTYP 2 #define WSCASEP 3 #define WSTEST 3 #define WSINCR 4 #define WSDEF 4 #define WSBODY 5 #define WSTAB 5 #define WSEXIT 6 /* possible entries for "wstyp" */ #define WSWHILE 0 #define WSFOR 1 #define WSDO 2 #define WSSWITCH 3 /* "switch" label stack */ #define SWSTSZ 100 /* literal pool */ #define LITABSZ 2000 #define LITMAX LITABSZ-1 /* input line */ #define LINESIZE 200 #define LINEMAX (LINESIZE-1) #define MPMAX LINEMAX /* macro (define) pool */ #define MACQSIZE 1000 #define MACMAX (MACQSIZE-1) /* "include" stack */ #define INCLSIZ 3 /* statement types (tokens) */ #define STIF 1 #define STWHILE 2 #define STRETURN 3 #define STBREAK 4 #define STCONT 5 #define STASM 6 #define STEXP 7 #define STDO 8 #define STFOR 9 #define STSWITCH 10 #define DEFLIB inclib() |
Added cc8/cross/error.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /* File error.c: 2.1 (83/03/20,16:02:00) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" error (ptr) char ptr[]; { FILE *tempfile; tempfile = output; output = stdout; doerror(ptr); output = tempfile; doerror(ptr); errcnt++; } doerror(ptr) char *ptr; { int k; comment (); outstr (line); nl (); comment (); k = 0; while (k < lptr) { if (line[k] == 9) tab (); else outbyte (' '); k++; } outbyte ('^'); nl (); comment (); outstr ("****** "); outstr (ptr); outstr (" ******"); nl (); } |
Added cc8/cross/expr.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 | /* File expr.c: 2.2 (83/06/21,11:24:26) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * lval[0] - symbol table address, else 0 for constant * lval[1] - type indirect object to fetch, else 0 for static object * lval[2] - type pointer or array, else 0 */ expression (comma) int comma; { int lval[3]; do { if (heir1 (lval)) rvalue (lval); if (!comma) return 0; } while (match (",")); } heir1 (lval) int lval[]; { int k, lval2[3]; char fc; k = heir1a (lval); if (match ("=")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); if (heir1 (lval2)) rvalue (lval2); store (lval); return (0); } else { fc = ch(); if (match ("-=") || match ("+=") || match ("*=") || match ("/=") || match ("%=") || match (">>=") || match ("<<=") || match ("&=") || match ("^=") || match ("|=")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gpush (); if (heir1 (lval2)) rvalue (lval2); switch (fc) { case '-': { if (dbltest(lval,lval2)) gaslint(); gsub(); result (lval, lval2); break; } case '+': { if (dbltest(lval,lval2)) gaslint(); gadd (lval,lval2); result(lval,lval2); break; } case '*': gmult (); break; case '/': gdiv (); break; case '%': gmod (); break; case '>': gasr (); break; case '<': gasl (); break; case '&': gand (); break; case '^': gxor (); break; case '|': gor (); break; } store (lval); return (0); } else return (k); } } heir1a (lval) int lval[]; { int k, lval2[3], lab1, lab2; k = heir1b (lval); blanks (); if (ch () != '?') return (k); if (k) rvalue (lval); FOREVER if (match ("?")) { testjump (lab1 = getlabel (), FALSE); if (heir1b (lval2)) rvalue (lval2); jump (lab2 = getlabel ()); printlabel (lab1); col (); nl (); blanks (); if (!match (":")) { error ("missing colon"); return (0); } if (heir1b (lval2)) rvalue (lval2); printlabel (lab2); col (); nl (); } else return (0); } heir1b (lval) int lval[]; { int k, lval2[3], lab; k = heir1c (lval); blanks (); if (!sstreq ("||")) return (k); if (k) rvalue (lval); FOREVER if (match ("||")) { testjump (lab = getlabel (), TRUE); if (heir1c (lval2)) rvalue (lval2); printlabel (lab); col (); nl (); gbool(); } else return (0); } heir1c (lval) int lval[]; { int k, lval2[3], lab; k = heir2 (lval); blanks (); if (!sstreq ("&&")) return (k); if (k) rvalue (lval); FOREVER if (match ("&&")) { testjump (lab = getlabel (), FALSE); if (heir2 (lval2)) rvalue (lval2); printlabel (lab); col (); nl (); gbool(); } else return (0); } heir2 (lval) int lval[]; { int k, lval2[3]; k = heir3 (lval); blanks (); if ((ch() != '|') | (nch() == '|') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '|') & (nch() != '|') & (nch() != '=')) { inbyte (); gpush (); if (heir3 (lval2)) rvalue (lval2); gor (); blanks(); } else return (0); } } heir3 (lval) int lval[]; { int k, lval2[3]; k = heir4 (lval); blanks (); if ((ch () != '^') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '^') & (nch() != '=')){ inbyte (); gpush (); if (heir4 (lval2)) rvalue (lval2); gxor (); blanks(); } else return (0); } } heir4 (lval) int lval[]; { int k, lval2[3]; k = heir5 (lval); blanks (); if ((ch() != '&') | (nch() == '|') | (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if ((ch() == '&') & (nch() != '&') & (nch() != '=')) { inbyte (); gpush (); if (heir5 (lval2)) rvalue (lval2); gand (); blanks(); } else return (0); } } heir5 (lval) int lval[]; { int k, lval2[3]; k = heir6 (lval); blanks (); if (!sstreq ("==") & !sstreq ("!=")) return (k); if (k) rvalue (lval); FOREVER { if (match ("==")) { gpush (); if (heir6 (lval2)) rvalue (lval2); geq (); } else if (match ("!=")) { gpush (); if (heir6 (lval2)) rvalue (lval2); gne (); } else return (0); } } heir6 (lval) int lval[]; { int k, lval2[3]; k = heir7 (lval); blanks (); if (!sstreq ("<") && !sstreq ("<=") && !sstreq (">=") && !sstreq (">")) return (k); if (sstreq ("<<") || sstreq (">>")) return (k); if (k) rvalue (lval); FOREVER { if (match ("<=")) { gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gule (); continue; } gle (); } else if (match (">=")) { gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { guge (); continue; } gge (); } else if ((sstreq ("<")) && !sstreq ("<<")) { inbyte (); gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gult (); continue; } glt (); } else if ((sstreq (">")) && !sstreq (">>")) { inbyte (); gpush (); if (heir7 (lval2)) rvalue (lval2); if (lval[2] || lval2[2]) { gugt (); continue; } ggt (); } else return (0); blanks (); } } heir7 (lval) int lval[]; { int k, lval2[3]; k = heir8 (lval); blanks (); if (!sstreq (">>") && !sstreq ("<<") || sstreq(">>=") || sstreq("<<=")) return (k); if (k) rvalue (lval); FOREVER { if (sstreq(">>") && ! sstreq(">>=")) { inbyte(); inbyte(); gpush (); if (heir8 (lval2)) rvalue (lval2); gasr (); } else if (sstreq("<<") && ! sstreq("<<=")) { inbyte(); inbyte(); gpush (); if (heir8 (lval2)) rvalue (lval2); gasl (); } else return (0); blanks(); } } heir8 (lval) int lval[]; { int k, lval2[3]; k = heir9 (lval); blanks (); if ((ch () != '+') & (ch () != '-') | nch() == '=') return (k); if (k) rvalue (lval); FOREVER { if (match ("+")) { gpush (); if (heir9 (lval2)) rvalue (lval2); /* if left is pointer and right is int, scale right */ if (dbltest (lval, lval2)) gaslint (); /* will scale left if right int pointer and left int */ gadd (lval,lval2); result (lval, lval2); } else if (match ("-")) { gpush (); if (heir9 (lval2)) rvalue (lval2); /* if dbl, can only be: pointer - int, or pointer - pointer, thus, in first case, int is scaled up, in second, result is scaled down. */ if (dbltest (lval, lval2)) gaslint (); gsub (); /* if both pointers, scale result */ if ((lval[2] == CINT) && (lval2[2] == CINT)) { gasrint(); /* divide by intsize */ } result (lval, lval2); } else return (0); } } heir9 (lval) int lval[]; { int k, lval2[3]; k = heir10 (lval); blanks (); if (((ch () != '*') && (ch () != '/') && (ch () != '%')) || (nch() == '=')) return (k); if (k) rvalue (lval); FOREVER { if (match ("*")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gmult (); } else if (match ("/")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gdiv (); } else if (match ("%")) { gpush (); if (heir10 (lval2)) rvalue (lval2); gmod (); } else return (0); } } heir10 (lval) int lval[]; { int k; unsigned char *ptr; if (match ("++")) { if ((k = heir10 (lval)) == 0) { needlval (); return (0); } // if (lval[1]) // gpush (); rivalue (lval); // ginc (lval); // store (lval); return (0); } else if (match ("--")) { if ((k = heir10 (lval)) == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gdec (lval); store (lval); return (0); } else if (match ("-")) { k = heir10 (lval); if (k) rvalue (lval); gneg (); return (0); } else if (match ("~")) { k = heir10 (lval); if (k) rvalue (lval); gcom (); return (0); } else if (match ("!")) { k = heir10 (lval); if (k) rvalue (lval); glneg (); return (0); } else if (ch()=='*' && nch() != '=') { inbyte(); k = heir10 (lval); if (k) rvalue (lval); if (ptr = lval[0]) lval[1] = ptr[TYPE]; else lval[1] = CINT; lval[2] = 0; /* flag as not pointer or array */ return (1); } else if (ch()=='&' && nch()!='&' && nch()!='=') { inbyte(); k = heir10 (lval); if (k == 0) { error ("illegal address"); return (0); } ptr = lval[0]; lval[2] = ptr[TYPE]; if (lval[1]) return (0); /* global and non-array */ immed (); k=128+ptr[OFFSET]+ptr[OFFSET+1]*256; onum(k); ot("\t/Offset from stackbase at 128 (200(8))"); nl (); lval[1] = ptr[TYPE]; return (0); } else { k = heir11 (lval); if (match ("++")) { if (k == 0) { needlval (); return (0); } // if (lval[1]) // gpush (); rvalue (lval); gisz (lval); // ginc (lval); // store (lval); // gdec (lval); return (0); } else if (match ("--")) { if (k == 0) { needlval (); return (0); } if (lval[1]) gpush (); rvalue (lval); gdec (lval); store (lval); ginc (lval); return (0); } else return (k); } } heir11 (lval) int *lval; { int k; char *ptr; k = primary (lval); ptr = lval[0]; blanks (); if ((ch () == '[') | (ch () == '(')) FOREVER { if (match ("[")) { if (ptr == 0) { error ("can't subscript"); junk (); needbrack ("]"); return (0); } else if (ptr[IDENT] == POINTER) rvalue (lval); else if (ptr[IDENT] != ARRAY) { error ("can't subscript"); k = 0; } gpush (); expression (YES); needbrack ("]"); if (ptr[TYPE] == CINT) gaslint (); gadd (NULL,NULL); lval[0] = 0; lval[1] = ptr[TYPE]; k = 1; } else if (match ("(")) { if (ptr == 0) callfunction (0); else if (ptr[IDENT] != FUNCTION) { rvalue (lval); callfunction (0); } else callfunction (ptr); k = lval[0] = 0; } else return (k); } if (ptr == 0) return (k); if (ptr[IDENT] == FUNCTION) { immed (); prefix (); outstr (ptr); nl (); return (0); } return (k); } |
Added cc8/cross/function.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | /* File function.c: 2.1 (83/03/20,16:02:04) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * begin a function * * called from "parse", this routine tries to make a function out * of what follows * modified version. p.l. woods * */ int argtop; newfunc () { char n[NAMESIZE], *ptr, rtn[NAMESIZE]; fexitlab = getlabel(); if (!symname (n) ) { error ("illegal function or declaration"); kill (); return 0; } if (ptr = findglb (n)) { if (ptr[IDENT] != FUNCTION) multidef (n); else if (ptr[OFFSET] == FUNCTION) multidef (n); else ptr[OFFSET] = FUNCTION; } else addglb (n, FUNCTION, CINT, 0, PUBLIC); // Do not allocate any storage to global functions if (!match ("(")) error ("missing open paren"); prefix (); if (astreq(n,"main",4)) { if (inbreak) { ol("\tEND"); output=bfile; } outstr("xmain"); } else outstr (n); strcpy(rtn,n); col (); // outstr("\t0"); nl (); if (inbreak) { ol("\tCLA CLL"); ol("\tCALL 2,PGINIT"); ol("\tARG STKP"); ol("\tARG GBL"); } prologue (rtn); locptr = STARTLOC; argstk = 0; while (!match (")")) { if (symname (n)) { if (findloc (n)) multidef (n); else { addloc (n, 0, 0, argstk, AUTO); argstk = argstk + intsize(); } } else { error ("illegal argument name"); junk (); } blanks (); if (!streq (line + lptr, ")")) { if (!match (",")) error ("expected comma"); } if (endst ()) break; } stkp = 0; argtop = argstk; while (argstk) { if (amatch ("register", 8)) { if (amatch("char", 4)) getarg(CCHAR); else if (amatch ("int", 3)) getarg(CINT); else getarg(CINT); ns(); } else if (amatch ("char", 4)) { getarg (CCHAR); ns (); } else if (amatch ("int", 3)) { getarg (CINT); ns (); } else { error ("wrong number args"); break; } } statement(YES); printlabel(fexitlab); col(); nl(); if (astreq(n,"main",4)) /* On exit from main pop literal table as well */ modstk(0); else modstk (0); gret (rtn); stkp = 0; locptr = STARTLOC; } /* * declare argument types * * called from "newfunc", this routine add an entry in the local * symbol table for each named argument * completely rewritten version. p.l. woods * */ getarg (t) int t; { int j, legalname, address; char n[NAMESIZE], c, *argptr; FOREVER { if (argstk == 0) return 0; if (match ("*")) j = POINTER; else j = VARIABLE; if (!(legalname = symname (n))) illname (); if (match ("[")) { while (inbyte () != ']') if (endst ()) break; j = POINTER; } if (legalname) { if (argptr = findloc (n)) { argptr[IDENT] = j; argptr[TYPE] = t; address = argtop - glint(argptr); if (t == CCHAR && j == VARIABLE) address = address + byteoff(); argptr[OFFSET] = (address) & 0xff; argptr[OFFSET + 1] = (address >> 8) & 0xff; } else error ("expecting argument name"); } argstk = argstk - intsize(); if (endst ()) return 0; if (!match (",")) error ("expected comma"); } } |
Added cc8/cross/gen.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | /* File gen.c: 2.1 (83/03/20,16:02:06) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* ToUpper routine */ ucase(ch) int ch; { if ('a'>ch || ch>'z') return(ch); return(ch-32); } /* * return next available internal label number * */ getlabel () { return (nxtlab++); } /* * print specified number as label */ printlabel (label) int label; { olprfix (); outdec (label); } /* * glabel - generate label */ glabel (lab) char *lab; { prefix (); outstr (lab); col (); nl (); } /* * gnlabel - generate numeric label */ gnlabel (nlab) int nlab; { printlabel (nlab); col (); nl (); } outbyte (c) char c; { if (c == 0) return (0); fputc (c, output); return (c); } outstr (ptr) char ptr[]; { int k; k = 0; while (outbyte (ucase(ptr[k++]))); } tab () { outbyte (9); } ol (ptr) char ptr[]; { ot (ptr); nl (); } ot (ptr) char ptr[]; { outstr (ptr); } outdec (number) int number; { int k, zs; char c; if (number == -32768) { outstr ("-32768"); return 0; } zs = 0; k = 10000; if (number < 0) { number = (-number); outbyte ('-'); } while (k >= 1) { c = number / k + '0'; if ((c != '0' | (k == 1) | zs)) { zs = 1; outbyte (c); } number = number % k; k = k / 10; } } store (lval) int *lval; { if (lval[1] == 0) putmem (lval[0]); else putstk (lval[1]); } rvalue (lval) int *lval; { if ((lval[0] != 0) & (lval[1] == 0)) getmem (lval[0]); else indirect (lval[1]); } rivalue (lval) int *lval; { if ((lval[0] != 0) & (lval[1] == 0)) getincmem (lval[0]); else incdirect (lval[1]); } test (label, ft) int label, ft; { needbrack ("("); expression (YES); needbrack (")"); testjump (label, ft); } |
Added cc8/cross/io.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | /* File io.c: 2.1 (83/03/20,16:02:07) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * open input file */ openin (p) char *p; { strcpy(fname, p); fixname (fname); if (!checkname (fname)) return (NO); if ((input = fopen (fname, "r")) == NULL) { pl ("Open failure\n"); return (NO); } kill (); return (YES); } /* * open output file */ openout () { outfname (fname); if ((output = fopen (fname, "w")) == NULL) { pl ("Open failure"); return (NO); } kill (); return (YES); } /* * change input filename to output filename */ outfname (s) char *s; { while (*s) s++; *--s = 's'; } /* * remove NL from filenames * */ fixname (s) char *s; { while (*s && *s++ != EOL); if (!*s) return 0; *(--s) = 0; } /* * check that filename is "*.c" */ checkname (s) char *s; { while (*s) s++; if (*--s != 'c') return (NO); if (*--s != '.') return (NO); return (YES); } kill () { lptr = 0; line[lptr] = 0; } inln () { int k; FILE *unit; FOREVER { if (feof (input)) return 0; if ((unit = input2) == NULL) unit = input; kill (); while ((k = fgetc (unit)) != EOF) { if ((k == EOL) | (lptr >= LINEMAX)) break; if (k != 13) line[lptr++] = k; } line[lptr] = 0; if (output && cmode) { outstr("/\t"); ol(line); } if (k <= 0) if (input2 != NULL) { input2 = inclstk[--inclsp]; fclose (unit); } if (lptr) { if ((ctext) & (cmode)) { comment (); outstr (line); nl (); } lptr = 0; return 0; } } } inbyte () { while (ch () == 0) { if (feof (input)) return (0); preprocess (); } return (gch ()); } inchar () { if (ch () == 0) inln (); if (feof (input)) return (0); return (gch ()); } gch () { if (ch () == 0) return (0); else return (line[lptr++] & 127); } nch () { if (ch () == 0) return (0); else return (line[lptr + 1] & 127); } ch () { return (line[lptr] & 127); } /* * print a carriage return and a string only to console * */ pl (str) char *str; { int k; k = 0; putchar (EOL); while (str[k]) putchar (str[k++]); } |
Added cc8/cross/lex.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | /* File lex.c: 2.1 (83/03/20,16:02:09) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * semicolon enforcer * * called whenever syntax requires a semicolon * */ ns () { if (!match (";")) error ("missing semicolon"); } junk () { if (an (inbyte ())) while (an (ch ())) gch (); else while (an (ch ())) { if (ch () == 0) break; gch (); } blanks (); } endst () { blanks (); return ((streq (line + lptr, ";") | (ch () == 0))); } needbrack (str) char *str; { if (!match (str)) { error ("missing bracket"); comment (); outstr (str); nl (); } } /* * test if given character is alpha * */ alpha (c) char c; { c = c & 127; return (((c >= 'a') & (c <= 'z')) | ((c >= 'A') & (c <= 'Z')) | (c == '_')); } /* * test if given character is numeric * */ numeric (c) char c; { c = c & 127; return ((c >= '0') & (c <= '9')); } /* * test if given character is alphanumeric * */ an (c) char c; { return ((alpha (c)) | (numeric (c))); } sstreq (str1) char *str1; { return (streq(line + lptr, str1)); } streq (str1, str2) char str1[], str2[]; { int k; k = 0; while (str2[k]) { if ((str1[k] != str2[k])) return (0); k++; } return (k); } astreq (str1, str2, len) char str1[], str2[]; int len; { int k; k = 0; while (k < len) { if ((str1[k] != str2[k])) break; if (str1[k] == 0) break; if (str2[k] == 0) break; k++; } if (an (str1[k])) return (0); if (an (str2[k])) return (0); return (k); } match (lit) char *lit; { int k; blanks (); if (k = streq (line + lptr, lit)) { lptr = lptr + k; return (1); } return (0); } amatch (lit, len) char *lit; int len; { int k; blanks (); if (k = astreq (line + lptr, lit, len)) { lptr = lptr + k; while (an (ch ())) inbyte (); return (1); } return (0); } blanks () { FOREVER { while (ch () == 0) { preprocess (); if (feof (input)) break; } if (ch () == ' ') gch (); else if (ch () == 9) gch (); else return 0; } } |
Added cc8/cross/main.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | /* File main.c: 2.7 (84/11/28,10:14:56) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" main (argc, argv) int argc; char** argv; /* OS/8 CC8 can't cope, but bootstrapping CC8 doesn't work, either */ { char *p,*bp; int smacptr; macptr = 0; ctext = 0; argc--; argv++; errs = 0; aflag = 1; while (p = *argv++) if (*p == '-') while (*++p) switch(*p) { case 't': case 'T': ctext = 1; break; case 's': case 'S': sflag = 1; break; case 'c': case 'C': cflag = 1; break; case 'a': case 'A': aflag = 0; break; case 'd': case 'D': bp = ++p; if (!*p) usage(); while (*p && *p != '=') p++; if (*p == '=') *p = '\t'; while (*p) p++; p--; defmac(bp); break; default: usage(); } else break; smacptr = macptr; if (!p) usage(); while (p) { errfile = 0; if (typof(p) == 'c' || typof(p) =='C') { glbptr = STARTGLB; locptr = STARTLOC; wsptr = ws; inclsp = iflevel = skiplevel = swstp = litptr = stkp = errcnt = ncmp = lastst = quote[1] = gsize = inbreak = 0; macptr = smacptr; input2 = NULL; quote[0] = '"'; cmode = 1; glbflag = 1; nxtlab = 0; litlab = getlabel (); defmac("end\tmemory"); rglbptr = glbptr; defmac("short\tint"); initmac(); /* * compiler body */ if (!openin (p)) return 0; if (!openout ()) return 0; header (); gtext (); parse (); fclose (input); gdata (); dumplits (); dumpglbs (); errorsummary (); trailer (); fclose (output); pl (""); errs = errs || errfile; getchar(); #ifndef NOASLD } if (!errfile && !sflag) errs = errs || assemble(p); #else } else { fputs("Don't understand file ", stderr); fputs(p, stderr); errs = 1; } #endif p = *argv++; } #ifndef NOASLD if (!errs && !sflag && !cflag) errs = errs || link(); #endif exit(errs != 0); getchar(); } FEvers() { outstr("/\tFront End (1.0:27/1/99)"); } usage() { fputs("usage: sccXXXX [-tcsa] [-dSYM[=VALUE]] files\n", stderr); exit(1); } /* * process all input text * * at this level, only static declarations, defines, includes, * and function definitions are legal. * */ parse () { while (!feof (input)) { if (amatch ("extern", 6)) dodcls(EXTERN); else if (amatch ("static",6)) dodcls(STATIC); else if (dodcls(PUBLIC)) ; else if (match ("#asm")) doasm (); else if (match ("#include")) doinclude (); else if (match ("#define")) dodefine(); else if (match ("#undef")) doundef(); else newfunc (); blanks (); } } /* * parse top level declarations */ dodcls(stclass) int stclass; { blanks(); if (amatch("char", 4)) declglb(CCHAR, stclass); else if (amatch("int", 3)) declglb(CINT, stclass); else if (stclass == PUBLIC) return(0); else declglb(CINT, stclass); ns (); return(1); } /* * dump the literal pool */ dumplits () { int j, k; /* A loc containing the size */ ol("\tLAP"); ot ("\tCPAGE "); onum (2+litptr); nl(); outbyte('L'); printlabel (litlab); col(); ot("\t"); onum (-litptr); nl(); if (litptr == 0) return 0; /* Generate a loc containing the address of the literals */ outbyte('X'); printlabel (litlab); col(); ot("\t"); printlabel (litlab); nl(); printlabel (litlab); col (); k = 0; while (k < litptr) { defbyte (); j = 8; while (j--) { onum (litq[k++] & 127); if ((j == 0) | (k >= litptr)) { nl (); break; } outbyte (';'); } } ol("\tEAP"); } /* * dump all static variables */ dumpglbs () { int j; if (!glbflag) { ot("GBLS,\t0"); nl(); return 0; } cptr = rglbptr; while (cptr < glbptr) { if (cptr[IDENT] != FUNCTION) { ppubext(cptr); if (cptr[STORAGE] != EXTERN) { //prefix (); //outstr (cptr); //col (); //defstorage (); j = glint(cptr); if ((cptr[TYPE] == CINT) || (cptr[IDENT] == POINTER)) j = j * intsize(); //onum (j); //nl (); } } else { fpubext(cptr); } cptr = cptr + SYMSIZ; } ot("GBLS,\t"); onum(gsize+128); // Beginning of stack after globals nl(); } /* * report errors */ errorsummary () { if (ncmp) error ("missing closing bracket"); nl (); comment (); outdec (errcnt); if (errcnt) errfile = YES; outstr (" error(s) in compilation"); nl (); comment(); ot("literal pool:"); outdec(litptr); nl(); comment(); ot("global pool:"); outdec(glbptr-rglbptr); nl(); comment(); ot("Macro pool:"); outdec(macptr); nl(); pl (errcnt ? "Error(s)" : "No errors"); } typof(s) char *s; { s += strlen(s) - 2; if (*s == '.') return(*(s+1)); return(' '); } |
Added cc8/cross/preproc.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | /* File preproc.c: 2.3 (84/11/27,11:47:40) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * open an include file */ doinclude () { char *p; FILE *inp2; blanks (); if (inp2 = fixiname ()) if (inclsp < INCLSIZ) { inclstk[inclsp++] = input2; input2 = inp2; } else { fclose (inp2); error ("too many nested includes"); } else { error ("Could not open include file"); } kill (); } /* * fixiname - remove "brackets" around include file name */ fixiname () { char c1, c2, *p, *ibp; char buf[20]; FILE *fp; char buf2[100]; ibp = &buf[0]; if ((c1 = gch ()) != '"' && c1 != '<') return (NULL); for (p = line + lptr; *p ;) *ibp++ = *p++; c2 = *(--p); if (c1 == '"' ? (c2 != '"') : (c2 != '>')) { error ("incorrect delimiter"); return (NULL); } *(--ibp) = 0; fp = NULL; if (c1 == '<' || !(fp = fopen(buf, "r"))) { strcpy(buf2, DEFLIB); strcat(buf2, buf); fp = fopen(buf2, "r"); } return(fp); } /* * "asm" pseudo-statement * * enters mode where assembly language statements are passed * intact through parser * */ doasm () { cmode = 0; FOREVER { inln (); if (match ("#endasm")) { ol("/\t#ENDASM"); break; } if (feof (input)) break; outstr (line); nl (); } kill (); cmode = 1; } dodefine () { addmac(); } doundef () { int mp; char sname[NAMESIZE]; if (!symname(sname)) { illname(); kill(); return 0; } if (mp = findmac(sname)) delmac(mp); kill(); } preprocess () { if (ifline()) return 0; while (cpp()); } doifdef (ifdef) int ifdef; { char sname[NAMESIZE]; int k; blanks(); ++iflevel; if (skiplevel) return 0; k = symname(sname) && findmac(sname); if (k != ifdef) skiplevel = iflevel; } ifline() { FOREVER { inln(); if (feof(input)) return(1); if (match("#ifdef")) { doifdef(YES); continue; } else if (match("#ifndef")) { doifdef(NO); continue; } else if (match("#else")) { if (iflevel) { if (skiplevel == iflevel) skiplevel = 0; else if (skiplevel == 0) skiplevel = iflevel; } else noiferr(); continue; } else if (match("#endif")) { if (iflevel) { if (skiplevel == iflevel) skiplevel = 0; --iflevel; } else noiferr(); continue; } if (!skiplevel) return(0); } } noiferr() { error("no matching #if..."); } cpp () { int k; char c, sname[NAMESIZE]; int tog; int cpped; /* non-zero if something expanded */ cpped = 0; /* don't expand lines with preprocessor commands in them */ if (!cmode || line[0] == '#') return(0); mptr = lptr = 0; while (ch ()) { if ((ch () == '/') & (nch () == '/')) { inln(); } if ((ch () == ' ') | (ch () == 9)) { keepch (' '); while ((ch () == ' ') | (ch () == 9)) gch (); } else if (ch () == '"') { keepch (ch ()); gch (); while (ch () != '"') { if (ch () == 0) { error ("missing quote"); break; } if (ch() == '\\') keepch(gch()); keepch (gch ()); } gch (); keepch ('"'); } else if (ch () == 39) { keepch (39); gch (); while (ch () != 39) { if (ch () == 0) { error ("missing apostrophe"); break; } if (ch() == '\\') keepch(gch()); keepch (gch ()); } gch (); keepch (39); } else if ((ch () == '/') & (nch () == '*')) { inchar (); inchar (); while ((((c = ch ()) == '*') & (nch () == '/')) == 0) if (c == '$') { inchar (); tog = TRUE; if (ch () == '-') { tog = FALSE; inchar (); } if (alpha (c = ch ())) { inchar (); toggle (c, tog); } } else { if (ch () == 0) inln (); else inchar (); if (feof (input)) break; } inchar (); inchar (); } else if (an (ch ())) { k = 0; while (an (ch ())) { if (k < NAMEMAX) sname[k++] = ch (); gch (); } sname[k] = 0; if (k = findmac (sname)) { cpped = 1; while (c = macq[k++]) keepch (c); } else { k = 0; while (c = sname[k++]) keepch (c); } } else keepch (gch ()); } keepch (0); if (mptr >= MPMAX) error ("line too long"); lptr = mptr = 0; while (line[lptr++] = mline[mptr++]); lptr = 0; return(cpped); } keepch (c) char c; { mline[mptr] = c; if (mptr < MPMAX) mptr++; return (c); } defmac(s) char *s; { kill(); strcpy(line, s); addmac(); } addmac () { char sname[NAMESIZE]; int k; int mp; if (!symname (sname)) { illname (); kill (); return 0; } if (mp = findmac(sname)) { error("Duplicate define"); delmac(mp); } k = 0; while (putmac (sname[k++])); while (ch () == ' ' | ch () == 9) gch (); while (putmac (gch ())); if (macptr >= MACMAX) error ("macro table full"); } delmac(mp) int mp; { --mp; --mp; /* step over previous null */ while (mp >= 0 && macq[mp]) macq[mp--] = '%'; } putmac (c) char c; { macq[macptr] = c; if (macptr < MACMAX) macptr++; return (c); } findmac (sname) char *sname; { int k; k = 0; while (k < macptr) { if (astreq (sname, macq + k, NAMEMAX)) { while (macq[k++]); return (k); } while (macq[k++]); while (macq[k++]); } return (0); } toggle (name, onoff) char name; int onoff; { switch (name) { case 'C': ctext = onoff; break; } } |
Added cc8/cross/primary.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | /* File primary.c: 2.4 (84/11/27,16:26:07) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" primary (lval) int *lval; { unsigned char *ptr, sname[NAMESIZE]; int num[1]; int k; lval[2] = 0; /* clear pointer/array type */ if (match ("(")) { k = heir1 (lval); needbrack (")"); return (k); } if (amatch("sizeof", 6)) { needbrack("("); immed(); if (amatch("int", 3)) onum(intsize()); else if (amatch("char", 4)) onum(1); else if (symname(sname)) { if ((ptr = findloc(sname)) || (ptr = findglb(sname))) { if (ptr[STORAGE] == LSTATIC) error("sizeof local static"); k = glint(ptr); if ((ptr[TYPE] == CINT) || (ptr[IDENT] == POINTER)) k *= intsize(); onum(k); } else { error("sizeof undeclared variable"); onum(0); } } else { error("sizeof only on type or variable"); } needbrack(")"); nl(); return(lval[0] = lval[1] = 0); } if (symname (sname)) { if (ptr = findloc (sname)) { getloc (ptr); lval[0] = ptr; lval[1] = ptr[TYPE]; if (ptr[IDENT] == POINTER) { lval[1] = CINT; lval[2] = ptr[TYPE]; } if (ptr[IDENT] == ARRAY) { lval[2] = ptr[TYPE]; lval[2] = 0; return (0); } else return (1); } if (ptr = findglb (sname)) if (ptr[IDENT] != FUNCTION) { lval[0] = ptr; lval[1] = 0; if (ptr[IDENT] != ARRAY) { if (ptr[IDENT] == POINTER) lval[2] = ptr[TYPE]; return (1); } immed (); onum(128+ptr[OFFSET]+ptr[OFFSET+1]*256); ot("\t/Offset from stackbase at 128 (200(8))"); nl (); lval[1] = lval[2] = ptr[TYPE]; lval[2] = 0; return (0); } blanks (); if (ch() != '(') error("undeclared variable"); ptr = addglb (sname, FUNCTION, CINT, 0, PUBLIC); lval[0] = ptr; lval[1] = 0; return (0); } if (constant (num)) return (lval[0] = lval[1] = 0); else { error ("invalid expression"); immed (); onum (0); nl (); junk (); return (0); } } /* * true if val1 -> int pointer or int array and val2 not pointer or array */ dbltest (val1, val2) int val1[], val2[]; { if (val1 == NULL) return (FALSE); if (val1[2] != CINT) return (FALSE); if (val2[2]) return (FALSE); return (TRUE); } /* * determine type of binary operation */ result (lval, lval2) int lval[], lval2[]; { if (lval[2] && lval2[2]) lval[2] = 0; else if (lval2[2]) { lval[0] = lval2[0]; lval[1] = lval2[1]; lval[2] = lval2[2]; } } constant (val) int val[]; { if (number (val)) { if (val[0]==0) { ol("\t/ (0)"); cpri(); return (1); } immed (); } else if (pstr (val)) immed (); else if (qstr (val)) { immd2 (); stkbase(); nl(); /* outbyte ('+'); */ immd3 (); } else return (0); onum (val[0]); nl (); return (1); } number (val) int val[]; { int k, minus, base; char c; k = minus = 1; while (k) { k = 0; if (match ("+")) k = 1; if (match ("-")) { minus = (-minus); k = 1; } } if (!numeric (c = ch ())) return (0); if (match ("0x") || match ("0X")) while (numeric (c = ch ()) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { inbyte (); k = k * 16 + (numeric (c) ? (c - '0') : ((c & 07) + 9)); } else { base = (c == '0') ? 8 : 10; while (numeric (ch ())) { c = inbyte (); k = k * base + (c - '0'); } } if (minus < 0) k = (-k); val[0] = k; return (1); } pstr (val) int val[]; { int k; char c; k = 0; if (!match ("'")) return (0); while ((c = gch ()) != 39) { c = (c == '\\') ? spechar(): c; k = (k & 255) * 256 + (c & 255); } val[0] = k; return (1); } qstr (val) int val[]; { char c; if (!match (quote)) return (0); val[0] = litptr; while (ch () != '"') { if (ch () == 0) break; if (litptr >= LITMAX) { error ("string space exhausted"); while (!match (quote)) if (gch () == 0) break; return (1); } c = gch(); litq[litptr++] = (c == '\\') ? spechar(): c; } gch (); litq[litptr++] = 0; return (1); } /* * decode special characters (preceeded by back slashes) */ spechar() { char c; c = ch(); if (c == 'n') c = EOL; else if (c == 't') c = TAB; else if (c == 'r') c = CR; else if (c == 'f') c = FFEED; else if (c == 'b') c = BKSP; else if (c == '0') c = EOS; else if (c == EOS) return 0; gch(); return (c); } /* * perform a function call * * called from "heir11", this routine will either call the named * function, or if the supplied ptr is zero, will call the contents * of HL * NB Added section to load Acc with nargs for vararg calls * NB have addded pseudo functions here as well */ callfunction (ptr) char *ptr; { int nargs; if (strcmp(ptr,"stri")==0) { expression(NO); stri(); needbrack(")"); return 0; } if (strcmp(ptr,"iinit")==0) { expression(NO); iinit(); needbrack(")"); return 0; } nargs = 0; blanks (); if (ptr == 0) gpush (); while (!streq (line + lptr, ")")) { if (endst ()) break; expression (NO); if (ptr == 0) swapstk (); gpush (); nargs = nargs + intsize(); if (!match (",")) break; } needbrack (")"); if (aflag) gnargs(nargs / intsize()); if (ptr) gcall (ptr,&nargs); else callstk (); stkp = modstk (stkp + nargs); } needlval () { error ("must be lvalue"); } |
Added cc8/cross/stmt.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | /* File stmt.c: 2.1 (83/03/20,16:02:17) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * statement parser * * called whenever syntax requires a statement. this routine * performs that statement and returns a number telling which one * * 'func' is true if we require a "function_statement", which * must be compound, and must contain "statement_list" (even if * "declaration_list" is omitted) */ statement (func) int func; { if ((ch () == 0) & feof (input)) return (0); lastst = 0; if (func) if (match ("{")) { compound (YES); return (lastst); } else error ("function requires compound statement"); if (match ("{")) compound (NO); else stst (); return (lastst); } /* * declaration */ stdecl () { if (amatch("register", 8)) doldcls(DEFAUTO); else if (amatch("auto", 4)) doldcls(DEFAUTO); else if (amatch("static", 6)) doldcls(LSTATIC); else if (doldcls(AUTO)) ; else return (NO); return (YES); } doldcls(stclass) int stclass; { blanks(); if (amatch("char", 4)) declloc(CCHAR, stclass); else if (amatch("int", 3)) declloc(CINT, stclass); else if (stclass == LSTATIC || stclass == DEFAUTO) declloc(CINT, stclass); else return(0); ns(); return(1); } /* * non-declaration statement */ stst () { if (amatch ("if", 2)) { doif (); lastst = STIF; } else if (amatch ("while", 5)) { dowhile (); lastst = STWHILE; } else if (amatch ("switch", 6)) { doswitch (); lastst = STSWITCH; } else if (amatch ("do", 2)) { dodo (); ns (); lastst = STDO; } else if (amatch ("for", 3)) { dofor (); lastst = STFOR; } else if (amatch ("return", 6)) { doreturn (); ns (); lastst = STRETURN; } else if (amatch ("break", 5)) { dobreak (); ns (); lastst = STBREAK; } else if (amatch ("continue", 8)) { docont (); ns (); lastst = STCONT; } else if (match (";")) ; else if (amatch ("case", 4)) { docase (); lastst = statement (NO); } else if (amatch ("default", 7)) { dodefault (); lastst = statement (NO); } else if (match ("#asm")) { doasm (); lastst = STASM; } else if (match ("{")) compound (NO); else { expression (YES); /* if (match (":")) { dolabel (); lastst = statement (NO); } else { */ ns (); lastst = STEXP; /* } */ } } /* * compound statement * * allow any number of statements to fall between "{" and "}" * * 'func' is true if we are in a "function_statement", which * must contain "statement_list" */ compound (func) int func; { int decls; decls = YES; ncmp++; while (!match ("}")) { if (feof (input)) return 0; if (decls) { if (!stdecl ()) decls = NO; } else stst (); } ncmp--; } /* * "if" statement */ doif () { int fstkp, flab1, flab2; char *flev; flev = locptr; fstkp = stkp; flab1 = getlabel (); test (flab1, FALSE); statement (NO); stkp = modstk (fstkp); locptr = flev; if (!amatch ("else", 4)) { gnlabel (flab1); return 0; } jump (flab2 = getlabel ()); gnlabel (flab1); statement (NO); stkp = modstk (fstkp); locptr = flev; gnlabel (flab2); } /* * "while" statement */ dowhile () { int ws[7]; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSWHILE; ws[WSTEST] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); gnlabel (ws[WSTEST]); test (ws[WSEXIT], FALSE); statement (NO); jump (ws[WSTEST]); gnlabel (ws[WSEXIT]); locptr = ws[WSSYM]; stkp = modstk (ws[WSSP]); delwhile (); } /* * "do" statement */ dodo () { int ws[7]; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSDO; ws[WSBODY] = getlabel (); ws[WSTEST] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); gnlabel (ws[WSBODY]); statement (NO); if (!match ("while")) { error ("missing while"); return 0; } gnlabel (ws[WSTEST]); test (ws[WSBODY], TRUE); gnlabel (ws[WSEXIT]); locptr = ws[WSSYM]; stkp = modstk (ws[WSSP]); delwhile (); } /* * "for" statement */ dofor () { int ws[7], *pws; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSFOR; ws[WSTEST] = getlabel (); ws[WSINCR] = getlabel (); ws[WSBODY] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); pws = readwhile (); needbrack ("("); if (!match (";")) { expression (YES); ns (); } gnlabel (pws[WSTEST]); if (!match (";")) { expression (YES); testjump (pws[WSBODY], TRUE); jump (pws[WSEXIT]); ns (); } else pws[WSTEST] = pws[WSBODY]; gnlabel (pws[WSINCR]); if (!match (")")) { expression (YES); needbrack (")"); jump (pws[WSTEST]); } else pws[WSINCR] = pws[WSTEST]; gnlabel (pws[WSBODY]); statement (NO); jump (pws[WSINCR]); gnlabel (pws[WSEXIT]); locptr = pws[WSSYM]; stkp = modstk (pws[WSSP]); delwhile (); } /* * "switch" statement */ doswitch () { int ws[7]; int *ptr; ws[WSSYM] = locptr; ws[WSSP] = stkp; ws[WSTYP] = WSSWITCH; ws[WSCASEP] = swstp; ws[WSTAB] = getlabel (); ws[WSDEF] = ws[WSEXIT] = getlabel (); addwhile (ws); // immed (); // printlabel (ws[WSTAB]); // nl (); // gpush (); needbrack ("("); expression (YES); needbrack (")"); // stkp = stkp + intsize(); /* '?case' will adjust the stack */ gjcase (); jump (ws[WSTAB]); statement (NO); ptr = readswitch (); // if (ptr[WSDEF]!=ptr[WSEXIT]) jump (ptr[WSDEF]); jump (ptr[WSEXIT]); dumpsw (ptr); gnlabel (ptr[WSEXIT]); locptr = ptr[WSSYM]; // stkp = modstk (ptr[WSSP]); swstp = ptr[WSCASEP]; delwhile (); } /* * "case" label */ docase () { int val; val = 0; if (readswitch ()) { if (!number (&val)) if (!pstr (&val)) error ("bad case label"); addcase (val); if (!match (":")) error ("missing colon"); } else error ("no active switch"); } /* * "default" label */ dodefault () { int *ptr, lab; if (ptr = readswitch ()) { ptr[WSDEF] = lab = getlabel (); gnlabel (lab); if (!match (":")) error ("missing colon"); } else error ("no active switch"); } /* * "return" statement */ doreturn () { if (endst () == 0) expression (YES); jump(fexitlab); } /* * "break" statement */ dobreak () { int *ptr; if ((ptr = readwhile ()) == 0) return 0; modstk (ptr[WSSP]); jump (ptr[WSEXIT]); } /* * "continue" statement */ docont () { int *ptr; if ((ptr = findwhile ()) == 0) return 0; /* modstk (ptr[WSSP]); */ if (ptr[WSTYP] == WSFOR) jump (ptr[WSINCR]); else jump (ptr[WSTEST]); } /* * dump switch table */ dumpsw (ws) int ws[]; { int i,j; gdata (); gnlabel (ws[WSTAB]); if (ws[WSCASEP] != swstp) { j = ws[WSCASEP]; while (j < swstp) { i = 4; while (i--) { immd3(); onum (swstcase[j]); nl(); casejump(); jump (swstlab[j++]); if ((i == 0) | (j >= swstp)) { nl (); break; } nl(); } } jump(ws[WSDEF]); } gtext (); } |
Added cc8/cross/sym.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | /* File sym.c: 2.1 (83/03/20,16:02:19) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" /* * declare a static variable */ declglb (typ, stor) int typ, stor; { int k, j; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst ()) return 0; k = 1; if (match ("*")) j = POINTER; else j = VARIABLE; if (!symname (sname)) illname (); if (findglb (sname)) multidef (sname); if (match ("[")) { k = needsub (); if (k || stor == EXTERN) j = ARRAY; else j = POINTER; } addglb (sname, j, typ, k, stor); break; } if (!match (",")) return 0; } } /* * declare local variables * * works just like "declglb", but modifies machine stack and adds * symbol table entry with appropriate stack offset to find it again */ declloc (typ, stclass) int typ, stclass; { int k, j; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst ()) return 0; if (match ("*")) j = POINTER; else j = VARIABLE; if (!symname (sname)) illname (); if (findloc (sname)) multidef (sname); if (match ("[")) { k = needsub (); if (k) { j = ARRAY; if (typ == CINT) k = k * intsize(); } else { j = POINTER; k = intsize(); } } else if ((typ == CCHAR) & (j != POINTER)) k = 1; else k = intsize(); if (stclass != LSTATIC) { k = galign(k); stkp = modstk (stkp - k); addloc (sname, j, typ, stkp+k-1, AUTO); /* Reversed stack for PDP8 */ } else addloc( sname, j, typ, k, LSTATIC); break; } if (!match (",")) return 0; } } /* * get required array size */ needsub () { int num[1]; if (match ("]")) return (0); if (!number (num)) { error ("must be constant"); num[0] = 1; } if (num[0] < 0) { error ("negative size illegal"); num[0] = (-num[0]); } needbrack ("]"); return (num[0]); } findglb (sname) char *sname; { char *ptr; ptr = STARTGLB; while (ptr != glbptr) { if (astreq (sname, ptr, NAMEMAX)) return (ptr); ptr = ptr + SYMSIZ; } return (0); } findloc (sname) char *sname; { char *ptr; ptr = locptr; while (ptr != STARTLOC) { ptr = ptr - SYMSIZ; if (astreq (sname, ptr, NAMEMAX)) return (ptr); } return (0); } addglb (sname, id, typ, value, stor) char *sname, id, typ; int value, stor; { char *ptr; if (cptr = findglb (sname)) return (cptr); if (glbptr >= ENDGLB) { error ("global symbol table overflow"); return (0); } cptr = ptr = glbptr; while (an (*ptr++ = *sname++)); cptr[IDENT] = id; cptr[TYPE] = typ; cptr[STORAGE] = stor; cptr[OFFSET] = gsize & 0xff; cptr[OFFSET+1] = (gsize >> 8) & 0xff; gsize = gsize + value; glbptr = glbptr + SYMSIZ; return (cptr); } addloc (sname, id, typ, value, stclass) char *sname, id, typ; int value, stclass; { char *ptr; int k; if (cptr = findloc (sname)) return (cptr); if (locptr >= ENDLOC) { error ("local symbol table overflow"); return (0); } cptr = ptr = locptr; while (an (*ptr++ = *sname++)); cptr[IDENT] = id; cptr[TYPE] = typ; cptr[STORAGE] = stclass; if (stclass == LSTATIC) { gdata(); printlabel(k = getlabel()); col(); defstorage(); onum(value); nl(); gtext(); value = k; } else value = galign(value); cptr[OFFSET] = value & 0xff; cptr[OFFSET+1] = (value >> 8) & 0xff; locptr = locptr + SYMSIZ; return (cptr); } /* * test if next input string is legal symbol name * */ symname (sname) char *sname; { int k; char c; blanks (); if (!alpha (ch ())) return (0); k = 0; while (an (ch ())) sname[k++] = gch (); sname[k] = 0; return (1); } illname () { error ("illegal symbol name"); } multidef (sname) char *sname; { error ("already defined"); comment (); outstr (sname); nl (); } glint(syment) char *syment; { short l,u,r; l = syment[OFFSET]; u = syment[OFFSET+1]; r = (l & 0xff) + ((u << 8) & ~0x00ff); return (r); } |
Added cc8/cross/test/README.md.
> > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | This directory contains a very simple BASIC interpreter that can be compiled using the CC8 cross-compiler to create a SABR file, which can be assembled under the PiDP-8/I OS/8 environment per the instructions in [the top-level README][/doc/trunk/cc8/README.md] file. With the native OS/8 compiler installed in a running OS/8 instance, this will assemble and run the BASIC interpreter: .COMP BASIC.SB .R LOADER BASIC,LIBC/G And off you go... |
Added cc8/cross/test/basic.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | #include <libc.h> #include <init.pa> #define SMAX 10 #define CMAX 256 #define BMAX 64 #define LMAX 32 #define DMAX 32 #define CBMX 1024 #define LXMX 999 int E [SMAX]; /* subroutine line number stack */ int L [CMAX]; /* FOR loop beginning line number */ int M [CMAX]; /* FOR loop maximum index value */ int P [CMAX]; /* program variable value */ char Lb[CBMX]; /* Line buffer of CBMX chars */ int l,i,j; int *C; /* subroutine stack pointer */ char B [BMAX]; /* command input buffer */ char F [2]; /* temporary search string */ char *m [LXMX]; /* pointers to lines of program. This is a real waste of space! */ char *p,*q,*x,*y,*z,*s,*d; G( ) { /* get program line from buffer */ atoi(B,&l); y=m[l]; if(y){ if(strstr(B," ")) strcpy(y,B); else y=m[l]=0; return; } y=Lb; while(*y) y=y+DMAX; strcpy(y,B); m [l]=y; } /* end G */ /* recursive descent parser for arithmetic/logical expressions */ S( ) { int o; o=J( ); switch(*p++){ case '=': return o==S( ); break; case '#': return o!=S( ); default: p--; return o; } } /* end S */ J( ) { int o; o=K( ); switch(*p++){ case '<': return o<J( ); break; case '>': return o>J( ); default: p--; return o; } } /* end J */ K( ) { int o; o=V( ); switch(*p++){ case '$': return o<=K( ); break; case '!': return o>=K( ); default: p--; return o; } } /* end K */ V( ) { int o; o=W( ); switch(*p++){ case '+': return o+V( ); break; case '-': return o-V( ); default: p--; return o; } } /* end V */ W( ) { int o; o=Y( ); switch(*p++){ case '*': return o*W( ); break; case '/': return o/W( ); default: p--; return o; } } /* end W */ Y( ) { int o; if(*p=='-'){ p++; return -Y(); } q=p; if(*p>='0'&&*p<='9'){ while(*p>='0'&&*p<='9') p++; atoi(q,&o); return o; } if(*p=='('){ p++; o=S( ); p++; return o; } return P [*p++]; } /* end Y */ bufclear() { memset(m,0,LXMX); memset(Lb,0,CBMX); } main( ) { int tmp; /* temp var to fix bug 07Sep2005 Somos */ bufclear(); while(puts("Ok\r\n"),gets(B)) switch(*B){ case 'R': /* "RUN" command */ C=E; l=1; for(i=0; i<CMAX; i++) /* initialize variables */ P [i]=0; while(l){ while(!(s=m [l])) l++; while(*s!=' ') s++; /* skip line number */ if ( ! strstr ( s , "\"" ) ) { while ( ( p = strstr ( s , "<>" ) ) ) * p ++ = '#' , * p = ' ' ; while ( ( p = strstr ( s , "<=" ) ) ) * p ++ = '$' , * p = ' ' ; while ( ( p = strstr ( s , ">=" ) ) ) * p ++ = '!' , * p = ' ' ; } d=B; j=0; while(*s){ if(*s=='"') j++; if(*s!=' '||(j&1)) *d++=*s; s++; } *d=j=0; d--; /* backup to last char in line */ if(B [1]!='='){ switch(*B){ case 'E': /* "END" */ l=-1; break; case 'R': /* "REM" */ if(B [2]!='M') l=*--C; /* "RETURN" */ break; case 'I': if(B [1]=='N'){ /* "INPUT" */ tmp=*d; /* save for bug fix next line 07Sep2005 Somos */ gets(p=B); P [tmp]=S( ); } else { /* "IF" */ *(tmp=strstr(B,"TH"))=0; /* "THEN" */ p=B+2; if(S( )){ p=tmp+4; l=S( )-1; } } break; case 'P': /* "PRINT" */ tmp=','; p=B+5; while(tmp==','){ if(*p=='"'){ while(*++p!='"') putc(*p); p++; } else { printf("%d",S( )); } tmp=*p++; putc(' '); } puts("\r\n"); break; case 'G': /* "GOTO" */ p=B+4; if(B [2]=='S'){ /* "GOSUB" */ *C++=l; p++; } l=S( )-1; break; case 'F': /* "FOR" */ *(tmp=strstr(B,"TO"))=0; /* "TO" */ p=B+5; P [i=B [3]]=S( ); p=tmp+2; M [i]=S( ); L [i]=l; break; case 'N': /* "NEXT" */ tmp=*d; if(P [tmp]<M [tmp]){ l=L [tmp]; P [tmp]++; } break; } } else { p=B+2; P [*B]=S( ); } l++; } /* end while l */ break; case 'L': /* "LIST" command */ for(j=0; j<LXMX; j++) if(m[j]){ puts(m[j]); puts("\r\n"); } break; case 'N': /* "NEW" command */ bufclear(); break; case 'B': /* "BYE" command */ return 0; break; case 0: default: G( ); }/* end switch *B */ return 0; } /* end main */ |
Added cc8/cross/test/init.pa.
> | 1 | ../../include/init.pa |
Added cc8/cross/while.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | /* File while.c: 2.1 (83/03/20,16:02:22) */ /*% cc -O -c % * */ #include <stdio.h> #include "defs.h" #include "data.h" addwhile (ptr) int ptr[]; { int k; if (wsptr == WSMAX) { error ("too many active whiles"); return 0; } k = 0; while (k < WSSIZ) *wsptr++ = ptr[k++]; return 0; } delwhile () { if (readwhile ()) wsptr = wsptr - WSSIZ; } int readwhile () { if (wsptr == ws) { error ("no active do/for/while/switch"); return (0); } else return (wsptr-WSSIZ); } int *findwhile () { int *ptr; for (ptr = wsptr; ptr != ws;) { ptr = ptr - WSSIZ; if (ptr[WSTYP] != WSSWITCH) return (ptr); } error ("no active do/for/while"); return (0); } int *readswitch () { int *ptr; if (ptr = (int *)readwhile ()) if (ptr[WSTYP] == WSSWITCH) return (ptr); return (0); } addcase (val) int val; { int lab; if (swstp == SWSTSZ) error ("too many case labels"); else { swstcase[swstp] = val; swstlab[swstp++] = lab = getlabel (); printlabel (lab); col (); nl (); } } |
Added cc8/include/init.pa.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | #asm / / PDP8/E Run time routines for Small c compiler / ABSYM POP 160 ABSYM PSH 161 ABSYM JLC 162 ABSYM STKP 163 ABSYM PTSK 164 ABSYM POPR 165 ABSYM PCAL 166 ABSYM TMP 167 ABSYM GBL 170 ABSYM ZTMP 171 / DECIM / STK, COMMN 3840 / / / ENTRY MAIN MAIN, BLOCK 2 TAD GBLS DCA STKP TAD GBLS DCA GBL ISZ GBL / LOCAL LITERALS = STKP+1 TAD PVL DCA PSH TAD OVL DCA POP TAD MVL DCA PTSK TAD PVR DCA POPR TAD PVC DCA PCAL RIF TAD (3201 DCA PCL1 TAD PCL1 DCA DCC0 JMS MCC0 CLA CMA MQL CALL 1,LIBC ARG STKP CALL 0,OPEN JMSI PCAL XMAIN CALL 0,EXIT / PUSH, 0 CDF1 ISZ STKP DCAI STKP TADI STKP JMPI PUSH PPOP, 0 CDF1 DCA TMP TADI STKP MQL CMA TAD STKP DCA STKP TAD TMP JMPI PPOP PUTSTK, 0 JMSI POP SWP DCA JLC SWP DCAI JLC TADI JLC JMPI PUTSTK POPRET, JMSI POP SWP DCA ZTMP SWP JMPI ZTMP PCALL, 0 CLA CLL PCL1, 0 TADI PCALL DCA ZTMP TAD PCALL IAC JMSI PSH / PUSH RETURN CLA JMPI ZTMP PVL, PUSH OVL, PPOP MVL, PUTSTK SVL, STK PVR, POPRET PVC, PCALL / #endasm |
Added cc8/include/libc.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* Libc header Please note, no function declarations are made so, make sure the arg lists are correct in the calling code */ #define itoa libc0 #define puts libc1 #define nl libc2 #define getc libc3 #define gets libc4 #define atoi libc5 #define sscanf vlibc6 #define xinit libc7 #define memcpy libc8 #define kbhit libc9 #define putc libc10 #define strcpy libc11 #define strcat libc12 #define strstr libc13 #define exit libc14 #define isnum libc15 #define isdigit libc15 #define isalpha libc16 #define sprintf vlibc17 #define memset libc18 #define fgetc libc19 #define fopen libc20 #define fputc libc21 #define fclose libc22 #define printf vlibc23 #define isalnum libc24 #define isspace libc25 #define fprintf vlibc26 #define fputs libc27 #define strcmp libc28 #define cupper libc29 #define fgets libc30 |
Added cc8/os8/c8.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <libc.h> #include <init.pa> /* C pre-processor stub for PDP/8 c compiler 2017 */ /* Ask for input file, copy to CC.CC and run CC1 */ main() { int bfr; int fnm[10]; putc('>'); gets(fnm); cupper(fnm); fopen(fnm,"r"); fopen("CC.CC","w"); while (bfr=fgetc()) if (bfr!=12) /* Ignore form feed */ fputc(bfr); fclose(); #asm CALL 1,CHAIN ARG FNM HLT FNM, TEXT "CC1@@@" #endasm } |
Added cc8/os8/calc.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | int main() { int x,y,ans,i; int choice; int div; int bfr[10]; ans=0; while (1) { printf("DO YOU WISH TO CONTINUE (Y/N):"); ans=getc(); if (ans=='Y') { printf("ENTER ANY TWO NUMBERS:\r\n"); printf("ENTER THE FIRST NUMBER:"); gets(bfr); sscanf(bfr,"%d",&x); printf("ENTER THE SECOND NUMBER:"); gets(bfr); sscanf(bfr,"%d",&y); printf("SELECT THE OPERATION:\r\n"); printf("1: ADDITION\r\n"); printf("2: SUBTRACTION\r\n"); printf("3: MULTIPLICATION\r\n"); printf("4: DIVISION\r\n"); printf("CHOICE:"); gets(bfr); sscanf(bfr,"%d",&choice); if (choice==1) printf("Result:%d\r\n",x+y); if (choice==2) printf("Result:%d\r\n",x-y); if (choice==3) printf("Result:%d\r\n",x*y); if (choice==4) printf("Result:%d\r\n",x/y); } break; } |
Added cc8/os8/fib.c.
> > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | int fib(n) { if (n < 2) return n; else return fib(n-1)+fib(n-2); } int main() { int i; for (i=0;i<10;i++) printf("Fib#:%d = %d\r\n",fib(i)); } |
Added cc8/os8/header.sb.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | / SABR DEFINITIONS / FRONT END (2.0:1/4/2017) OPDEF ANDI 0400 OPDEF TADI 1400 OPDEF ISZI 2400 OPDEF DCAI 3400 OPDEF JMSI 4400 OPDEF JMPI 5400 OPDEF MQL 7421 OPDEF MQA 7701 OPDEF MQO 7501 OPDEF SWP 7521 OPDEF CDF1 6211 OPDEF CDF0 6201 OPDEF RIF 6224 OPDEF CAF0 6203 OPDEF BSW 7002 OPDEF CAM 7621 / / PDP8/E Run time routines for Small c compiler / ABSYM POP 160 ABSYM PSH 161 ABSYM JLC 162 ABSYM STKP 163 ABSYM PTSK 164 ABSYM POPR 165 ABSYM PCAL 166 ABSYM TMP 167 ABSYM GBL 170 ABSYM ZTMP 171 / DECIM / STK, COMMN 3840 / / / ENTRY MAIN MAIN, BLOCK 2 TAD GBLS DCA STKP TAD GBLS DCA GBL ISZ GBL / LOCAL LITERALS = STKP+1 TAD PVL DCA PSH TAD OVL DCA POP TAD MVL DCA PTSK TAD PVR DCA POPR TAD PVC DCA PCAL RIF TAD (3201 DCA PCL1 TAD PCL1 DCA DCC0 JMS MCC0 CLA CMA MQL CALL 1,LIBC ARG STKP CALL 0,OPEN JMSI PCAL XMAIN CALL 0,EXIT / PUSH, 0 CDF1 ISZ STKP DCAI STKP TADI STKP JMPI PUSH PPOP, 0 CDF1 DCA TMP TADI STKP MQL CMA TAD STKP DCA STKP TAD TMP JMPI PPOP PUTSTK, 0 JMSI POP SWP DCA JLC SWP DCAI JLC TADI JLC JMPI PUTSTK POPRET, JMSI POP SWP DCA ZTMP SWP JMPI ZTMP PCALL, 0 CLA CLL PCL1, 0 TADI PCALL DCA ZTMP TAD PCALL IAC JMSI PSH / PUSH RETURN CLA JMPI ZTMP PVL, PUSH OVL, PPOP MVL, PUTSTK SVL, STK PVR, POPRET PVC, PCALL / |
Added cc8/os8/init.pa.
> | 1 | ../include/init.pa |
Added cc8/os8/libc.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | #asm / / PDP8/E lIBC routines for Small c compiler / THIS IS A COMPLEX COLLECTION OF MIXED C AND ASSEMBLER / SOME FUNCTIONS HAVE BEEN SUBSTANTIALLY SHORTENED TO SAVE SPACE / EVENTUALLY, MOST WILL NEED TO BE WRITTEN IN ASSEMBLER AND HAND OPTIMISED EG ATOI / ABSYM POP 147 ABSYM PSH 150 ABSYM JLC 151 ABSYM STKP 152 ABSYM PTSK 153 ABSYM POPR 154 ABSYM PCAL 155 ABSYM TMP 156 ABSYM GBL 157 ABSYM ZTMP 146 ABSYM ZPTR 145 ABSYM ZCTR 144 ABSYM FPTR 160 / DECIM / / / / DUMMY ARGST DUMMY ARGNM ARGST, BLOCK 2 ARGNM, BLOCK 2 / ENTRY LIBC LIBC, BLOCK 2 CLA CLL TAD I LIBC DCA ARGST INC LIBC# TAD I LIBC DCA ARGST# INC LIBC# TAD I ARGST DCA STKP IAC TAD LCALL / INIT ? LCALL==-1 SZA CLA JMP LB1 TAD STKP DCA GBL / SET LOCAL GBL(LITPTR) ISZ GBL TAD PVL DCA PSH TAD OVL DCA POP TAD MVL DCA PTSK TAD PVR DCA POPR TAD PVC DCA PCAL RIF TAD (3201 DCA PCL1 TAD PCL1 DCA DCC0 JMS MCC0 TAD STKP DCA I ARGST / UPDATE MASTER STKP DCA ZPTR / INIT PRINTF FLAG DCA FPTR / INIT FPRINTF FLAG LB1, MQA / CALL INDEX IN MQ SPA JMP LRET TAD CPNT DCA LCALL TAD I LCALL DCA LCALL JMSI PCAL LCALL, -1 RETRN LIBC LRET, CLA MQL DCA LCALL / INIT OK RETRN LIBC / PUSH, 0 CDF1 ISZ STKP DCAI STKP TADI STKP JMPI PUSH PPOP, 0 CDF1 DCA TMP TADI STKP MQL CMA TAD STKP DCA STKP TAD TMP JMPI PPOP PUTSTK, 0 JMSI POP SWP DCA JLC SWP DCAI JLC TADI JLC JMPI PUTSTK POPRET, JMSI POP SWP DCA ZTMP TAD STKP DCA I ARGST / UPDATE MASTER STKP SWP CDF1 JMPI ZTMP PCALL, 0 CLA CLL PCL1, 0 TADI PCALL DCA ZTMP TAD PCALL IAC JMSI PSH / PUSH RETURN CLA TAD STKP DCA I ARGST / UPDATE MASTER STKP CDF1 JMPI ZTMP PVL, PUSH OVL, PPOP MVL, PUTSTK PVR, POPRET PVC, PCALL / CPNT, CLIST CPAGE 24 / / THIS IS THE DISPATCH LIST FOR THIS LIBRARY / MAKE SURE LIBC.H MATCHES / CLIST, ITOA PUTS DISPXY GETC GETS ATOI SSCANF XINIT MEMCPY KBHIT PUTC STRCPY STRCAT STRSTR EXIT ISNUM ISALPHA SPRINTF MEMSET FGETC FOPEN FPUTC FCLOSE PRINTF ISALNUM ISSPACE FPRINTF FPUTS STRCMP CUPPER FGETS #endasm #define stdout 0 #define NULL 0 #define isdigit isnum fgetc() { #asm CLA CLL CALL 2,CHRIO ARG (-4 ARG FRSL TAD FRSL TAD (-26 /^Z SNA CLA DCA FRSL TAD FRSL CDF1 JMPI POPR FRSL,BLOCK 2 // CHRIO - CHARACTER I/O. / / CALL CHRIO(IDEVN,ICHAR) / / IDEV = FORT II DEVICE NUMBER. / / ICHAR = 7 OR 8 BIT CHARACTER. / / IF IDEV IS POSITIVE, THE CHAR IS OUTPUTTED. / / IF IDEV IS NEGATIVE, THE NEXT CHAR IS / READ FROM THE DEVICE, AND PUT IN ICHAR. / // ENTRY CHRIO CHRIO, BLOCK 2 JMS GETP SPA /WHAT IS DEVICE SIGN? JMP RCHAR /NEG DEV. MEANS READ. JMS SETDEV /POS DEV. MEANS WRITE. 0000 JMS GETP DCA ICHAR JMS CHSUB JMP XIT IDEV, 0 ICHAR, 0 ADDR, 0 RCHAR, CIA /READ A CHAR. JMS SETDEV 1024 /SET BIT FOR READ. (8 UNITS NOW!) JMS GETP CLA TAD CDFB DCA CDFCH JMS CHSUB CDFCH, HLT AND (127 / 7 BIT FOR NOW DCAI ADDR XIT, CLA RETRN CHRIO SETDEV, 0 TAD (-1 AND (7 CLL RAR;RTR;RTR TAD I SETDEV INC SETDEV DCA IDEV JMP I SETDEV CHSUB, 0 TAD ICHAR AND (255 TAD IDEV CALL 0,GENIO JMP I CHSUB GETP, 0 TAD CHRIO DCA CDFA CDFA, HLT TADI CHRIO# DCA CDFB INC CHRIO# TADI CHRIO# DCA ADDR INC CHRIO# CDFB, HLT TADI ADDR JMP I GETP #endasm } fputc(ch) int ch; { ch; #asm DCA FRSL CALL 2,CHRIO ARG (4 ARG FRSL CDF1 TAD FRSL #endasm } sixbit(p) char *p; { *p++; #asm AND (63 BSW MQL #endasm *p; #asm AND (63 MQO #endasm } fputs(p) int *p; { while (*p++) #asm DCA FRSL CALL 2,CHRIO ARG (4 ARG FRSL CDF1 #endasm } fopen (fnm,flg) char *fnm; int flg; { char *p; p=fnm; p=strstr(fnm,"."); if (p==0) return(-1); if (*flg=='w') { #asm CLA TAD FC1# DCA FBSE# JMP FC3 FC1, CALL 0,OOPEN FC2, CALL 0,IOPEN #endasm } if (*flg=='r') { #asm CLA TAD FC2# DCA FBSE# FC3, CDF1 #endasm *p++=0; sixbit(p); #asm PAGE / OFFSET IOPEN+81 = FILEEX DCA ZTMP TAD FC2# / CODE AND (63 TAD (128 DCA FDCT CDF0 TADI FDCT DCA FEX1 TAD FDCT TAD (64 DCA FDCT TADI FDCT TAD (81 / OFFSET OF EXTENSION DCA FDCT FEX1, HLT TAD ZTMP DCAI FDCT CDF1 #endasm fnm; #asm DCA ZTMP / PACK 6 8BIT CHARS INTO FILENAME TAD (-3 DCA FDCT TAD FDCA DCA FP4 FP1, CAM TADI ZTMP SNA JMP FP2 AND (63 BSW MQL ISZ ZTMP FP2, TADI ZTMP / WILL USE STACK FIELD AND (63 SZA ISZ ZTMP MQO FP4, DCA FFNM ISZ FP4 ISZ FDCT JMP FP1 TAD (46 DCAI ZTMP / PUT . BACK INTO FNM CLA CLL CMA TAD STKP DCA STKP FBSE, CALL 2,IOPEN ARG FDEV ARG FFNM JMPI POPR FDCA, DCA FFNM FDCT, 0 FFNM, TEXT /TM@@@@/ FDEV, TEXT /DSK@@@/ #endasm } } fclose() { #asm CALL 0,OCLOS #endasm } puts(p) char *p; { while (*p++) #asm TLS XC1, TSF JMP XC1 #endasm } dispxy(x,y) int x,y; { x; #asm 3115 / DIX #endasm y; #asm 3116 / DIY 3117 / DIL #endasm } getc() { #asm CLA GT1, KSF JMP GT1 KRB TLS AND (127 /* 7 BIT! */ #endasm } gets(p) char *p; { int q,tm; tm=1; q=p; while (tm) { #asm XC2, CLA CLL KSF JMP XC2 KRB TAD (-255 CLA KRB SNL / DO NOT ECHO BS TLS XC3, AND (127 TAD (-13 / CR IS END OF STRING -> 0 SZA TAD (13 DCAI STKP #endasm if (tm!=127) *p++=tm; else if (p-q) { puts("\b \b"); p--; } } putc(10); /* newline */ return 1; } atoi(p,rsl) char *p; int *rsl; { #asm DCA ZTMP DCA ZCTR TAD (3584 / NOP DCA XINV CDF1 / Change DF back to 1 in case SABR changes it! #endasm while (*p==' ') p++; if (*p=='-') { #asm CLA TAD (3617 DCA XINV / CIA CDF1 #endasm p++; } while (*p++) { #asm TAD (-48 / '0' ... SEE CODE DCA JLC TAD JLC SPA CLA JMP XRET TAD (-10 TAD JLC SMA CLA JMP XRET / EXIT IF NOT NUMBER TAD ZTMP CLL RTL / *4 TAD ZTMP / *5 CLL RAL / *10 TAD JLC DCA ZTMP ISZ ZCTR / CHAR COUNTER #endasm } #asm XRET, TAD ZCTR MQL CMA TAD STKP / ->RSL DCA TMP TADI TMP DCA TMP TAD ZTMP XINV, NOP DCAI TMP / WRITE RSL MQA / RETURN LENGTH #endasm } xinit() { puts("PDP-8 C Compiler V1.0:\r\n"); } memcpy(dst,src,cnt) int dst,src,cnt; { #asm CLA TAD STKP TAD (-4 DCA 12 CMA TADI 12 DCA 11 CMA TADI 12 DCA 10 TADI 12 CIA DCA ZTMP CP1, TADI 10 DCAI 11 ISZ ZTMP JMP CP1 #endasm } kbhit() { #asm CLA CMA KSF CLA #endasm } putc(p) char p; { p; #asm TLS MP1, TSF JMP MP1 #endasm } strcmp( dm , sm ) char *dm,*sm; { int rsl; rsl=0; while (*dm) rsl+=(*sm++-*dm++); return rsl; } strcpy( dm , sm ) char *dm,*sm; { while (*dm++=*sm++); } strcat( dm , sm ) char *dm,*sm; { int qm; qm=dm; while(*dm) dm++; strcpy(dm,sm); return qm; } strstr ( s , o ) char *s , *o ; { char *x , *y , *z ; for ( x = s ; * x ; x ++ ) { for ( y = x , z = o ; * z && * y == * z ; y ++ ) z ++ ; if ( z > o && ! * z ) return x ; } return 0 ; } exit(retval) int retval; { #asm CALL 0,EXIT HLT #endasm } isalnum(vl) int vl; { return (isnum(vl) + isalpha(vl)); } isnum(vl) int vl; { vl; #asm TAD (-48 SPA JMP XNO TAD (-10 SMA CLA XNO, CLA SKP IAC #endasm } isspace(vl) int vl; { vl; #asm SNA JMP YNO TAD (-33 SMA CLA YNO, CLA SKP IAC #endasm } isalpha(vl) int vl; { vl; /* Include '?' and '@' as alpha vars */ #asm TAD (-65 SPA JMP ANO TAD (-26 SPA JMP BNO TAD (-6 SPA JMP ANO TAD (-26 BNO, SMA CLA ANO, CLA SKP IAC #endasm } cupper(p) /* In place convert to uppercase */ int p; { p; #asm DCA ZTMP CPP1, CLA TADI ZTMP SNA JMP CPP2 TAD (-97 SPA JMP CPP3 TAD (-26 SMA JMP CPP3 TAD (91 DCAI ZTMP CPP3, ISZ ZTMP JMP CPP1 CPP2, #endasm } /* Arbitrary fgets(). Read until LF, CR/LF are retained*/ /* EOF returns null, else strlen(*p) */ fgets(p) char *p; { char *q; q=p; while(*p=fgetc()) { if (*p++==10) break; } *p=0; return (p-q); } memset(dst, dt, sz) char *dst; int dt,sz; { int i; for (i=0;i<sz;i++) *dst++=dt; } /* ** reverse string in place */ reverse(s) char *s; { char *j; int c; j = s + strlen(s) - 1; while(s < j) { c = *s; *s++ = *j; *j-- = c; } } /* This is somewhat involved in that the vararg system in SmallC is rather limited. For printf and sprintf, a char buffer is required supplied by the user or, as below, located at the end of the stack (7500 .. 64 locs). In addition, another page zero location (ZPTR) is required. This is always risky as the SABR/LOADER system uses a lot of locations here. See how this goes as it is possible to use arbitrary localions on the stack as well. */ fprintf(nxtarg) int nxtarg; { #asm ISZ FPTR JMP PRINTF #endasm } printf(nxtarg) int nxtarg; { #asm TAD (3904 / THIS IS THE PRINT BUFFER AT 7500 ON THE STACK DCA ZPTR JMP SPRINTF #endasm } /* ** sprintf(obfr, ctlstring, arg, arg, ...) ** Called by printf(). */ sprintf(nxtarg) int nxtarg; { int arg, left, pad, cc, len, maxchr, width; char *ctl, *sptr, str[17],*obfr,zptr; #asm TAD ZPTR DCAI STKP / POINTS TO ZPTR #endasm cc = 0; nxtarg = &nxtarg-nxtarg; if (zptr) obfr=zptr; else obfr = *nxtarg++; ctl = *nxtarg++; while(*ctl) { if(*ctl!='%') {*obfr++=*ctl++; ++cc; continue;} else ++ctl; if(*ctl=='%') {*obfr++=*ctl++; ++cc; continue;} if(*ctl=='-') {left = 1; ++ctl;} else left = 0; if(*ctl=='0') pad = '0'; else pad = ' '; width=0; if(isdigit(*ctl)) { ctl+=atoi(ctl, &width); } maxchr=0; if(*ctl=='.') { ctl+=atoi(++ctl,&maxchr)+1; } arg = *nxtarg++; sptr = str; switch(*ctl++) { case 'c': str[0] = arg; str[1] = NULL; break; case 's': sptr = arg; break; case 'd': itoa(arg,str); break; case 'b': itoab(arg,str,2); break; case 'o': itoab(arg,str,8); break; case 'u': itoab(arg,str,10); break; case 'x': itoab(arg,str,16); break; default: return (cc); } len = strlen(sptr); if(maxchr && maxchr<len) len = maxchr; if(width>len) width = width - len; else width = 0; if(!left) while(width--) {*obfr++=pad; ++cc;} while(len--) {*obfr++=*sptr++; ++cc; } if(left) while(width--) {*obfr++=pad; ++cc;} } *obfr=0; zptr; #asm SNA / IF ZPTR, EITHER USE PUTS OR FPUTS JMP PF1 JMSI PSH CLA TAD FPTR SNA CLA JMP PF2 JMSI PCAL FPUTS JMP PF3 PF2, JMSI PCAL PUTS PF3, JMSI POP PF1, CLA DCA ZPTR DCA FPTR #endasm return(cc); } /* ** itoa(n,s) - Convert n to characters in s */ itoa(n, s) char *s; int n; { int sign; char *ptr; ptr = s; if ((sign = n) < 0) n = -n; do { *ptr++ = n % 10 + '0'; } while ((n = n / 10) > 0); if (sign < 0) *ptr++ = '-'; *ptr = '\0'; reverse(s); } /* ** itoab(n,s,b) - Convert "unsigned" n to characters in s using base b. ** NOTE: This is a non-standard function. */ itoab(n, s, b) int n; char *s; int b; { char *ptr; int lowbit; ptr = s; b >>= 1; do { lowbit = n & 1; n = (n >> 1) & 4095; *ptr = ((n % b) << 1) + lowbit; if(*ptr < 10) *ptr += '0'; else *ptr += 55; ++ptr; } while(n /= b); *ptr = 0; reverse (s); } strlen(p) char *p; { int n; n=0; while (*p++) n++; return n; } #define EOF 0 sscanf(nxtarg) int nxtarg; { char *ctl; int u; int *narg, wast, ac, width, ch, cnv, base, ovfl, sign, *ibfr; ac = 0; nxtarg = &nxtarg-nxtarg; ibfr = *nxtarg++; ctl = *nxtarg++; while(*ctl) { if(*ctl++ != '%') continue; narg = *nxtarg++; ctl += atoi(ctl, &width); if (!width) width=-1; if(!(cnv = *ctl++)) break; switch(cnv) { case 'c': *narg = *ibfr++; break; case 's': while(width--) if((*narg++ = *ibfr++) == 0) break; *narg = 0; break; default: switch(cnv) { case 'b': base = 2; break; case 'd': base = 10; break; case 'o': base = 8; break; case 'x': base = 16; break; default: return (ac); } *narg = u = 0; sign = 1; while(width-- && (ch=*ibfr++)>32) { if(ch == '-') {sign = -1; continue;} if(ch < '0') break; if(ch >= 'a') ch -= 87; else if(ch >= 'A') ch -= 55; else ch -= '0'; u = u * base + ch; } *narg = sign * u; } ++ac; } return (ac); } |
Added cc8/os8/n8.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 | #include <libc.h> #include <init.pa> #define SMAX 10 #define CMAX 256 #define BMAX 64 #define LMAX 32 #define DMAX 32 #define CBMX 1024 #define LXMX 999 int asm[CBMX]; int ltbf[512]; int xlt[CMAX]; int gm[CMAX]; /* Global symbol table */ int tkbf[LMAX]; int *p,*q,*s,*ltpt; int gsym,lsym,gadr,ladr,stkp,lctr,*fptr,gsz,ctr,tm,ectr; int glim,*n,ccm; int tmp; int tkn[BMAX]; int bfr[BMAX]; int tmbf[LMAX]; int smbf[LMAX]; int Lb[BMAX]; int lm[CMAX]; /* Auto symbol table */ int fstk[BMAX]; /* Push down stack for For etc. */ int inproc,addr,cbrk; int izf,ixf,idf,ieq,ssz,icd; getsym() { q=tkbf; while (isspace(*p)) p++; while (isalnum(*p)) *q++=*p++; *q=0; while (isspace(*p)) p++; return *tkbf; } chkpsh() { switch (*p) { case 0: case ',': case ')': case '=': case ']': case ' ': return; } stri(19); stkp++; } /* recursive descent parser for arithmetic/logical expressions */ S( ) { J( ); switch(*p++){ case '=': S(); stri(1); stkp--; break; case ']': case ')': return 1; case ',': break; default: p--; } if (ieq) { ieq=0; S(); stri(24); stkp--; } return 0; } /* end S */ J( ) { K( ); switch(*p++){ case '&': J( ); stri(20); stkp--; break; case '|': J( ); stri(-20); stkp--; break; default: p--; } } /* end J */ K( ) { V( ); switch(*p++){ case '<': K( ); stri(11); stkp--; break; case '>': K( ); stri(-11); stkp--; break; default: p--; } } /* end K */ V( ) { W( ); switch(*p++){ case '+': V(); stri(2); stkp--; break; case '-': V( ); stri(3); stkp--; break; default: p--; } } /* end V */ W( ) { Y( ); chkpsh(); switch(*p++) { case '*': W( ); stri(13); stkp--; break; case '/': W( ); stri(14); stkp--; break; default: p--; } } /* end W */ Y( ) { int o,ctx; int txbf[10]; while (*p==' ') p++; if (!*p) return; if (*p=='"') { stri(10); stri(ltpt-ltbf); while (*++p!='"') { if (*p=='\\') switch (*++p) { case 'r': *p=13; break; case 'n': *p=10; } *ltpt++=*p; } *ltpt++=0; p++; return; } n=q=p; if (*p=='-') p++; if(isdigit(*p)) { while(isdigit(*p)) p++; stri(4); atoi(q,&tmp); stri(tmp); return; } if (*p==39) { stri(4); stri(*++p); p+=2; return; } ixf=izf=idf=ieq=icd=0; if (!getsym()) { switch (*p++) { case '&': getsym(); stri(21); stri(fndlcl(tkbf)); return; case '*': getsym(); ixf++; break; case '!': Y(); stri(26); return; case '(': S(); return; case ')': icd=1; return; } } if(*p=='('){ strcpy(txbf,tkbf); ctx=o=0;p++; while (*p && !o) { o=S( ); if (icd) break; stkp++; stri(19); ctx++; /* arg count */ } stri(9); stri(ctx); stkp-=ctx; if ((o=strstr(gm,txbf))){ stri(o-gm); } else { stri(gsz); strpad(txbf); strcat(gm,smbf); gsz+=9; } return; } /* Digraphs */ q=p+1; if (tmp=*q==*p) switch (*p) { case '+': izf=-tmp; p+=2; break; case '-': idf=-tmp; p+=2; break; case '=': ieq=-tmp; p=q+1; break; } o=fndlcl(tkbf); tmp=-17; if (ssz>1) { if (*p=='[') { stri(21); stri(o); stri(19); stkp++; p++;S(); stri(2); if (*p=='=') stri(19); else { stri(22); stkp--; } return; } stri(21); stri(o); return; } switch (*p) { case 0: case ',': case ')': tmp=-17; break; case '=': tmp=8; if (ixf) tmp=-8; ixf=0; stkp++; default: break; } stri(tmp); stri(o); if (*n=='-') stri(27); if (izf) stri(15); if (idf) stri(25); if (ixf) stri(22); return; } /* end Y */ procst(trm) char trm; { ccm=ctr=1; p=q=Lb; while(1) { tm=fgetc(); ctr-=tm=='('; ctr+=tm==')'; ccm-=tm==','; if (!ctr || tm==trm) break; *q++=tm; } *q=0; if (inproc) while (*p) S(); } strpad(sym) char *sym; { char *a,*b; strcpy(a=smbf," "); /* 9 spaces */ while (*sym) *a++=*sym++; } addsym(sym,sz) char *sym; int sz; { strpad(sym); smbf[8]=sz; if (inproc+(sz<0)) { smbf[7]=stkp+1; stkp+=sz; strcat(lm,smbf); stri(6); stri(sz); return; } smbf[7]=gadr; gadr+=sz; strcat(gm,smbf); gsz+=9; } fndlcl(sym) char *sym; { strpad(sym); smbf[7]=0; if (s=strstr(lm,smbf)) { ssz=s[8]; s=s+7; return *s-stkp; } if (s=strstr(gm,smbf)) { ssz=s[8]; s=s+7; return *s; } return 0; } gettk() { char xtm; q=tkbf; while (isspace(xtm=fgetc())); while (isalnum(xtm)) { *q++=xtm; xtm=fgetc(); } *q=0; return xtm; } popfr() { while (*fptr==inproc) { cbrk=*--fptr; stri(23); stri(*--fptr); stri(5); stri(*fptr+2); fptr--; } } dostt() { p=tmbf; while (tm!=';') { *p++=tm; tm=fgetc(); } *p=0; strcpy(Lb,tkbf); strcat(Lb,tmbf); p=Lb; S(); tm=1; } fnbrk() { while (tm!='(') tm=fgetc(); } next() { char *lp; int fflg; lp=0; if (*tkbf) { strcat(tkbf," "); lp=strstr(tkn,tkbf); } fflg=lctr; if (lp) { switch(lp-tkn) { case 0: while (tm!=';' && tm!='{') { tm=gettk(); strcpy(bfr,tkbf); while (isspace(tm)) tm=fgetc(); switch (tm) { case '[': tm=gettk(); atoi(tkbf,&fflg); addsym(bfr,fflg); tm=fgetc(); break; case '(': stri(7); stri(gsz); if (strstr("main",tkbf)) strcpy(tkbf,"XMAIN"); addsym(tkbf,1); procst(')'); stkp=-(ccm+1); while (*p) { getsym(); addsym(tkbf,-1); p++; stkp+=2; } stkp=0; tm=gettk(); cbrk=100; break; case ',': case ';': addsym(tkbf,1); break; } /* end whie */ } /* end case 0: */ break; case 4: fflg=fflg+100; case 12: fnbrk(); stri(5); *++fptr=fflg; stri(fflg); procst(0); stri(12); stri(tm=*fptr+2); *++fptr=cbrk; if (fflg<100) cbrk=tm; *++fptr=inproc; lctr+=3; tm=0; stri(99); break; case 7: tm=0; break; case 18: stri(23); stri(cbrk); break; case 24: procst(';'); stri(23); stri(ectr); tm=1; break; case 31: fnbrk(); procst(';'); stri(5); stri(lctr++); *++fptr=lctr; procst(';'); stri(12); stri(lctr+2); stri(23); stri(lctr+1); stri(5); stri(lctr++); procst(')'); *++fptr=cbrk; *++fptr=inproc; stri(23); stri(lctr-2); stri(5); stri(lctr++); lctr++; tm=0; break; default: dostt(); } /* End switch */ } else switch (tm) { case '{': tm=1; inproc++; break; case '}': break; case -1: case 0: stri(0); #asm CALL 1,CHAIN ARG FNM HLT FNM, TEXT "CC2@@@" #endasm case '/': while (fgetc()!='/'); /* Skip comment */ tm=1; break; default: dostt(); } return tm; } main() { char trm; memset(ltbf,0,&ssz-ltbf); fopen("CC.CC","r"); strcpy(tkn,"int if else while break return for "); lctr = 10; ectr = 900; ltpt = ltbf; fptr = fstk; *fptr = -1; gadr = 128; /* Start of globals */ iinit(asm); tm=gettk(); while (1) { trm=next(); tm=gettk(); switch (trm) { case '{': inproc++; break; case '}': inproc--; if (!inproc) { stri(5); stri(ectr++); stri(16); stri(-stkp); stkp = *lm = 0; break; } case ';': case 1: stri(99); if (!strcmp("else",tkbf)) { stri(-23); stri(100+lctr+2); popfr(); *++fptr=100+lctr++; *++fptr=cbrk; *++fptr=inproc; } else popfr(); case 0: break; default: procst(';'); } } } |
Added cc8/os8/os8.sb.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 | #asm / / PDP8/E Run time routines for Small c compiler / ABSYM POP 160 ABSYM PSH 161 ABSYM JLC 162 ABSYM STKP 163 ABSYM PTSK 164 ABSYM POPR 165 ABSYM PCAL 166 ABSYM TMP 167 ABSYM GBL 170 ABSYM ZTMP 171 / DECIM / STK, COMMN 3840 / / / ENTRY MAIN MAIN, BLOCK 2 TAD GBLS DCA STKP TAD GBLS TAD (2 / ACTUAL START AFTER A NULL AND 1 WORD CALL DCA GBL TAD PVL DCA PSH TAD OVL DCA POP TAD MVL DCA PTSK TAD PVR DCA POPR TAD PVC DCA PCAL RIF TAD (3201 DCA PCL1 TAD PCL1 DCA DCC0 JMSI PCAL XMAIN CALL 0,EXIT / PUSH, 0 CDF1 ISZ STKP DCAI STKP TADI STKP JMPI PUSH PPOP, 0 CDF1 DCA TMP TADI STKP MQL CMA TAD STKP DCA STKP TAD TMP JMPI PPOP PUTSTK, 0 JMSI POP SWP DCA JLC SWP DCAI JLC TADI JLC JMPI PUTSTK POPRET, JMSI POP SWP DCA ZTMP SWP JMPI ZTMP PCALL, 0 CLA CLL PCL1, 0 TADI PCALL DCA ZTMP TAD STKP DCAI (163 / ADDRESS OF STKP TAD PCALL IAC JMSI PSH / PUSH RETURN CLA JMPI ZTMP PVL, PUSH OVL, PPOP MVL, PUTSTK SVL, STK PVR, POPRET PVC, PCALL / #endasm /* Comparison routines */ outdec (number) int number; { #asm CLA CLL CMA TAD STKP / STKP-1 -> ARG DCA VAL# CALL 2,WRITE ARG (1 ARG FMT CALL 1,IOH VAL, ARG 0 CALL 1,IOH ARG 0 JMSI POPR FMT, TEXT /(I5)/ #endasm } outstr(p) char *p; { while (*p++) #asm TLS XC1, TSF JMP XC1 #endasm } nl() { outstr("\r\n"); } getch() { #asm CLA GT1, KSF JMP GT1 KRB #endasm } instr(p) char *p; { int q,tm; tm=1; q=p; while (tm) { #asm XC2, CLA MQL KSF JMP XC2 KRB TLS XC3, AND (127 SWP TAD STKP JMSI PSH MQA JMSI PTSK #endasm if (tm==13) tm=0; if (tm==127) { if (p-q) { p--; outstr("\b \b"); } } else { *p++=tm; } } outstr("\n"); return 1; } atoi(p) char *p; { #asm DCA ZTMP TAD (3584 / NOP DCA XINV CDF1 / Change DF back to 1 in case SABR changes it! #endasm while (*p==' ') p++; if (*p=='-') { #asm CLA TAD (3617 DCA XINV / CIA CDF1 #endasm p++; } while (*p++) { #asm TAD (-48 / '0' ... SEE CODE DCA JLC TAD JLC SPA CLA JMP XRET TAD (-10 TAD JLC SMA CLA JMP XRET TAD ZTMP CLL RTL TAD ZTMP CLL RAL TAD JLC DCA ZTMP #endasm } #asm XRET, TAD ZTMP XINV, NOP #endasm } cend() { #asm CLA SKP CX, CCEND TAD CX #endasm } xinit() { outstr("PDP-8 C Compiler V1.0:"); poct(cend()); nl(); } /* Excluded at present #asm PAGE NARG, 0 PFMT, BLOCK 20 PXFMT, PFMT SCF, CALL 0,READ PTF, CALL 0,WRITE QTF, JMP PL11 QMF, NOP SCANF, CIA DCA NARG TAD SCF# DCA PL9# TAD QMF DCA PL12 JMP PL10 PRINTF, CIA DCA NARG TAD PTF# DCA PL9# TAD QTF DCA PL12 PL10, TAD STKP TAD NARG DCA JLC TADI JLC DCA JLC TAD PXFMT DCA TMP PL1, CDF1 TADI JLC SNA JMP PL2 AND (63 CLL RTL;RTL;RTL MQL ISZ JLC TADI JLC SNA JMP PL21 AND (63 MQO CDF0 DCAI TMP ISZ TMP ISZ JLC JMP PL1 PL21, MQO PL2, CDF0 DCAI TMP PL9, CALL 2,WRITE ARG (1 ARG PFMT PL4, ISZ NARG SKP JMP PL3 TAD STKP TAD NARG PL12, NOP DCA JLC CDF1 TADI JLC PL11, DCA PL5# CALL 1,IOH PL5, ARG 0 JMP PL4 PL3, CALL 1,IOH ARG 0 JMSI POPR #endasm */ disp(x,y) int x,y; { #asm OCTAL OPDEF DISPX 6053 OPDEF DISPY 6054 OPDEF INTEN 6055 SKPDF DSSKP 6052 OPDEF DSCLR 6050 DECIM TAD STKP TAD (-1 DCA JLC TADI JLC DISPY CLA TAD STKP TAD (-2 DCA JLC TADI JLC DISPX CLA INTEN DS1, DSSKP JMP DS1 DSCLR #endasm } kbhit() { #asm CLA CMA KSF CLA #endasm } putchar(p) char p; { p; #asm TLS MP1, TSF JMP MP1 #endasm } strcpy( dm , sm ) char *dm,*sm; { while (*sm) *dm++=*sm++; *dm=0; } strcat( dm , sm ) char *dm,*sm; { int qm; qm=dm; while(*dm) dm++; strcpy(dm,sm); return qm; } strstr ( s , o ) char *s , *o ; { char *x , *y , *z ; for ( x = s ; * x ; x ++ ) { for ( y = x , z = o ; * z && * y == * z ; y ++ ) z ++ ; if ( z > o && ! * z ) return x ; } return 0 ; } cexit(retval) int retval; { #asm CALL 0,EXIT HLT #endasm } isnum(vl) int vl; { vl; #asm TAD (-48 SPA JMP XNO TAD (-10 SMA CLA XNO, CLA SKP IAC #endasm } isalpha(vl) int vl; { vl; /* Include '?' and '@' as alpha vars */ #asm TAD (-63 SPA JMP ANO TAD (-28 SMA CLA ANO, CLA SKP IAC #endasm } poct(vl) int vl; { vl; #asm CLL RAL DCA TMP TAD (-4 DCA PCTR PWR0, TAD TMP RAL RTL DCA TMP TAD TMP AND (7 TAD (48 TLS PRW1, TSF JMP PRW1 CLA ISZ PCTR JMP PWR0 PCTR, 0 #endasm } /* Not included */ pdec(vl) int vl; { if (vl&2048) { vl=-vl; putchar('-'); } vl; #asm CPAGE 52 ARW7, SZA JMP ARW6 TAD (-1 DCA CZB JMP ARW8 ARW6, DCA VALUE DCA DIGIT DCA AFLG TAD (-4 DCA CZB TAD AZA DCA ARW SKP ARW4, DCA VALUE CLL ARW2, TAD VALUE ARW, TAD TENPWR SZL ISZ DIGIT SZL JMP ARW4 CLA TAD DIGIT SZA CLA JMP ARW5 TAD AFLG SNA CLA JMP ARW3 /SKIP LEADING ZEROES ARW5, ISZ AFLG TAD DIGIT ARW8, TAD (48 TLS ARW3, TSF JMP ARW3 CLA DCA DIGIT ISZ ARW ISZ CZB JMP ARW2 JMP CZB /WILL NOW BE 0 AZA, TAD TENPWR TENPWR, -1000 -100 -10 -1 VALUE, 0 DIGIT, 0 AFLG, 0 CZB, 0 #endasm } |
Added cc8/os8/p8.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | #include <libc.h> #include <init.pa> #define SMAX 10 #define CMAX 256 #define BMAX 64 #define LMAX 32 #define DMAX 32 #define CBMX 1024 #define LXMX 999 int asm[CBMX]; int ltbf[512]; int xlt[CMAX]; int gm[CMAX]; /* Global symbol table */ int tkbf[LMAX]; int *p,*q,*s,*ltpt; int gsym,lsym,gadr,ladr,stkp,*as,lctr,*fptr,gsz,ctr,tm,ectr; int glim; int ltsz,pflg,t; int tmstr[32]; main() { as=asm; fopen("HEADER.SB","r"); fopen("CC.SB","w"); strcpy(xlt,"ITOA PUTS DISPXY GETC GETS ATOI SSCANF XINIT MEMCPY KBHIT PUTC STRCPY STRCAT STRSTR EXIT ISNUM "); strcat(xlt,"ISALPH SPRINTF MEMSET FGETC FOPEN FPUTC FCLOSE PRINTF ISALNUM ISSPACE FPRINTF FPUTS STRCMP CUPPER FGETS "); while (t=fgetc()) if (t!=12) /* Ignore form feed */ fputc(t); cupper(gm); while (*as) { pflg=0; *tmstr=0; switch (*as++) { case 99: fprintf("/\r"); break; case 1: fprintf("\tJMSI PTSK\r"); break; case 3: strcpy(tmstr,"\tCIA\r"); case 2: fprintf("%s\tTADI STKP\r\tJMSI POP\r",tmstr); break; case 4: fprintf("\tCLA\r\tTAD (%d\r",*as++); break; case 5: if (*as<0) *as=100-*as; fprintf("CC%d,\r",*as++); break; case 6: if (*as>1) fprintf("\tTAD STKP\r\tTAD (%d\r\tDCA STKP\r",*as); else if (*as>0) fputs("\tISZ STKP\r"); as++; break; case 7: p=gm+*as++; while (*p-' ') fputc(*p++); fputs(",\r"); break; case -8: strcpy(tmstr,"\tDCA JLC\r\tTADI JLC\r"); case 8: if (*as>0) fprintf("\tCLA\r\tTAD (%d\r%s\tJMSI PSH\r",*as++,tmstr); else fprintf("\tCLA\r\tTAD STKP\r\tTAD (%d\r%s\tJMSI PSH\r",*as++,tmstr); break; case 9: tm=*as++; p=gm+*as++; strcpy(tkbf," "); memcpy(tkbf,p,7); if (p=strstr(xlt,tkbf)) { t=(p-xlt)>>3; if ((t==6) + (t==17) + (t==23)) fprintf("\tCLA\r\tTAD (%d\r\tJMSI PSH\r",tm++); fprintf("\tCLA\r\tTAD (%d\r\tMQL\r\tCALL 1,LIBC\r\tARG STKP\r\tCDF1\r",t); } else fprintf("\tJMSI PCAL\r\t%s\r",tkbf); if (tm) fprintf("\tMQL\r\tTAD (%d\r\tTAD STKP\r\tDCA STKP\r\tSWP\r",-tm); break; case 10: fprintf("\tCLA\r\tTAD GBL\r\tTAD (%d\r",*as++); break; case -11: fprintf("\tCIA\r\tTADI STKP\r\tJMSI POP\r\tSMA SZA CLA\r\tCMA\r"); break; case 11: fprintf("\tCIA\r\tTADI STKP\r\tJMSI POP\r\tSPA CLA\r\tCMA\r"); break; case 12: fprintf("\tSNA\r\tJMP CC%d\r",*as++); break; case 13: fprintf("\tJMSI POP\r\tDCA JLC\r\tSWP\r\tCALL 1,MPY\r\tARG JLC\r\tCDF1\r"); break; case 14: fprintf("\tJMSI POP\r\tDCA JLC\r\tSWP\r\tCALL 1,DIV\r\tARG JLC\r\tCDF1\r"); break; case 15: fprintf("\tISZI JLC\r\tNOP\r"); break; case 16: fprintf("\tMQL\r\tTAD STKP\r\tTAD (%d\r\tDCA STKP\r\tSWP\r\tJMPI POPR\r/\r",*as++); break; case 17: pflg++; case -17: if (*as>0) fprintf("\tCLA\r\tTAD (%d\r\tDCA JLC\r\tTADI JLC\r",*as++); else fprintf("\tCLA\r\tTAD STKP\r\tTAD (%d\r\tDCA JLC\r\tTADI JLC\r",*as++); if (pflg==0) break; case 19: fprintf("\tJMSI PSH\r"); break; case 20: fprintf("\tANDI STKP\r\tJMSI POP\r"); break; case -20: fprintf("\tJMSI POP\r\tMQA\r"); break; case 21: if (*as>0) fprintf("\tCLA\r\tTAD (%d\r",*as++); else fprintf("\tCLA\r\tTAD STKP\r\tTAD (%d\r",*as++); break; case 22: fprintf("\tDCA JLC\r\tTADI JLC\r"); break; case 23: if (*as<100) fprintf("\tJMP CC%d\r",*as); as++; break; case -23: fprintf("\tJMP CC%d\r",*as++); break; case 24: fprintf("\tCIA\r\tTADI STKP\r\tJMSI POP\r\tSNA CLA\r\tCMA\r"); break; case 25: fprintf("\tMQL\r\tCMA\r\tTADI JLC\r\tDCAI JLC\r\tSWP\r"); break; case 26: fprintf("\tSNA CLA\r\tCMA\r"); break; case 27: fputs("\tCIA\r"); } } ltsz=ltpt-ltbf; fprintf("\tLAP\r\tCPAGE %d\rLCC0,\t%d\rXCC0,\tCC0\rCC0,\t\r",ltsz+2,-ltsz); p=ltbf; while (ltsz) { fprintf("%d",*p++); if (ltsz>1) fputs("; "); if ((ltsz&7)==0) fputc(13); ltsz--; } fprintf("\r\tEAP\rGBLS,\t%d\r",gadr); fprintf("\rMCC0,\t0\r\tCDF1\r\tTAD LCC0\r\tSNA CLA\r\tJMP I MCC0\r\tTAD XCC0\r\tDCA JLC\rDCC0,\tCDF0\r\tTADI JLC\r"); fprintf("\tJMSI PSH\r\tCLA\r\tISZ JLC\r\tISZ LCC0\r\tJMP DCC0\r\tJMP I MCC0\rCCEND,\t0\r\t\END\r"); fclose(); } |
Added cc8/os8/ps.c.
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | int main() { int ar[20],i,j,n; n=14; for (i=1;i<n;i++) { ar[i]=1; for (j=i-1;j>1;j--) ar[j]=ar[j-1]+ar[j]; for (j=0;j<2*(n-i-1);j++) putc(' '); for (j=1;j<i+1;j++) printf("%4d",ar[j]); printf("\r\n"); } } |
Deleted doc/class-simh.md.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted doc/os8-fortran-iv.md.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted doc/os8-macrel.md.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted doc/os8-patching.md.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted doc/os8-v3d-device-extensions.md.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to doc/pidp8i-test.md.
|
| | > > > | | | < < < < < < < | < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # PCB Test Program ## Compiling and Installing `pidp8i-test` is a simple program to test [Oscar Vermeulen's PiDP-8/I Kit][project] during construction. It is built and installed alongside the other software with the normal `make` process. ## Running It If you are building the software on the Pi for the first time, log out of your user account after installing it, then back in so that the install script's changes to your user's `PATH` take effect. Thereafter, simply give these commands: $ sudo systemctl stop pidp8i $ pidp8i-test The first command ensures that the modified PDP-8 simulator is stopped during the test, since only one program can be talking to the switch and LED array at a given time. (This also applies to other programs like [Deeper Thought 2][dt2].) ## Test Procedure You can at any time hit Ctrl-C to stop the test. The test proceeds as follows: * All On test: It turns on all LEDs for 5 seconds. |
︙ | ︙ | |||
102 103 104 105 106 107 108 | ## License This document is licensed under the same terms as the associated [`src/test.c` program][program]. | < | 90 91 92 93 94 95 96 97 98 99 | ## License This document is licensed under the same terms as the associated [`src/test.c` program][program]. [project]: http://obsolescence.wix.com/obsolescence#!pidp-8 [dt2]: https://github.com/VentureKing/Deeper-Thought-2 [program]: https://tangentsoft.com/pidp8i/doc/trunk/src/test.c |
Changes to doc/uwfocal-manual-supp.md.
︙ | ︙ | |||
69 70 71 72 73 74 75 | The problem affecting U/W FOCAL which prevents it from handling input at modern paste-through-SSH speeds doesn't affect OS/8 itself, so we'll use it as an intermediary: .R PIP *HELLO.DA<TTY: ⇠ use default extension for O I | | | | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | The problem affecting U/W FOCAL which prevents it from handling input at modern paste-through-SSH speeds doesn't affect OS/8 itself, so we'll use it as an intermediary: .R PIP *HELLO.DA<TTY: ⇠ use default extension for O I 01.10 TYPE "Hello, world!"! ^Z ⇠ Ctrl-Z is the EOF marker in OS/8 *^C ⇠ return to OS/8 from PIP .R UWF16K ⇠ run U/W FOCAL *O I HELLO ⇠ open text file for input; "types" pgm in for us _G ⇠ EOF seen, program started Hello, world! ⇠ and it runs! That is, we use OS/8's `PIP` command to accept text input from the terminal (a.k.a. TTY = teletype) and write it to a text file. Then we load that text in as program input using commands we'll explain in detail [below](#ls-write). |
︙ | ︙ | |||
833 834 835 836 837 838 839 | Also, while the `ERASE` command may be used to zero variables in other FOCALs, you must use `ZERO` for that in U/W FOCAL. If your program starts off with `ERASE` commands to initialize its variables, there's a pretty good chance your program will just erase itself under U/W FOCAL. | > > > > | > > > > > > > > < < < < < < | | < | | | | | < | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | Also, while the `ERASE` command may be used to zero variables in other FOCALs, you must use `ZERO` for that in U/W FOCAL. If your program starts off with `ERASE` commands to initialize its variables, there's a pretty good chance your program will just erase itself under U/W FOCAL. ------------------------------------------------------------------------ ## Coccyges ### <a id="rationale"></a>Why Did We Write This? [The Manual][uwfm] is well written as far as it goes, but there are gaps: 1. It inspires questions in the reader's mind without providing an answer. While that is actually a hallmark of a good book, the U/W FOCAL manual sometimes does it for topics that are properly within its scope and so should be answered within. 1. It omits coverage for some topics we wish it would cover, though they are not properly within its scope. 1. It is written somewhat generically for the whole PDP-8 family as of late 1978, whereas the PiDP-8/I project is focused on a single model from 1968. Those not familiar with the differences can therefore be confused by some of its directions. 1. There are considerations in our simulated PiDP-8/I world that simply did not apply to those running U/W FOCAL on the real hardware. 1. There are multiple versions of U/W FOCAL; the version covered by [the Manual][uwfm] isn't the one we actually ship. Our two [other][uwfr] primary [sources][uwfd] also do not cover exactly the version of U/W FOCAL we ship. This document is our attempt to fill these gaps and to supplement those other documents. [Extensions and corrections][hack] are welcome. ### <a id="references"></a>References The primary sources for this supplement are: * [U/W FOCAL Manual][uwfm], October 1978, by Jim van Zee of the University of Washington. * [U/W FOCAL reference cards][uwfr] from the U/W FOCAL distribution, approximately contemporaneous with the Manual, but clearly for a different version of U/W FOCAL than is documented in the Manual. * [DECUS Submission for U/W FOCAL][uwfd], also by van Zee, from August 1978. This document describes the OS/8 version of U/W FOCAL rather than the paper tape version described by the Manual. We chose to convert the Manual to Markdown rather than this DECUS submission because the scan is terrible, resulting in nearly worthless OCR output; we *really* did not want to retype the whole thing! On balance, we think the Manual is a better tutorial than the DECUS submission, though the DECUS submission is perhaps a better reference text. [df8]: http://www.ibiblio.org/pub/academic/computer-science/history/pdp-8/FOCL69%20Files/DEC-08-AJAD-D.pdf [f71]: http://svn.so-much-stuff.com/svn/trunk/pdp8/src/decus/focal8-177/ [hack]: https://tangentsoft.com/pidp8i/doc/trunk/HACKERS.md#patches [uwfd]: http://www.pdp8.net/pdp8cgi/query_docs/view.pl?id=191 [uwfm]: https://tangentsoft.com/pidp8i/doc/trunk/doc/uwfocal-manual.md [uwfr]: https://tangentsoft.com/pidp8i/doc/trunk/doc/uwfocal-refcards.md |
︙ | ︙ |
Changes to doc/uwfocal-manual.md.
︙ | ︙ | |||
1749 1750 1751 1752 1753 1754 1755 | It is also possible to use the reader/punch for data storage purposes. This works best with paper tape since the audio recorder lacks a 'stop-on-character' capability, making it difficult for UWF to keep up with the data once the tape has started moving. By way of an example, the following command will read in 50 numbers from the high-speed reader: | | | 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 | It is also possible to use the reader/punch for data storage purposes. This works best with paper tape since the audio recorder lacks a 'stop-on-character' capability, making it difficult for UWF to keep up with the data once the tape has started moving. By way of an example, the following command will read in 50 numbers from the high-speed reader: O R; FOR 1=1,50; ASK DATA(I); NEXT; O I,E Notice that an `O I,E` command is used at the end of the loop to restore input to the keyboard. If this command were omitted the H.S. reader would continue to be used for input, probably causing an error to occur since it is unlikely that the next data value on the tape would correspond to anything expected from the keyboard. The `,E` part of this command is explained more fully in the next section. |
︙ | ︙ | |||
2244 2245 2246 2247 2248 2249 2250 | example in connection with the `FLOG` function allows one to avoid the 'log-of-zero' error with a call such as `FLOG(FMAX(1E-10,X))`. Similarly, the `FMIN` function can be used to avoid typing nonexistent values when dumping an array in a multi-column format. In this example, `C` is the number of columns and `N` the number of data values in the array: | | | 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 | example in connection with the `FLOG` function allows one to avoid the 'log-of-zero' error with a call such as `FLOG(FMAX(1E-10,X))`. Similarly, the `FMIN` function can be used to avoid typing nonexistent values when dumping an array in a multi-column format. In this example, `C` is the number of columns and `N` the number of data values in the array: FOR 1=1,C,N; FOR J=I,FMIN(N,C+I-1); TYPE Q(J); NEXT; TYPE ! As a final example, an entire array can be scanned for its extrema simply by comparing each element with the previous best estimates: SET MIN=MAX=A(1); FOR I=2,N; SET MIN=FMIN(A(I),MIN), MAX=FMAX(A(I),MAX) A disadvantage of this method for locating the extremes is that no |
︙ | ︙ |
Changes to examples/README.md.
︙ | ︙ | |||
29 30 31 32 33 34 35 | ## How to Use the BASIC Examples To use the example BASIC program, simply transcribe it into OS/8 BASIC: .R BASIC NEW OR OLD--NEW | | | | | | | | | | < < > | < < | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | ## How to Use the BASIC Examples To use the example BASIC program, simply transcribe it into OS/8 BASIC: .R BASIC NEW OR OLD--NEW FILE NAME--PAL001.BA READY 10 FOR I = 1 TO 999 10 FOR I = 1 TO 999 20 A = I / 3 \ B = I / 5 30 IF INT(A) = A GOTO 60 40 IF INT(B) = B GOTO 60 50 GOTO 70 60 T = T + I 70 NEXT I 80 PRINT "TOTAL: "; T 90 END SAVE READY RUN PAL001 BA 4A TOTAL: xxxxxxx READY BYE If you're SSH'd into the PiDP-8/I, "transcribing" is simply a matter of cut-and-paste into the terminal window. I've obscured the output on purpose, since I don't want this page to be a spoiler for the Project Euler site. If you get a 2-letter code from BASIC in response to your `RUN` command, it means you have an error in the program. See the BASIC section of the OS/8 Handbook for a decoding guide. ## How to Use the Assembly Language Examples For each PAL8 assembly program in `asm/*.pal` or `examples/*.pal`, there are two additional files: | Extension | Meaning ----------------------------- | `*.pal` | the PAL8 assembly source code for the program | `obj/*.lst` | the human-readable assembler output | `bin/*-pal.pt` | the machine-readable assembler output (RIM format) There are three ways to run these on your PiDP-8/I, each starting with one of the above three files: 1. Transcribe the assembly program text to a file within a PDP-8 operating system and assemble it inside the simulator. 2. Toggle the program in from the front panel. I can recommend this method only for very short programs. 3. Copy the `*-pal.pt` file to a USB stick and use the PiDP-8/I's [automatic media mounting feature][howto]. This is the fastest method. I cover each of these options below, in the same order as the list above. ## Option 1: Transcribing the Assembly Code into an OS/8 Session To transcribe [`examples/add.pal`][pal] into the OS/8 simulation on a PiDP-8/I: .R EDIT *ADD.PA< |
︙ | ︙ | |||
171 172 173 174 175 176 177 | above. At the OS/8 command line, say: .R PIP *ADD.PA<TTY: Now you can simply copy the assembly language text in your desktop PC's text editor, paste it into the SSH window, and then hit Ctrl-Z to tell | | < | | | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | above. At the OS/8 command line, say: .R PIP *ADD.PA<TTY: Now you can simply copy the assembly language text in your desktop PC's text editor, paste it into the SSH window, and then hit Ctrl-Z to tell `PIP` that the text input from the terminal (`TTY:`) is finished. This is not only a smidge simpler than doing the same thing via `EDIT`, it also avoids a certain limitation of `EDIT` that starts to bite you once your program text exceeds about 5,600 characters. ## Option 2: Toggling a Programs in Via the Front Panel After building the PiDP-8/I software, each of the `examples/*.pal` files is assembled by `palbart` which writes out a human-readable listing file to `obj/*.lst`, named after the source file. Take [`obj/add.lst`][lst] as an example, in which you will find three columns of numbers on the code-bearing lines: |
︙ | ︙ | |||
202 203 204 205 206 207 208 | The first number refers to the corresponding line number in [`add.pal`][pal], the second is a PDP-8 memory address, and the third is the value stored at that address. To toggle the `add` program in, press `Stop` to halt the processor, then twiddle the switches like so: | | | | | | | | | | | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | The first number refers to the corresponding line number in [`add.pal`][pal], the second is a PDP-8 memory address, and the third is the value stored at that address. To toggle the `add` program in, press `Stop` to halt the processor, then twiddle the switches like so: | Set SR Switches To... | Then Toggle... |------------------------------------------------ | 000 010 000 000 | `Load Add` | 111 011 000 000 | `Dep` | 001 010 000 101 | `Dep` | 001 010 000 110 | `Dep` | 011 010 000 111 | `Dep` | 111 100 000 010 | `Dep` | 000 000 000 010 | `Dep` | 000 000 000 011 | `Dep` To run it, repeat the first step in the table above, loading the program's starting address (0200) first into the switch register (SR) and then into the PDP-8's program counter (PC) via `Load Add`. Then toggle `Start` to run the program. If you then: If you then toggle 000 010 000 111 into SR, press `Load Add` followed by `Exam`, you should see 000 000 000 101 in the third row of lights, the bit pattern for five at memory location 0207, that being the correct answer for "2 + 3" in the expected location, which is what we expected `add.pal` to do. You could load that address back up again and `Dep` a different value into that location, then start the program over again at |
︙ | ︙ | |||
239 240 241 242 243 244 245 | Beware that this program does not contain an explicit value for memory location 0207 at the start, but it does overwrite this location with the answer, since location `C` is defined as having the address just after the last value you entered via SR above, 0206. That is the source of the "07" in the lower two digits of the fourth instruction, 3207. | | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | Beware that this program does not contain an explicit value for memory location 0207 at the start, but it does overwrite this location with the answer, since location `C` is defined as having the address just after the last value you entered via SR above, 0206. That is the source of the "07" in the lower two digits of the fourth instruction, 3207. ## Option 3: Loading a Program from Paper Tape The `palbart` assembly process described above also produces paper tape output files in RIM format in `bin/-pal*.pt`. The simplest way to load these assembly examples into your PiDP-8/I is to copy each such file to a USB stick, one file per stick. Then, load the paper tape into the simulated PDP-8/I's core memory. |
︙ | ︙ | |||
276 277 278 279 280 281 282 | `Start` to run the program. There is an SVG template for USB stick labels in the distribution under the [`labels/`][label] directory, for use if you find yourself creating long-lived USB sticks. See [`labels/README.md`][lread] for more information. | < < < < < < < < < < < < < | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | `Start` to run the program. There is an SVG template for USB stick labels in the distribution under the [`labels/`][label] directory, for use if you find yourself creating long-lived USB sticks. See [`labels/README.md`][lread] for more information. ## License Copyright © 2016-2017 by Warren Young. This document is licensed under the terms of [the SIMH license][sl]. [lst]: https://tangentsoft.com/pidp8i/doc/trunk/examples/add.lst [pal]: https://tangentsoft.com/pidp8i/doc/trunk/examples/add.pal [label]: https://tangentsoft.com/pidp8i/dir?ci=trunk&name=labels [lread]: https://tangentsoft.com/pidp8i/doc/trunk/labels/README.md [howto]: http://obsolescence.wixsite.com/obsolescence/how-to-use-the-pidp-8 [sl]: https://tangentsoft.com/pidp8i/doc/trunk/SIMH-LICENSE.md |
Deleted examples/pep001-f2.ft.
|
| < < < < < < < < < < < < |
Deleted examples/pep001-f4.ft.
|
| < < < < |
Deleted examples/pep001.c.
|
| < < < < < < < < < < < < < < < < |
Deleted examples/pep001.fc.
|
| < < < < < < < |
Changes to lib/mkos8/argparser.py.
︙ | ︙ | |||
27 28 29 30 31 32 33 | # Except as contained in this notice, the names of the authors above # shall not be used in advertising or otherwise to promote the sale, # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## import argparse | < < < < < | > > > | < | | | > | > > > > > > > > > > > > > > > > > > > > > > > < < > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # Except as contained in this notice, the names of the authors above # shall not be used in advertising or otherwise to promote the sale, # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## import argparse class ArgParser (argparse.ArgumentParser): def __init__ (self, allowed_acts): argparse.ArgumentParser.__init__ (self, description = 'Build OS/8 RK05 disk images') self.add_bool ('-v', '--verbose', help = 'verbose SIMH output instead of progress messages') self.add_bool ('--enable-music', help = 'add *.MU files to binary disk') self.add_bool ('--disable-ba', help = 'leave BASIC games and demos off binary disk') self.add_bool ('--disable-cc8', help = 'leave CC8 off binary disk') self.add_bool ('--disable-dcp', help = 'leave DCP disassembler off binary disk') self.add_bool ('--disable-focal', help = 'leave FOCAL 69 and U/W FOCAL off binary disk') self.add_bool ('--enable-focal69', help = 'install FOCAL 69 on the binary disk') self.add_bool ('--disable-uwfocal', help = 'leave U/W FOCAL (only) off binary disk') self.add_bool ('--disable-fortran-ii', help = 'leave FORTRAN II compiler off binary disk') self.add_bool ('--disable-fortran-iv', help = 'leave FORTRAN IV compiler off binary disk') self.add_bool ('--disable-init', help = 'suppress display of the INIT message on OS/8 boot') self.add_bool ('--disable-k12', help = 'leave 12-bit Kermit off binary disk') self.add_bool ('--disable-macrel', help = 'leave MACREL assembler off binary disk') self.add_bool ('--enable-vtedit', help = 'install and enable TECO VTEDIT mode') self.add_bool ('--disable-crt', help = 'console is a printing terminal and does not use ' + 'character overwrite on rubout') self.add_bool ('--disable-lcmod', help = 'disable the OS/8 command upcasing patch; best set ' + 'when SIMH is set to tti ksr mode') self.add_bool ('--disable-advent', help = 'leave game of Adventure off binary disk') self.add_bool ('--disable-chess', help = 'leave CHEKMO-II off binary disk') self.add_argument ( 'what', choices = allowed_acts, help = 'select which RK05 media gets built; default is "all"', nargs = argparse.REMAINDER) self.args = self.parse_args() if len (self.args.what) == 0: self.args.what = [ 'all' ] def add_bool (self, *args, **kwargs): kwargs['action'] = 'store_true' kwargs['default'] = False self.add_argument (*args, **kwargs) |
Changes to lib/pidp8i/__init__.py.in.
︙ | ︙ | |||
30 31 32 33 34 35 36 | # # Except as contained in this notice, the names of the authors above # shall not be used in advertising or otherwise to promote the sale, # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## | | | 30 31 32 33 34 35 36 37 | # # Except as contained in this notice, the names of the authors above # shall not be used in advertising or otherwise to promote the sale, # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## __all__ = [ 'dirs' ] |
Changes to lib/pidp8i/dirs.py.in.
︙ | ︙ | |||
42 43 44 45 46 47 48 | # file in the development tree and the install script overwrites these # for the installation tree. build = "@builddir@" src = "@abs_top_srcdir@" # Derived directories. Where it matters, these are the development tree # paths, overridden or adjusted below if we're installed. | | | | < | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | # file in the development tree and the install script overwrites these # for the installation tree. build = "@builddir@" src = "@abs_top_srcdir@" # Derived directories. Where it matters, these are the development tree # paths, overridden or adjusted below if we're installed. bin = build + "/bin/" log = build + "/obj/" media = src + "/media/os8/" os8 = bin # Adjust paths for the "installed" case if not os.path.exists(log): # The obj/ dir doesn't exist in the install tree log = "/tmp/" if not os.path.exists(media): |
︙ | ︙ |
Deleted lib/pidp8i/ips.py.in.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to lib/simh.py.
1 2 3 4 5 6 | #!/usr/bin/python # -*- coding: utf-8 -*- ######################################################################## # simh/__init__.py - A wrapper class around pexpect for communicating # with an instance of the PiDP-8/I SIMH simulator running OS/8. # | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/usr/bin/python # -*- coding: utf-8 -*- ######################################################################## # simh/__init__.py - A wrapper class around pexpect for communicating # with an instance of the PiDP-8/I SIMH simulator running OS/8. # # Copyright © 2017 by Jonathan Trites, William Cattey, and Warren Young. # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to |
︙ | ︙ | |||
29 30 31 32 33 34 35 | # # Except as contained in this notice, the names of the authors above # shall not be used in advertising or otherwise to promote the sale, # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > | > > > > > > > > | > | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | # # Except as contained in this notice, the names of the authors above # shall not be used in advertising or otherwise to promote the sale, # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## import pexpect import pkg_resources import time class simh: # pexpect object instance, set by ctor _child = None #### ctor ############################################################ def __init__ (self, basedir): # Start the simulator instance self._child = pexpect.spawn(basedir + '/bin/pidp8i-sim') # Turn off pexpect's default inter-send() delay. We add our own as # necessary. The conditional tracks an API change between 3 and 4. pev4 = (pkg_resources.get_distribution("pexpect").parsed_version > pkg_resources.parse_version("4.0")) self._child.delaybeforesend = None if pev4 else 0 #### back_to_cmd ###################################################### # Pause the simulation and return to the SIMH command prompt when the # simulated software emits the given prompt string. Typically used to # wait for OS/8 to finish running a command so we can do something # down at the SIMH layer instead. def back_to_cmd (self, prompt): self._child.expect ("\n%s$" % prompt) self.os8_kbd_delay () self._child.sendcontrol ('e') #### os8_kbd_delay ################################################### # Artificially delay the media generation process to account for the # fact that OS/8 lacks a modern multi-character keyboard input buffer. # It is unsafe to send text faster than a contemporary terminal could. # # The constant is based on advice we received that OS/8 would begin to # become unreliable when run with a terminal speaking more than about # 600 bps. We divide that by 7-bit ASCII plus necessary start, stop, # and parity bits to get characters per second. Then we multiply that # by 4, the minimum number of times faster our SIMH instance runs as # compared to a real PDP-8. (Keep in mind that we initially run the # simulator without any throttling.) Finally, we invert that value to # get secs per character instead of characters per second. OS/8 must # be able to accept input at least this fast on our simulator. _kbd_delay = 1 / (600 / (7 + 1 + 1 + 1) * 4) def os8_kbd_delay (self): time.sleep (self._kbd_delay) #### os8_send_cmd ###################################################### # Wait for an OS/8 command prompt running within SIMH, then send the # given line. # # The prompt string is passed in because OS/8 has several different # prompt types. def os8_send_cmd (self, prompt, line): self._child.expect ("\n%s$" % prompt) self.os8_send_line (line) #### os8_send_ctrl ##################################################### # Send a control character to OS/8 corresponding to the ASCII letter # given. We precede it with the OS/8 keyboard delay, since we're # probably following a call to os8_send_line or os8_send_cmd. def os8_send_ctrl (self, char): self.os8_kbd_delay () self._child.sendcontrol (char[0].lower ()) #### os8_send_line ##################################################### # Core of os8_send_cmd. Also used by code that needs to send text # "blind" to OS/8, without expecting a prompt, as when driving EDIT. def os8_send_line (self, line): self.os8_send_str (line) self._child.send ("\r") |
︙ | ︙ | |||
300 301 302 303 304 305 306 | #### quit ############################################################ # Quits the simulator and waits for it to exit def quit (self): self.send_cmd ("q") self._child.expect (pexpect.EOF) | < < < < < < < < | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | #### quit ############################################################ # Quits the simulator and waits for it to exit def quit (self): self.send_cmd ("q") self._child.expect (pexpect.EOF) #### send_cmd ######################################################## # Wait for a SIMH command prompt and then send the given command def send_cmd (self, cmd): self._child.expect ("sim> $") self._child.sendline (cmd) |
︙ | ︙ | |||
331 332 333 334 335 336 337 | #### set_logfile ##################################################### def set_logfile (self, lf): self._child.logfile = lf #### spin ############################################################ | | < | | < < < < < < < < | 185 186 187 188 189 190 191 192 193 194 195 | #### set_logfile ##################################################### def set_logfile (self, lf): self._child.logfile = lf #### spin ############################################################ # Let child run indefinitely without asking anything more from it. def spin (self): self._child.expect (pexpect.EOF, timeout = None) |
Changes to libexec/mkos8.
︙ | ︙ | |||
35 36 37 38 39 40 41 | import os import sys sys.path.insert (0, os.path.dirname (__file__) + '/../lib') sys.path.insert (0, os.getcwd () + '/lib') # Remaining Python core modules import re | | > > > < < < < < < < < < < < < < < < < | | > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | import os import sys sys.path.insert (0, os.path.dirname (__file__) + '/../lib') sys.path.insert (0, os.getcwd () + '/lib') # Remaining Python core modules import re from shutil import copyfile import subprocess # Our local modules from mkos8 import * from pidp8i import * from simh import * #### globals and constants ############################################# # Flag set when -v is *not* given. Causes make_*() and the functions # called thereby to print progress messages to the console since SIMH # and OS/8 output is not being sent there to clue the user into the # script's progress. progmsg = True # kludgy flag to add more verbose debug output. debug = False # Name of the RK05 disk image files we create _bin_rk05 = "os8v3d-bin.rk05" _src_rk05 = "os8v3d-src.rk05" _patched_rk05 = "os8v3d-patched.rk05" #### check_exists ###################################################### # Check existence of all files needed def check_exists (s, image_copyins): for copyin in image_copyins: image = copyin[1] image_path = dirs.media + image if (not os.path.isfile(image_path)): print "Required file: " + image_path + " not found." s.quit () exit (-1) # else: print "Found " + image_path #### Data Structures ################################################## # # The make procedures use helper procedures # to confirm that the relevant input image file exists and |
︙ | ︙ | |||
134 135 136 137 138 139 140 | # Assumes our context is "in simh". # Assumes dt0 and dt1 are free. # Assumes rk0 is the boot device # Detaches dt0 and dt1 after using them. # copyin0 mounts on dt0. copyin1 mounts on dt1. # Either copyin or both can be None | | | | | | | | | | | | | | | | | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | # Assumes our context is "in simh". # Assumes dt0 and dt1 are free. # Assumes rk0 is the boot device # Detaches dt0 and dt1 after using them. # copyin0 mounts on dt0. copyin1 mounts on dt1. # Either copyin or both can be None def copyin_pair (s, copyin0, copyin1): if debug: if copyin0: print "Copying: " + copyin0[1] + " to: " + copyin0[0] + "from dt0" else: print "copyin0 is empty." if copyin1: print "Copying: " + copyin1[1] + " to: " + copyin1[0] + "from dt1" else: print "copyin1 is empty." if not copyin0 and not copyin1: return # Nothing to do. # The order of events here is a bit funky because we want # to use both DECtape drives but also # switch between SIMH and OS/8 as infrequently as possible. if copyin0: s.send_cmd ("attach -r dt0 " + dirs.media + copyin0[1]) if copyin1: s.send_cmd ("attach -r dt1 " + dirs.media + copyin1[1]) s.os8_restart() if copyin0: if progmsg: print copyin0[2] if copyin0[3]: # We have specific files to do. for file_copyin in copyin0[3]: s.os8_send_cmd ("\.", "COPY " + file_copyin[0] + "<DTA0:" + file_copyin[1]) else: s.os8_send_cmd ("\.", "COPY " + copyin0[0] + "<DTA0:*.*") if copyin1: if progmsg: print copyin1[2] if copyin1[3]: # We have specific files to do. for file_copyin in copyin1[3]: s.os8_send_cmd ("\.", "COPY " + file_copyin[0] + "<DTA1:" + file_copyin[1]) else: s.os8_send_cmd ("\.", "COPY " + copyin1[0] + "<DTA1:*.*") s.back_to_cmd("\.") if copyin0: s.send_cmd ("detach dt0") if copyin1: s.send_cmd ("detach dt1") #### do_all_copyins #################################################### def do_all_copyins (s, copyins): pair_idx = 0 pair_ct = int(len(copyins) / 2) while pair_idx < pair_ct: copyin_pair(s, copyins[pair_idx * 2], copyins[pair_idx * 2 + 1]) pair_idx += 1 if pair_ct * 2 < len(copyins): copyin_pair(s, copyins[len(copyins) - 1], None) #### make_bin ########################################################## # Top-level driver for the "make binary OS/8 RK05 disk image" process. # # If there is already an RK05 binary destination image, moves it aside # to a ".save" instance, overwriting the previous .save if it exists. # # One of the input images is used as a bootable DECtape. # That DECtape gets written on. # It needs stuff from tape #2 # So the first two DECtapes # are treated separately and specially. # All the other DECtape images used are read only. def make_bin (s, args): ro_boot_tape = "al-4711c-ba-os8-v3d-1.1978.tu56" ro_boot_tape_path = dirs.media + ro_boot_tape driver_tape = "al-4712c-ba-os8-v3d-2.1978.tu56" driver_tape_path = dirs.media + driver_tape local_tape = "local.tu56" local_tape_path = dirs.media + local_tape boot_dt_path = dirs.media + "bootable-al-4711-c-ba-os8-v3d-1.1978.tu56" special_bin_copyins = [ ["", ro_boot_tape, "", None], ['RKA0:', driver_tape, "Device Drivers...", None], ] music_copyin = ['RKB0:', 'subsys/music.tu56', |
︙ | ︙ | |||
241 242 243 244 245 246 247 | ['RKB0:', '8KVT.BN'], ['RKB0:', '8KNOVT.BN'] ] focal69_copyin = ['RKA0:', 'subsys/focal69.tu56', "Installing FOCAL 69...", focal69_files] fiv_copyins = [ | | | < | < < < < < < < < > | | | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | ['RKB0:', '8KVT.BN'], ['RKB0:', '8KNOVT.BN'] ] focal69_copyin = ['RKA0:', 'subsys/focal69.tu56', "Installing FOCAL 69...", focal69_files] fiv_copyins = [ ['RKA0:', "al-4549d-ba-fr4-v3d-1.1978.tu56", "Installing FORTRAN IV (part 1 of 2)...", None], ['RKA0:', "al-5596d-ba-fr4-v3d-2.1978.tu56", "Installing FORTRAN IV (part 2 of 2)...", None], ] macrel_copyin = ['RKA0:', "al-5642a-ba-macrel-linker.1978.tu56", "Installing MACREL...", None] uwfocal_files = [['SYS:', 'UWF16K.SV']] uwfocal_copyin = ['RKA0:', 'subsys/uwfocal-v4e-2.tu56', "Installing U/W FOCAL...", uwfocal_files] advent_copyin = ['RKB0:', 'subsys/advent.tu56', |
︙ | ︙ | |||
300 301 302 303 304 305 306 | if args.enable_music: bin_copyins.append(music_copyin) if not args.disable_advent: bin_copyins.append(advent_copyin) if not args.disable_ba: bin_copyins.append(ba_copyin) if not args.disable_cc8: bin_copyins.append(cc8_copyin) if not args.disable_k12: bin_copyins.append(k12_copyin) | | | | | | < | < < < < < < | | | < | | | | | < < < < | | | | | | | < < < | | | < < < < < < < > > > > | > > | | | | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | if args.enable_music: bin_copyins.append(music_copyin) if not args.disable_advent: bin_copyins.append(advent_copyin) if not args.disable_ba: bin_copyins.append(ba_copyin) if not args.disable_cc8: bin_copyins.append(cc8_copyin) if not args.disable_k12: bin_copyins.append(k12_copyin) if not args.disable_fortran_iv: bin_copyins = bin_copyins + fiv_copyins if not args.disable_macrel: bin_copyins.append(macrel_copyin) if local_files != []: local_copyins = ['RKA0:', local_tape, local_stat_str, local_files] bin_copyins.append(local_copyins) if args.enable_focal69 and not args.disable_focal: bin_copyins.append(focal69_copyin) if not args.disable_uwfocal and not args.disable_focal: bin_copyins.append(uwfocal_copyin) check_exists(s, special_bin_copyins) check_exists(s, bin_copyins) print "Generating " + _bin_rk05 + " from " + str(len(bin_copyins) + 2) + \ " source tapes..." image_path = dirs.os8 + _bin_rk05 if os.path.isfile(image_path): save_path = dirs.media + _bin_rk05 + ".save" print "Pre-existing " + _bin_rk05 + " found. Saving as " + _bin_rk05 + ".save" if os.path.isfile(save_path): print "Overwriting old " + _bin_rk05 + ".save" os.remove(save_path) os.rename(image_path, save_path) global progmsg if progmsg: print "Building initial OS/8 system..." if progmsg: print "Making a writeable copy of boot DECtape..." copyfile(ro_boot_tape_path, boot_dt_path) s.send_cmd ("attach rk0 " + image_path) s.send_cmd ("attach dt0 " + boot_dt_path) s.send_cmd ("attach -r dt1 " + driver_tape_path) if progmsg: print "Performing config with BUILD..." s.send_cmd ("boot dt0") # By default, we're going to have an INIT.CM script, but we don't want # to set it up this early for two reasons. First, we don't want the # "boot rk0" commands below to emit this message, since its text # varies depending on the host system, which would create unnecessary # differences in our output over time. Second, OS/8 is alleged not to # always build properly if INIT is enabled in these early stages. s.os8_send_cmd ("\.", "SET SYS NO INIT") s.os8_send_cmd ("\.", "RUN SYS BUILD") s.os8_send_cmd ("\$", "LOAD DTA1:RK8ESY.BN") s.os8_send_cmd ("\$", "LOAD DTA1:PT8E.BN") s.os8_send_cmd ("\$", "DELETE SYS") s.os8_send_cmd ("\$", "SYSTEM RK8E") s.os8_send_cmd ("\$", "DELETE RXA1") s.os8_send_cmd ("\$", "INSERT PT8E,PTR") s.os8_send_cmd ("\$", "INSERT PT8E,PTP") s.os8_send_cmd ("\$", "DELETE RKA0") s.os8_send_cmd ("\$", "DELETE RKB0") s.os8_send_cmd ("\$", "INSERT RK8E,RKA0,RKB0") s.os8_send_cmd ("\$", "INSERT RK05,RKA2,RKB2") s.os8_send_cmd ("\$", "DELETE DTA0") s.os8_send_cmd ("\$", "INSERT TC,DTA0") s.os8_send_cmd ("\$", "DSK RK8E:RKB0") s.os8_send_cmd ("\$", "PRINT") s.os8_send_cmd ("\$", "BOOT") s.os8_send_cmd ("WRITE ZERO DIRECT\?", "Y") s.os8_send_cmd ("\.", "SAVE SYS BUILD") s.back_to_cmd("\.") if progmsg: print "Copying OS/8 system files from TU56 source to RK05 image..." if progmsg: print "Copying in system tape 1 of 2..." s.send_cmd ("boot dt0") s.os8_send_cmd ("\.", "COPY RKA0:<DTA0:*.*") # There are not enough directory entries to put everything # Including all device drivers on the running packs. # So we DONT copy in the device drivers, nor TDINIT.SV, # nor the two TD8E-based DECtape system area files. # CCL.PA and KL8E.PA will be on the source disk. # However DECtape 2 has HELP.HL and .RL files that ARE needed. # if progmsg: print "Copying in system tape 2 of 2..." # s.os8_send_cmd ("\.", "COPY RKA0:<DTA1:*.*") if progmsg: print "Copying in help files..." s.os8_send_cmd ("\.", "COPY RKA0:<DTA1:*.HL") if args.disable_fortran_ii: s.os8_send_cmd ("\.", "DEL RKA0:FORT.SV") else: if progmsg: print "Installing FORTRAN II libraries..." s.os8_send_cmd ("\.", "COPY RKA0:<DTA1:*.RL") s.os8_send_cmd ("\.", "ZERO RKB0:") # must precede subsys/* copies s.back_to_cmd("\.") if progmsg: print "Deleting bootable copy of DECtape image and" if progmsg: print "rebooting into freshly-built RK05 OS/8 system..." s.send_cmd ("detach dt0") s.send_cmd ("detach dt1") s.send_cmd ("boot rk0") # must do: boot media just went away s.back_to_cmd("\.") os.remove(boot_dt_path) # don't check error: copyfile() succeeded above if progmsg: print "Performing remaining copies/installs..." do_all_copyins (s, bin_copyins) # Any further initialization of installed software is done here. s.send_cmd ("boot rk0") if not args.disable_crt: # NO SCOPE mode is the default on distribution tapes. if progmsg: print "Configuring scope-style rubout processing..." s.os8_send_cmd ("\.", "SET TTY SCOPE") # Make sure Scripts are included in local_files array! # Or this will fail. if not args.disable_lcmod: if progmsg: print "Patching OS/8 to upcase commands only; SIMH is set not to auto-upcase." s.os8_send_cmd ("\.", "SUBMIT SYS:LCSYS.BI") if progmsg: print "Patching OS/8 BASIC to cope with lower case input" s.os8_send_cmd ("\.", "SUBMIT SYS:LCBAS.BI") # Create a banner message and optionally set it to show on boot. # This message is always upcased, even if you do this before calling # LCSYS.BI. Is it a limitation of EDIT? if progmsg: print "Setting INIT message..." s.os8_send_cmd ("\.", "CREATE INIT.TX") s.os8_send_cmd ("#", "A") # append text to file with open(dirs.media + "/init.tx", "r") as f: for line in f: s.os8_send_line(line) s.os8_send_ctrl('L') # return to EDIT command mode s.os8_send_cmd ("#", "E") # save and exit s.os8_send_cmd ("\.", "CREATE INIT.CM") s.os8_send_cmd ("#", "A") s.os8_send_line("TYPE INIT.TX") s.os8_send_ctrl('L') s.os8_send_cmd ("#", "E") if not args.disable_init: # Set the message to display only if the user did not suppress it. # We do it this way so the user can turn it on later without # rebuilding their OS/8 media. s.os8_send_cmd ("\.", "SET SYS INIT") # Finish up if progmsg: print "Cleaning up..." s.os8_squish ("SYS") s.os8_squish ("DSK") s.back_to_cmd("\.") s.send_cmd ("detach rk0") #### make_src ########################################################## # Source-disk version of make_bin() above. |
︙ | ︙ | |||
492 493 494 495 496 497 498 | ] check_exists (s, src_copyins) print "Generating " + _src_rk05 + " from " + str(len(src_copyins)) + \ " source tapes..." | | | | | | | > > > > > > | > > > | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < | < | | > | < | | | < < < | | < < < < < < < < < < < < < < < < < < < < < < < < | | < | < < < < < < | | < < | < | | < | < < | | < < < < < < < < < < < < < < < < < < < < | | | | | 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | ] check_exists (s, src_copyins) print "Generating " + _src_rk05 + " from " + str(len(src_copyins)) + \ " source tapes..." bin_path = dirs.os8 + _bin_rk05 if (not os.path.isfile(bin_path)): print _bin_rk05 + " is needed to build src. Creating..." make_bin(args) src_path = dirs.os8 + _src_rk05 if os.path.isfile(src_path): save_path = src_path + ".save" print "Pre-existing " + _src_rk05 + " found. Saving as " + _src_rk05 + ".save" if os.path.isfile(save_path): print "Overwriting old " + _src_rk05 + ".save" os.remove(save_path) os.rename(src_path, save_path) if progmsg: print "Copying OS/8 source distribution:" s.send_cmd ("attach rk0 " + bin_path) s.send_cmd ("attach rk1 " + src_path) s.send_cmd ("boot rk0") s.os8_send_cmd ("\.", "ZERO RKA1:") s.os8_send_cmd ("\.", "ZERO RKB1:") s.back_to_cmd("\.") do_all_copyins (s, src_copyins) if progmsg: print "Cleaning up..." s.send_cmd ("detach rk0") s.send_cmd ("detach rk1") #### parse_r ######################################################### def parse_r (com, line): # Send args to Command decoder first. # Then perform com-specific parse. return #### parse_odt ######################################################### def parse_odt (s, com, line): odt_parse_str = "^([0-7]+)\s?/\s?(\S+)\s+([0-7;]+)" odt_parse = re.compile(odt_parse_str) print line if line == "\\c": return "break" match = odt_parse.match(line) if match == None: print "Aborting because of bad ODT line: " + line s.os8_send_ctrl('C') return "err" loc = match.group(1) old_val = match.group(2) new_val = match.group(3) expect_val_str = "[0-7]{4} " if debug: print "Loc: " + loc + ", old_val: " + old_val + ", new_val: " + new_val s.os8_send_str (loc + "/") s._child.expect(expect_val_str) if old_val.isdigit(): # We need to check old value found_val = s._child.after.strip() if found_val != old_val: print "Old value: " + found_val + " does not match " + old_val + ". Aborting patch." # Abort out of ODT back to the OS/8 Monitor s.os8_send_ctrl('C') return "err" s.os8_send_line (new_val) return "cont" #### do_patch_file ##################################################### def do_patch_file (s, filename): global progmsg try: patch_file = open(dirs.media + "patches/" + filename, "r") except IOError: print filename + " not found. Skipping." return -1 com_parse_str = "^\.([a-zA-Z]+)\s?(.*)$" com_parse = re.compile(com_parse_str) special_commands = {"ODT": parse_odt} inside_a_command = False the_command = "" the_command_parser = None for line in patch_file: line = line.rstrip() if line == "": continue elif line[0] == '#': continue # Ignore Comments elif inside_a_command: retval = the_command_parser (s, the_command, line) if retval == "break": inside_a_command = False s.os8_send_ctrl('C') elif retval == "err": return -1 elif line[0] == '.': # New OS/8 Command match = com_parse.match(line) if match == None: print "Ignoring failed OS/8 command parse of: " + line continue com = match.group(1) rest = match.group(2) if com in special_commands: inside_a_command = True the_command = com the_command_parser = special_commands[com] # We carefully separate com and args # But don't make much use of that yet. if progmsg: print line s.os8_send_cmd ("\.", line[1:]) # Skip Prompt. # Done. Signal success. return 0 #### make_patch ######################################################## def make_patch (s, args): global progmsg manifest_filename = "patch_list.txt" print "Generating " + _patched_rk05 + " from " + _bin_rk05 image_path = dirs.os8 + _patched_rk05 if os.path.isfile(image_path): save_path = dirs.media + _patched_rk05 + ".save" print "Pre-existing " + _patched_rk05 + " found. Saving as " + _patched_rk05 + ".save" if os.path.isfile(save_path): print "Overwriting old " + _patched_rk05 + ".save" os.remove(save_path) os.rename(image_path, save_path) if progmsg: print "Copying original " + _bin_rk05 + " to " + _patched_rk05 copyfile(dirs.os8 + _bin_rk05, image_path) s.send_cmd ("attach rk0 " + image_path) s.send_cmd ("boot rk0") # We're running OS/8. Let's patch! manifest = open (dirs.media + "patches/" + manifest_filename, "r") for line in manifest: if line == "": continue if line[0] == '#': continue # Allow commenting out files filename = line.strip() if progmsg: print "Applying patch file: " + filename retval = do_patch_file (s, filename) if retval == 0: print "Success." else: print "Failed." # Finish up print "Cleaning up..." # s.os8_squish ("SYS") # s.os8_squish ("DSK") s.back_to_cmd("\.") s.send_cmd ("detach rk0") #### main ############################################################## # Program entry point. Parses the command line and drives the above. def main (): |
︙ | ︙ | |||
818 819 820 821 822 823 824 | acts[this] = True break acts[act] = True # Log SIMH and OS/8 output to a file by default, but send it to the # console instead of the progress messages if -v was given using the # trick from https://stackoverflow.com/questions/21239338 | | | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | acts[this] = True break acts[act] = True # Log SIMH and OS/8 output to a file by default, but send it to the # console instead of the progress messages if -v was given using the # trick from https://stackoverflow.com/questions/21239338 s = simh (dirs.build) s.set_logfile (open (dirs.log + 'mkos8-' + first_act + '.log', 'w') \ if progmsg else os.fdopen (sys.stdout.fileno (), 'w', 0)) if acts["bin"]: make_bin (s, ap.args) if acts["src"]: make_src (s, ap.args) if acts["patch"]: make_patch (s, ap.args) s.quit () if progmsg: print "Done!" if __name__ == "__main__": main() |
Deleted media/os8/.agignore.
|
| < < < |
Deleted media/os8/.ignore.
|
| < |
Added media/os8/al-4549d-ba-fr4-v3d-1.1978.tu56.
cannot compute difference between binary files
Added media/os8/al-5596d-ba-fr4-v3d-2.1978.tu56.
cannot compute difference between binary files
Deleted media/os8/al-5642c-ba-macrel-v2-futil-v8b-by-hand.tu56.
cannot compute difference between binary files
Added media/os8/cc8.rk05.
cannot compute difference between binary files
Changes to media/os8/init.tx.in.
1 2 | PiDP-8/I @VERSION@ - OS/8 V3D - KBM V3Q - CCL V1F | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 | PiDP-8/I @VERSION@ - OS/8 V3D - KBM V3Q - CCL V1F CONFIGURED BY @BUILDUSER@ ON @BUILDTS@ RESTART ADDRESS =07600 TYPE: .DIR - TO GET A LIST OF FILES ON DSK: .DIR SYS: - TO GET A LIST OF FILES ON SYS: .R PROGNAME - TO RUN A SYSTEM PROGRAM .HELP FILENAME - TO TYPE A HELP FILE |
Changes to media/os8/local.tu56.
cannot compute difference between binary files
Deleted media/os8/patches/DLOG.RA.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to media/os8/patches/FORLIB-51.10.1M.patch8.
1 2 3 4 5 6 7 | # FORTRAN IV DLOG PATCH (JR) # # There is a problem with DLOG where it could not handle numbers smaller than # 1.E-018 correctly. The following patch fixes this problem. # # Make a source change to DLOG.RA using either EDIT or TECO. Replace # this line: | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # FORTRAN IV DLOG PATCH (JR) # # There is a problem with DLOG where it could not handle numbers smaller than # 1.E-018 correctly. The following patch fixes this problem. # # Make a source change to DLOG.RA using either EDIT or TECO. Replace # this line: # # DALA, EADD DAL1 /ADD BACK # with : # DALA, FLDA$ BPDAL /GET ARGUMENT BACK # .R RALF # *DLOG.RL<DLOG.RA # .R LIBRA # *FORLIB.RL<FORLIB.RL,DLOG.RL/Z/R |
Deleted media/os8/patches/OVRDRV-40.6.1M-v1B-8srccom.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to media/os8/patches/TECO-31.20.07M.v5C.patch8.
︙ | ︙ | |||
13 14 15 16 17 18 19 | # This mechanism works correctly except that the ringing of the bell # is accompanied by the printing of the (unwanted) two-character sequence "^G". # TECO is ringing the bell by calling TYPTCV instead of TPUT. # # The following patch corrects this problem, by causing # only a warning bell to ring. This patch upgrades TECO to V5C. | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 | # This mechanism works correctly except that the ringing of the bell # is accompanied by the printing of the (unwanted) two-character sequence "^G". # TECO is ringing the bell by calling TYPTCV instead of TPUT. # # The following patch corrects this problem, by causing # only a warning bell to ring. This patch upgrades TECO to V5C. . GET SYS TECO .ODT 0365/ 4521 4552 4573/ 0766 0767 \c .SAVE SYS TECO |
Changes to media/os8/patches/patch_list.txt.
|
| | | < < < < < | < < < < < < < < < > | < < < < < < < < < | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | # All but one of these patches have been verified # by reading the source code. # The patches that remain commented out are not recommended # and the reason why appears in the line above it. # Total of 44 of 54 So far. BASIC.UF-31.5.1M-V5B.patch8 BATCH-31.23.1M-v7B.patch8 BLOAD-31.10.1M-v5B.patch8 BRTS-31.11.1M-v5B.patch8 # BRTS 31.11.2O disables 8th bit parity. Recommended. BRTS-31.11.2-O.patch8 # BRTS 31.11.3O enables 132 column output. Recommended. BRTS-31.11.3-O.patch8 BRTS-31.11.5-x.patch8 CREF-21.15.1M-v5B.patch8 CREF-21.15.2M-v5C.patch8 EDIT-21.17.1M-v12B.patch8 EDIT-21.17.2M-v12C.patch8 EDIT-21.17.3M-v12D.patch8 # EDIT 21.17.4 overwrites patch in 21.17.2 and is NOT recommended. # EDIT-21.17.4M-V12C.patch8 F4-21.1.2M-v4B.patch8 F4-51.3.1M-v4C.patch8 F4-51.3.2M-v4x.patch8 FOTP-21.19.1M-V9B.patch8 # Can't verify FRTS because I don't know how to get a # .LS file to verify against. Nevertheless the patch is recommended. FRTS-51.3.3-O.patch8 FUTIL-31.21.1M-v7B.patch8 FUTIL-31.21.2M-v7D.patch8 # FUTIL 31.21.3O switches XS format. Recommend to leave it out. # FUTIL-31.21.3O.patch8 MCPIP-21.21M-v6B.patch8 MSBAT-31.22.1M-v3B.patch8 PAL8-21.22.1M-v10B.patch8 PAL8-21.22.2M-v10C.patch8 PAL8-21.22.3M-v10D.patch8 # Will verify this tomorrow PIP-21.23.1M-v12B.patch8 PIP10-21.24.1M-v3B.patch8 SABR-21.91.1M-v18B.patch8 SET-21.26.1M-v1C.patch8 SET-21.26.2M-v1D.patch8 SET-21.26.3M-v1E.patch8 # TECO 31.20.1 Unconditional no case flagging. Not recommended |
︙ | ︙ | |||
78 79 80 81 82 83 84 | TECO-31.20.06M-v5B.patch8 TECO-31.20.07M.v5C.patch8 TECO-31.20.08M-v5.04.patch8 TECO-31.20.10M-5.05.patch8 TECO-31.20.11M-v5.06.patch8 TECO-31.20.12M-v5.07.patch8 TECO-31.20.13M-v5.08.patch8 | < < < < < < < < < < < < | 54 55 56 57 58 59 60 | TECO-31.20.06M-v5B.patch8 TECO-31.20.07M.v5C.patch8 TECO-31.20.08M-v5.04.patch8 TECO-31.20.10M-5.05.patch8 TECO-31.20.11M-v5.06.patch8 TECO-31.20.12M-v5.07.patch8 TECO-31.20.13M-v5.08.patch8 |
Deleted media/os8/subsys/al-4545d-sa-fr4-v3d-1.tu56.
cannot compute difference between binary files
Deleted media/os8/subsys/al-4546d-sa-fr4-v3d-2.tu56.
cannot compute difference between binary files
Deleted media/os8/subsys/al-4547d-sa-fr4-v3d-3.tu56.
cannot compute difference between binary files
Deleted media/os8/subsys/al-4549d-ba-fr4-v3d-1.1978.tu56.
cannot compute difference between binary files
Deleted media/os8/subsys/al-5596d-ba-fr4-v3d-2.1978.tu56.
cannot compute difference between binary files
Changes to media/os8/subsys/cc8.tu56.
cannot compute difference between binary files
Added palbart/LICENSE.md.
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # palbart License The following was extracted from the top of [`palbart.c`][1] in this directory: --------- This is free software. There is no fee for using it. You may make any changes that you wish and also give it away. If you can make commercial product out of it, fine, but do not put any limits on the purchaser's right to do the same. If you improve it or fix any bugs, it would be nice if you told me and offered me a copy of the new version. --------- [1]: https://tangentsoft.com/pidp8i/doc/trunk/palbart/palbart.c |
Added palbart/palbart.1.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | .\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH PALBART 1 "January 16, 2000" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp <n> insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME palbart \- BART enhanced PDP8 crossassembler .SH SYNOPSIS .B palbart .RI [options] inputfile .br .SH DESCRIPTION This manual page documents briefly the .B palbart command. It is a cross-assembler to for PDP/8 assembly language programs. It will produce an output file in bin format, rim format, and using the appropriate pseudo-ops, a combination of rim and bin formats. A listing file is always produced and with an optional symbol table and/or a symbol cross-reference (concordance). The permanent symbol table can be output in a form that may be read back in so a customized permanent symbol table can be produced. Any detected errors are output to a separate file giving the filename in which they were detected along with the line number, column number and error message as well as marking the error in the listing file. .PP The following file name extensions are used: .PP .pal source code (input) .PP .lst assembly listing (output) .PP .bin assembly output in DEC's bin format (output) .PP .rim assembly output in DEC's rim format (output) .PP .err assembly errors detected (if any) (output) .PP .prm permanent symbol table in form suitable for reading after the EXPUNGE pseudo-op. .PP .SH OPTIONS A summary of options is included below. .TP .B \-d Show symbol table at end of assembly .TP .B \-h Display help. .TP .B \-l Allow generation of literals (default is no literal generation) Show version of program. .TP .B \-p Generate a file with the permanent symbols in it. (To get the current symbol table, assemble a file than has only a $ in it.) .TP .B \-r Produce output in rim format (default is bin format) .TP .B \-v Display version information. .TP .B \-x Generate a cross-reference (concordance) of user symbols. .SH DIAGNOSTICS Assembler error diagnostics are output to an error file and inserted in the listing file. Each line in the error file has the form .PP <filename>(<line>:<col>) : error: <message> at Loc = <loc> .PP An example error message is: .br bintst.pal(17:9) : error: undefined symbol "UNDEF" at Loc = 07616 .PP The error diagnostics put in the listing start with a two character error code (if appropriate) and a short message. A carat '^' is placed under the item in error if appropriate. An example error message is: .PP 17 07616 3000 DCA UNDEF .br UD undefined ^ .br 18 07617 1777 TAD I DUMMY .PP When an indirect is generated, an at character '@' is placed after the the instruction value in the listing as an indicator as follows: .PP 14 03716 1777@ TAD OFFPAG .PP Undefined symbols are marked in the symbol table listing by prepending a '?' to the symbol. Redefined symbols are marked in the symbol table listing by prepending a '#' to the symbol. Examples are: .PP #REDEF 04567 .br SWITCH 07612 .br ?UNDEF 00000 .PP Refer to the code for the diagnostic messages generated. .SH BUGS Only a minimal effort has been made to keep the listing format anything like the PAL-8 listing format. The operation of the conditional assembly pseudo-ops may not function exactly as the DEC versions. I did not have any examples of these so the implementation is my interpretation of how they should work. .PP The RIMPUNch and BINPUNch pseudo-ops do not change the binary output file type that was specified on startup. This was intentional and and allows rim formatted data to be output prior to the actual binary formatted data. On UN*X style systems, the same effect can be achieved ing the "cat" command, but on DOS/Windows systems, doing this was a major chore. .PP The floating point input does not generate values exactly as the DEC compiler does. I worked out several examples by hand and believe that this implementation is slightly more accurate. If I am mistaken, let me know and, if possible, a better method of generating the values. .br .SH HISTORICAL NOTE This assembler was written to support the fleet of PDP-8 systems used by the Bay Area Rapid Transit System. As of early 1997, this includes about 40 PDP-8/E systems driving the train destination signs in passenger stations. .SH REFERENCES This assembler is based on the pal assember by: .br Douglas Jones <jones@cs.uiowa.edu> and .br Rich Coon <coon@convexw.convex.com> .SH DISCLAIMER See the symbol table for the set of pseudo-ops supported. .PP See the code for pseudo-ops that are not standard for PDP/8 assembly. .PP Refer to DEC's "Programming Languages (for the PDP/8)" for complete documentation of pseudo-ops. .PP Refer to DEC's "Introduction to Programming (for the PDP/8)" or a lower level introduction to the assembly language. .SH WARRANTY If you don't like it the way it works or if it doesn't work, that's tough. You're welcome to fix it yourself. That's what you get for using free software. .SH COPYRIGHT NOTICE This is free software. There is no fee for using it. You may make any changes that you wish and also give it away. If you can make a commercial product out of it, fine, but do not put any limits on the purchaser's right to do the same. If you improve it or fix any bugs, it would be nice if you told me and offered me a copy of the new version. Gary Messenbrink <gam@rahul.net> .SH VERSIONS Version Date by Comments .br v1.0 12Apr96 GAM Original .br v1.1 18Nov96 GAM Permanent symbol table initialization error. .br v1.2 20Nov96 GAM Added BINPUNch and RIMPUNch pseudo-operators. .br v1.3 24Nov96 GAM Added DUBL pseudo-op (24 bit integer constants). .br v1.4 29Nov96 GAM Fixed bug in checksum generation. .br v2.1 08Dec96 GAM Added concordance processing (cross reference). .br v2.2 10Dec96 GAM Added FLTG psuedo-op (floating point constants). .br v2.3 2Feb97 GAM Fixed paging problem in cross reference output. .br v2.4 11Apr97 GAM Fixed problem with some labels being put in cross reference multiple times. .SH AUTHOR This manual page was written by Vince Mulhollon <vlm@execpc.com>, for the Debian GNU/Linux system (but may be used by others). |
Added palbart/palbart.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 | /******************************************************************************/ /* */ /* Program: PAL (BART version) */ /* File: pal.c */ /* Author: Gary A. Messenbrink */ /* gam@rahul.net */ /* */ /* Purpose: A 2 pass PDP-8 pal-like assembler. */ /* */ /* PAL(1) */ /* */ /* NAME */ /* pal - a PDP/8 pal-like assembler. */ /* */ /* SYNOPSIS: */ /* pal [ -$ -d -h -e -l -p -r -t -v -x ] inputfile */ /* */ /* DESCRIPTION */ /* This is a cross-assembler to for PDP/8 assembly language programs. */ /* It will produce an output file in bin format, rim format, and using the */ /* appropriate pseudo-ops, a combination of rim and bin formats. */ /* A listing file is always produced and with an optional symbol table */ /* and/or a symbol cross-reference (concordance). The permanent symbol */ /* table can be output in a form that may be read back in so a customized */ /* permanent symbol table can be produced. Any detected errors are output */ /* to a separate file giving the filename in which they were detected */ /* along with the line number, column number and error message as well as */ /* marking the error in the listing file. */ /* The following file name extensions are used: */ /* .pal source code (input) */ /* .lst assembly listing (output) */ /* .bin assembly output in DEC's bin format (output) */ /* .rim assembly output in DEC's rim format (output) */ /* .err assembly errors detected (if any) (output) */ /* .prm permanent symbol table in form suitable for reading after */ /* the EXPUNGE pseudo-op. */ /* */ /* OPTIONS */ /* -$ Allow files to not end with $ */ /* -d Dump the symbol table at end of assembly */ /* -h Show help */ /* -e Don't allow generation of links */ /* -l Allow generation of links (default is link generation) */ /* -n No redefinition of permanent symbols with labels */ /* -p Generate a file with the permanent symbols in it. */ /* (To get the current symbol table, assemble a file than has only */ /* a $ in it.) */ /* -r Produce output in rim format (default is bin format) */ /* -tN Set tab stops to N spaces (default is 8) */ /* -v Display program version. */ /* -x Generate a cross-reference (concordance) of user symbols. */ /* */ /* DIAGNOSTICS */ /* Assembler error diagnostics are output to an error file and inserted */ /* in the listing file. Each line in the error file has the form */ /* */ /* <filename>(<line>:<col>) : error: <message> at Loc = <loc> */ /* */ /* An example error message is: */ /* */ /* bintst.pal(17:9) : error: undefined symbol "UNDEF" at Loc = 07616 */ /* */ /* The error diagnostics put in the listing start with a two character */ /* error code (if appropriate) and a short message. A carat '^' is */ /* placed under the item in error if appropriate. */ /* An example error message is: */ /* */ /* 17 07616 3000 DCA UNDEF */ /* UD undefined ^ */ /* 18 07617 1777 TAD I DUMMY */ /* */ /* When an indirect is generated, an at character '@' is placed after the */ /* the instruction value in the listing as an indicator as follows: */ /* */ /* 14 03716 1777@ TAD OFFPAG */ /* */ /* Undefined symbols are marked in the symbol table listing by prepending */ /* a '?' to the symbol. Redefined symbols are marked in the symbol table */ /* listing by prepending a '#' to the symbol. Examples are: */ /* */ /* #REDEF 04567 */ /* SWITCH 07612 */ /* ?UNDEF 00000 */ /* */ /* Refer to the code for the diagnostic messages generated. */ /* */ /* BUGS */ /* This program will accept source that real PAL will not. To ensure */ /* valid source assemble on real or simulated PDP-8. */ /* Different PAL versions have different permanent symbols defined. This */ /* program define more than and PAL version. By default redefining them */ /* as a label is not an error. It is for normal PAL. The -n flag will */ /* make redefining an error. */ /* */ /* Only a minimal effort has been made to keep the listing format */ /* anything like the PAL-8 listing format. */ /* The operation of the conditional assembly pseudo-ops may not function */ /* exactly as the DEC versions. I did not have any examples of these so */ /* the implementation is my interpretation of how they should work. */ /* */ /* The RIMPUNch and BINPUNch pseudo-ops do not change the binary output */ /* file type that was specified on startup. This was intentional and */ /* and allows rim formatted data to be output prior to the actual binary */ /* formatted data. On UN*X style systems, the same effect can be achieved */ /* by using the "cat" command, but on DOS/Windows systems, doing this was */ /* a major chore. */ /* */ /* The floating point input does not generate values exactly as the DEC */ /* compiler does. I worked out several examples by hand and believe that */ /* this implementation is slightly more accurate. If I am mistaken, */ /* let me know and, if possible, a better method of generating the values. */ /* */ /* CDF .-. */ /* Generates 2201 when assembled at 5000. This looks like a bug in OS/8 */ /* PAL */ /* */ /* BUILD and INSTALLATION */ /* The current version has only been built under Linux. */ /* Earlier versions have been built and successfully executed on: */ /* a. Linux (80486 CPU)using gcc */ /* b. RS/6000 (AIX 3.2.5) */ /* c. Borland C++ version 3.1 (large memory model) */ /* d. Borland C++ version 4.52 (large memory model) */ /* with no modifications to the source code. */ /* */ /* On UNIX type systems, store the the program as the pal command */ /* and on PC type systems, store it as pal.exe */ /* */ /* HISTORICAL NOTE: */ /* This assembler was written to support the fleet of PDP-8 systems */ /* used by the Bay Area Rapid Transit System. As of early 1997, */ /* this includes about 40 PDP-8/E systems driving the train destination */ /* signs in passenger stations. */ /* */ /* REFERENCES: */ /* This assembler is based on the pal assembler by: */ /* Douglas Jones <jones@cs.uiowa.edu> and */ /* Rich Coon <coon@convexw.convex.com> */ /* */ /* DISCLAIMER: */ /* See the symbol table for the set of pseudo-ops supported. */ /* See the code for pseudo-ops that are not standard for PDP/8 assembly. */ /* Refer to DEC's "Programming Languages (for the PDP/8)" for complete */ /* documentation of pseudo-ops. */ /* Refer to DEC's "Introduction to Programming (for the PDP/8)" or a */ /* lower level introduction to the assembly language. */ /* */ /* WARRANTY: */ /* If you don't like it the way it works or if it doesn't work, that's */ /* tough. You're welcome to fix it yourself. That's what you get for */ /* using free software. */ /* */ /* COPYRIGHT NOTICE: */ /* This is free software. There is no fee for using it. You may make */ /* any changes that you wish and also give it away. If you can make */ /* a commercial product out of it, fine, but do not put any limits on */ /* the purchaser's right to do the same. If you improve it or fix any */ /* bugs, it would be nice if you told me and offered me a copy of the */ /* new version. */ /* */ /* */ /* Amendments Record: */ /* Version Date by Comments */ /* ------- ------- --- --------------------------------------------------- */ /* v1.0 12Apr96 GAM Original */ /* v1.1 18Nov96 GAM Permanent symbol table initialization error. */ /* v1.2 20Nov96 GAM Added BINPUNch and RIMPUNch pseudo-operators. */ /* v1.3 24Nov96 GAM Added DUBL pseudo-op (24 bit integer constants). */ /* v1.4 29Nov96 GAM Fixed bug in checksum generation. */ /* v2.1 08Dec96 GAM Added concordance processing (cross reference). */ /* v2.2 10Dec96 GAM Added FLTG psuedo-op (floating point constants). */ /* v2.3 2Feb97 GAM Fixed paging problem in cross reference output. */ /* DJG: I started with the 2.5 RK version but found when looking on the net */ /* later that multiple diverging version existed. I have tried to combine */ /* the fixed into one version. I took the version info below from the versions*/ /* I pulled from. */ /* http://dustyoldcomputers.com/pdp-common/reference/host/index.html */ /* http://www.dunnington.u-net.com/public/PDP-8/palbart.c */ /* http://sourcecodebrowser.com/palbart/2.4/palbart-2_84_8c_source.html */ /* http://packages.qa.debian.org/p/palbart.html */ /* v2.4 11Apr97 GAM Fixed problem with some labels being put in cross */ /* reference multiple times. */ /* Started with RK version, Attempted to merge */ /* GAM V2.4 and PNT change DJG */ /* v2.4 29Oct07 RK Added 4 character tabstop; IOTs for TA8/E. */ /* v2.4 19Jan03 PNT Added ASCII pseudo-op, like TEXT but not packed. */ /* v2.5 03Nov07 RK Fixed buffer overflow problem in readLine and */ /* increased symbol table size */ /* v2.6 14Jul03 PNT Added missing TTY symbols, and "1st TTY" symbols. */ /* v2.7 14Jun13 DJG David Gesswein djg@pdp8online.com */ /* Merged other changes found online giving duplicate */ /* Versions in the history */ /* Didn't copy over deleting -l literal flag */ /* All fixes to make it match OS/8 PAL8 better */ /* Fixed handling of IFDEF type conditionals */ /* Fixed excessive redefined symbol errors */ /* PAL8 uses 12 bit symbols and this program label */ /* symbols are 15 bit. */ /* Added FILENAME and DEVNAME psuedo ops */ /* Added OPR and KCF instructions. Fixed RMF */ /* Allowed space after = */ /* Prevented I and D from being deleted by EXPUNGE */ /* Allowed permanent symbols to be redefined with error*/ /* PAL8 updates without message. Error is just warning*/ /* Fixed certain cases of memory reference generation */ /* Allowed unary + */ /* Fixed " character literal at end of line */ /* Fixed errors in reloc handling */ /* Fixed [CDF CIF type expressions */ /* Made title default to first line */ /* Fixed checksum when nopunch used */ /* Fixed FIXTAB */ /* Probably added more subtle bugs */ /* v2.8 15Jun13 DJG Merged versions found on net. See above */ /* Added * to RELOC addresses in listing */ /* Changed default to literal/links on. Added -e to */ /* turn off */ /* Fixed PAGE when RELOC used */ /* Changed SPF to TFL and SPI to TSK */ /* Make error when changing permanent symbol to label */ /* if -e flag is used */ /* Allow space oring in IFZERO etc */ /* Fixed handling of page zero overflow */ /* v2.9 23Jun13 DJG Fixed properly all pages literal handling */ /* changing page doesn't cause loss of last literal */ /* location used. */ /* Fixed bin generation if no origin set */ /* v2.9a 01Jul13 DJG Fixed Comment. Binaries not updated */ /* v2.10 08Feb14 DJG Changed trailer to 8 bytes since pip didn't like */ /* trailer of one 0x80 */ /* v2.11 19Apr15 DPI Fixed incorrect link generation with impled 0200 */ /* starting address. Patch from Doug Ingrams */ /* v2.12 28Apr15 DJG Fixed incorrect handling of reloc, expressions with */ /* undefined symbols. Fixed conditional assembly with */ /* undefined symbols. Added new flag to allow file to */ /* not end with $ */ /* v2.13 02May15 DPI Fixed bug in readLine when removing \r from a blank */ /* line. Changed -s to -$ in -h display. Corrected */ /* version comment. */ /* v2.13 03May15 DJG Moved TITLE, BANK to new additional option. */ /* Change release variable below when you update. Send changes back to */ /* David Gesswein, djg@pdp8online.com. */ /******************************************************************************/ #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> char *release = "pal-2.13, 03 May 2015"; /* Set to 1 and use -e flag to make ( and [ literals errors */ #define LITERAL_ERROR 0 #define LINELEN 132 #define LIST_LINES_PER_PAGE 55 /* Includes 5 line page header. */ #define NAMELEN 128 #define SYMBOL_COLUMNS 5 #define SYMLEN 7 #define SYMBOL_TABLE_SIZE 4096 #define TITLELEN 63 #define XREF_COLUMNS 8 #define ADDRESS_FIELD 00177 #define FIELD_FIELD 070000 #define INDIRECT_BIT 00400 #define LAST_PAGE_LOC 00177 #define OP_CODE 07000 #define PAGE_BIT 00200 #ifdef PAGE_SIZE #undef PAGE_SIZE #endif #define PAGE_SIZE 00200 #define PAGE_FIELD 07600 #define PAGE_ZERO_END 00200 /* Macro to get the number of elements in an array. */ #define DIM(a) (sizeof(a)/sizeof(a[0])) /* Macro to get the address plus one of the end of an array. */ #define BEYOND(a) ((a) + DIM(A)) #define is_blank(c) ((c==' ') || (c=='\t') || (c=='\f') || (c=='>')) #define isend(c) ((c=='\0')|| (c=='\n')) #define isdone(c) ((c=='/') || (isend(c)) || (c==';')) /* Macros for testing symbol attributes. Each macro evaluates to non-zero */ /* (true) if the stated condition is met. */ /* Use these to test attributes. The proper bits are extracted and then */ /* tested. */ #define M_CONDITIONAL(s) ((s & CONDITION) == CONDITION) #define M_DEFINED(s) ((s & DEFINED) == DEFINED) #define M_DUPLICATE(s) ((s & DUPLICATE) == DUPLICATE) #define M_FIXED(s) ((s & FIXED) == FIXED) #define M_LABEL(s) ((s & LABEL) == LABEL) #define M_MRI(s) ((s & MRI) == MRI) #define M_MRIFIX(s) ((s & MRIFIX) == MRIFIX) #define M_PSEUDO(s) ((s & PSEUDO) == PSEUDO) #define M_REDEFINED(s) ((s & REDEFINED) == REDEFINED) #define M_UNDEFINED(s) (!M_DEFINED(s)) #define M_PERM_REDEFINED(s) ((s & PERM_REDEFINED) == PERM_REDEFINED) /* This macro is used to test symbols by the conditional assembly pseudo-ops. */ #define M_DEF(s) (M_DEFINED(s)) #define M_COND(s) (M_CONDITIONAL(s)) #define M_DEFINED_CONDITIONALLY(t) (M_DEF(t) && ((pass==1) ||!M_COND(t))) typedef unsigned char BOOL; typedef unsigned char BYTE; typedef short int WORD16; typedef long int WORD32; #ifndef FALSE #define FALSE 0 #define TRUE (!FALSE) #endif /* Line listing styles. Used to control listing of lines. */ enum linestyle_t { LINE, LINE_VAL, LINE_LOC_VAL, LOC_VAL }; typedef enum linestyle_t LINESTYLE_T; /* Symbol Types. */ /* Note that the names that have FIX as the suffix contain the FIXED bit */ /* included in the value. */ /* */ /* The CONDITION bit is used when processing the conditional assembly PSEUDO- */ /* OPs (e.g., IFDEF). During pass 1 of the assembly, the symbol is either */ /* defined or undefined. The condition bit is set when the symbol is defined */ /* during pass 1 and reset on pass 2 at the location the symbol was defined */ /* during pass 1. When processing conditionals during pass 2, if the symbol */ /* is defined and the condition bit is set, the symbol is treated as if it */ /* were undefined. This gives consistent behavior of the conditional */ /* pseudo-ops during both pass 1 and pass 2. */ enum symtyp { UNDEFINED = 0000, DEFINED = 0001, FIXED = 0002, MRI = 0004 | DEFINED, LABEL = 0010 | DEFINED, REDEFINED = 0020 | DEFINED, DUPLICATE = 0040 | DEFINED, PSEUDO = 0100 | FIXED | DEFINED, CONDITION = 0200 | DEFINED, PERM_REDEFINED = 0400, MRIFIX = MRI | FIXED | DEFINED, DEFFIX = DEFINED | FIXED }; typedef enum symtyp SYMTYP; enum pseudo_t { BANK, BINPUNCH, DECIMAL, DUBL, EJECT, ENPUNCH, EXPUNGE, FIELD, FIXMRI, FIXTAB, FLTG, IFDEF, IFNDEF, IFNZERO, IFZERO, NOPUNCH, OCTAL, PAGE, PAUSE, RELOC, RIMPUNCH, SEGMNT, TEXT, TITLE, XLIST, ZBLOCK, FILENAME, DEVICE, ASCII }; typedef enum pseudo_t PSEUDO_T; struct sym_t { SYMTYP type; char name[SYMLEN]; WORD16 val; int xref_index; int xref_count; }; typedef struct sym_t SYM_T; struct lpool_t { WORD16 loc; WORD16 last_punched; WORD16 pool[PAGE_SIZE]; }; typedef struct lpool_t LPOOL_T; struct emsg_t { char *list; char *file; }; typedef struct emsg_t EMSG_T; struct errsave_t { char *mesg; int col; }; typedef struct errsave_t ERRSAVE_T; struct fltg_ { WORD16 exponent; WORD32 mantissa; }; typedef struct fltg_ FLTG_T; /*----------------------------------------------------------------------------*/ /* Function Prototypes */ int binarySearch( char *name, int start, int symbol_count ); int compareSymbols( const void *a, const void *b ); void conditionFalse( void ); void conditionTrue( void ); SYM_T *defineLexeme( int start, int term, WORD16 val, SYMTYP type ); SYM_T *defineSymbol( char *name, WORD16 val, SYMTYP type, WORD16 start); void endOfBinary( void ); void errorLexeme( EMSG_T *mesg, int col ); void errorMessage( EMSG_T *mesg, int col ); void errorSymbol( EMSG_T *mesg, char *name, int col ); SYM_T *eval( void ); WORD32 evalDubl( WORD32 initial_value ); FLTG_T *evalFltg( void ); SYM_T *evalSymbol( void ); void getArgs( int argc, char *argv[] ); WORD32 getDublExpr( void ); WORD32 getDublExprs( void ); FLTG_T *getFltgExpr( void ); FLTG_T *getFltgExprs( void ); SYM_T *getExpr( void ); WORD16 getExprs( void ); WORD16 incrementClc( void ); void inputDubl( void ); void inputFltg( void ); WORD16 insertLiteral( LPOOL_T *pool, WORD16 value, int fieldpage_index ); char *lexemeToName( char *name, int from, int term ); void listLine( void ); SYM_T *lookup( char *name ); void moveToEndOfLine( void ); void nextLexBlank( void ); void nextLexeme( void ); void normalizeFltg( FLTG_T *fltg ); void onePass( void ); void printCrossReference( void ); void printErrorMessages( void ); void printLine(char *line, WORD16 loc, WORD16 val, LINESTYLE_T linestyle); void printPageBreak( void ); void printPermanentSymbolTable( void ); void printSymbolTable( void ); BOOL pseudoOperators( PSEUDO_T val ); void punchChecksum( void ); void punchLocObject( WORD16 loc, WORD16 val ); void punchLiteralPool( LPOOL_T *p, BOOL punch_page0 ); void punchOutObject( WORD16 loc, WORD16 val ); void punchLeader( int count ); void punchObject( WORD16 val ); void punchOrigin( WORD16 loc ); void readLine( void ); void saveError( char *mesg, int cc ); BOOL testForLiteralCollision( WORD16 loc ); void topOfForm( char *title, char *sub_title ); /*----------------------------------------------------------------------------*/ /* Table of pseudo-ops (directives) which are used to setup the symbol */ /* table on startup and when the EXPUNGE pseudo-op is executed. */ SYM_T pseudo[] = { { PSEUDO, "ASCII", ASCII }, /* Put 8-bit ASCII into memory (see TEXT) */ { PSEUDO, "BINPUN", BINPUNCH }, /* Output in Binary Loader format. */ { PSEUDO, "DECIMA", DECIMAL }, /* Read literal constants in base 10. */ { PSEUDO, "DEVICE", DEVICE }, /* Pack 6 bit device name into memory */ { PSEUDO, "DUBL", DUBL }, /* Ignored (unsupported). */ { PSEUDO, "EJECT", EJECT }, /* Eject a page in the listing. */ { PSEUDO, "ENPUNC", ENPUNCH }, /* Turn on object code generation. */ { PSEUDO, "EXPUNG", EXPUNGE }, /* Remove all symbols from symbol table. */ { PSEUDO, "FIELD", FIELD }, /* Set origin to memory field. */ { PSEUDO, "FILENA", FILENAME }, /* Pack 6 bit filename into memory. */ { PSEUDO, "FIXMRI", FIXMRI }, /* Like =, but creates mem ref instruction*/ { PSEUDO, "FIXTAB", FIXTAB }, /* Mark current symbols as permanent. */ { PSEUDO, "FLTG", FLTG }, /* Ignored (unsupported). */ { PSEUDO, "IFDEF", IFDEF }, /* Assemble if symbol is defined. */ { PSEUDO, "IFNDEF", IFNDEF }, /* Assemble if symbol is not defined. */ { PSEUDO, "IFNZER", IFNZERO }, /* Assemble if symbol value is not 0. */ { PSEUDO, "IFNZRO", IFNZERO }, /* Assemble if symbol value is not 0. */ { PSEUDO, "IFZERO", IFZERO }, /* Assemble if symbol value is 0. */ { PSEUDO, "NOPUNC", NOPUNCH }, /* Turn off object code generation. */ { PSEUDO, "OCTAL", OCTAL }, /* Read literal constants in base 8. */ { PSEUDO, "PAGE", PAGE }, /* Set orign to page +1 or page n (0..37).*/ { PSEUDO, "PAUSE", PAUSE }, /* Ignored */ { PSEUDO, "RELOC", RELOC }, /* Assemble to run at a different address.*/ { PSEUDO, "RIMPUN", RIMPUNCH }, /* Output in Read In Mode format. */ { PSEUDO, "SEGMNT", SEGMNT }, /* Like page, but with page size=1K words.*/ { PSEUDO, "TEXT", TEXT }, /* Pack 6 bit trimmed ASCII into memory. */ { PSEUDO, "XLIST", XLIST }, /* Toggle listing generation. */ { PSEUDO, "ZBLOCK", ZBLOCK }, /* Zero a block of memory. */ { PSEUDO, "TITLE", TITLE }, /* Use the text string as a listing title.*/ { PSEUDO, "BANK", BANK } /* Like field, select some 32K out of 128K*/ }; /* Number o extended pseudo operators to ignore unless command option specified * to enable */ #define NUMBER_ADDITIONAL_PSEUDO 2 /* Symbol Table */ /* The table is put in lexical order on startup, so symbols can be */ /* inserted as desired into the initial table. */ /* really_permanent_symbols aren't removed by EXPUNGE */ SYM_T really_permanent_symbols[] = { { MRIFIX, "I", 00400 }, /* INDIRECT ADDRESSING */ { MRIFIX, "Z", 00000 } /* PAGE ZERO ADDRESS */ }; SYM_T permanent_symbols[] = { /* Memory Reference Instructions */ { MRIFIX, "AND", 00000 }, /* LOGICAL AND */ { MRIFIX, "TAD", 01000 }, /* TWO'S COMPLEMENT ADD */ { MRIFIX, "ISZ", 02000 }, /* INCREMENT AND SKIP IF ZERO */ { MRIFIX, "DCA", 03000 }, /* DEPOSIT AND CLEAR ACC */ { MRIFIX, "JMP", 05000 }, /* JUMP */ { MRIFIX, "JMS", 04000 }, /* JUMP TO SUBROUTINE */ /* Floating Point Interpreter Instructions */ { MRIFIX, "FEXT", 00000 }, /* FLOATING EXIT */ { MRIFIX, "FADD", 01000 }, /* FLOATING ADD */ { MRIFIX, "FSUB", 02000 }, /* FLOATING SUBTRACT */ { MRIFIX, "FMPY", 03000 }, /* FLOATING MULTIPLY */ { MRIFIX, "FDIV", 04000 }, /* FLOATING DIVIDE */ { MRIFIX, "FGET", 05000 }, /* FLOATING GET */ { MRIFIX, "FPUT", 06000 }, /* FLOATING PUT */ { FIXED, "FNOR", 07000 }, /* FLOATING NORMALIZE */ { FIXED, "FEXT", 00000 }, /* EXIT FROM FLOATING POINT INTERPRETER */ { FIXED, "SQUARE", 00001 }, /* SQUARE C(FAC) */ { FIXED, "SQROOT", 00002 }, /* TAKE SQUARE ROOT OF C(FAC) */ /* Group 1 Operate Microinstrcutions */ { FIXED, "OPR", 07000 }, /* NO OPERATION */ { FIXED, "NOP", 07000 }, /* NO OPERATION */ { FIXED, "IAC", 07001 }, /* INCREMENT AC */ { FIXED, "RAL", 07004 }, /* ROTATE AC AND LINK LEFT ONE */ { FIXED, "RTL", 07006 }, /* ROTATE AC AND LINK LEFT TWO */ { FIXED, "RAR", 07010 }, /* ROTATE AC AND LINK RIGHT ONE */ { FIXED, "RTR", 07012 }, /* ROTATE AC AND LINK RIGHT TWO */ { FIXED, "CML", 07020 }, /* COMPLEMENT LINK */ { FIXED, "CMA", 07040 }, /* COMPLEMEMNT AC */ { FIXED, "CLL", 07100 }, /* CLEAR LINK */ { FIXED, "CLA", 07200 }, /* CLEAR AC */ /* Group 2 Operate Microinstructions */ { FIXED, "BSW", 07002 }, /* Swap bytes in AC (PDP/8e) */ { FIXED, "HLT", 07402 }, /* HALT THE COMPUTER */ { FIXED, "OSR", 07404 }, /* INCLUSIVE OR SR WITH AC */ { FIXED, "SKP", 07410 }, /* SKIP UNCONDITIONALLY */ { FIXED, "SNL", 07420 }, /* SKIP ON NON-ZERO LINK */ { FIXED, "SZL", 07430 }, /* SKIP ON ZERO LINK */ { FIXED, "SZA", 07440 }, /* SKIP ON ZERO AC */ { FIXED, "SNA", 07450 }, /* SKIP ON NON=ZERO AC */ { FIXED, "SMA", 07500 }, /* SKIP MINUS AC */ { FIXED, "SPA", 07510 }, /* SKIP ON POSITIVE AC (ZERO IS POSITIVE) */ /* Combined Operate Microinstructions */ { FIXED, "CIA", 07041 }, /* COMPLEMENT AND INCREMENT AC */ { FIXED, "STL", 07120 }, /* SET LINK TO 1 */ { FIXED, "GLK", 07204 }, /* GET LINK (PUT LINK IN AC BIT 11) */ { FIXED, "STA", 07240 }, /* SET AC TO -1 */ { FIXED, "LAS", 07604 }, /* LOAD ACC WITH SR */ /* MQ Instructions (PDP/8e) */ { FIXED, "MQL", 07421 }, /* Load MQ from AC, then clear AC. */ { FIXED, "MQA", 07501 }, /* Inclusive OR MQ with AC */ { FIXED, "SWP", 07521 }, /* Swap AC and MQ */ { FIXED, "ACL", 07701 }, /* Load MQ into AC */ /* Program Interrupt */ { FIXED, "IOT", 06000 }, { FIXED, "ION", 06001 }, /* TURN INTERRUPT PROCESSOR ON */ { FIXED, "IOF", 06002 }, /* TURN INTERRUPT PROCESSOR OFF */ /* Program Interrupt, PDP-8/e */ { FIXED, "SKON", 06000 }, /* Skip if interrupt on and turn int off. */ { FIXED, "SRQ", 06003 }, /* Skip on interrupt request. */ { FIXED, "GTF", 06004 }, /* Get interrupt flags. */ { FIXED, "RTF", 06005 }, /* Restore interrupt flags. */ { FIXED, "SGT", 06006 }, /* Skip on greater than flag. */ { FIXED, "CAF", 06007 }, /* Clear all flags. */ /* Keyboard/Reader */ { FIXED, "KCF", 06030 }, /* CLEAR KEYBOAR FLAG */ { FIXED, "KSF", 06031 }, /* SKIP ON KEYBOARD FLAG */ { FIXED, "KCC", 06032 }, /* CLEAR KEYBOARD FLAG & READ CHAR */ { FIXED, "KRS", 06034 }, /* READ KEYBOARD BUFFER (STATIC) */ { FIXED, "KIE", 06035 }, /* AC11 TO KEYBD/RDR INT ENABLE F/F */ { FIXED, "KRB", 06036 }, /* READ KEYBOARD BUFFER & CLEAR FLAG */ /* Teleprinter/Punch */ { FIXED, "TFL", 06040 }, /* SET TELEPRINTER/PUNCH FLAG */ { FIXED, "TSF", 06041 }, /* SKIP ON TELEPRINTER FLAG */ { FIXED, "TCF", 06042 }, /* CLEAR TELEPRINTER FLAG */ { FIXED, "TPC", 06044 }, /* LOAD TELEPRINTER & PRINT */ { FIXED, "TSK", 06045 }, /* SKIP IF TELETYPE INTERRUPT */ { FIXED, "TLS", 06046 }, /* LOAD TELPRINTER & CLEAR FLAG */ /* High Speed Paper Tape Reader */ { FIXED, "RSF", 06011 }, /* SKIP ON READER FLAG */ { FIXED, "RRB", 06012 }, /* READ READER BUFFER AND CLEAR FLAG */ { FIXED, "RFC", 06014 }, /* READER FETCH CHARACTER */ /* PC8-E High Speed Paper Tape Reader & Punch */ { FIXED, "RPE", 06010 }, /* Set interrupt enable for reader/punch */ { FIXED, "PCE", 06020 }, /* Clear interrupt enable for rdr/punch */ { FIXED, "RCC", 06016 }, /* Read reader buffer, clear flags & buf, */ /* and fetch character. */ /* High Speed Paper Tape Punch */ { FIXED, "PSF", 06021 }, /* SKIP ON PUNCH FLAG */ { FIXED, "PCF", 06022 }, /* CLEAR ON PUNCH FLAG */ { FIXED, "PPC", 06024 }, /* LOAD PUNCH BUFFER AND PUNCH CHARACTER* */ { FIXED, "PLS", 06026 }, /* LOAD PUNCH BUFFER AND CLEAR FLAG */ /* DECassette TU60 (RK 20071008) */ { FIXED, "KCLR", 06700 }, /* Clear all (clear A and B) */ { FIXED, "KSDR", 06701 }, /* Skip if data flag set */ { FIXED, "KSEN", 06702 }, /* Skip if EOT/BOT, not ready, or empty */ { FIXED, "KSBF", 06703 }, /* Skip if ready flag set */ { FIXED, "KLSA", 06704 }, /* AC4-11 -> A, clear A, -(AC4-11) -> A */ { FIXED, "KSAF", 06705 }, /* Skip on any flag or error */ { FIXED, "KGOA", 06706 }, /* Assert status A and transfer data to AC*/ { FIXED, "KRSB", 06707 }, /* Transfer B -> AC4-11 */ /* DECtape Transport Type TU55 and DECtape Control Type TC01 */ { FIXED, "DTRA", 06761 }, /* Contents of status register is ORed */ /* into AC bits 0-9 */ { FIXED, "DTCA", 06762 }, /* Clear status register A, all flags */ /* undisturbed */ { FIXED, "DTXA", 06764 }, /* Status register A loaded by exclusive */ /* OR from AC. If AC bit 10=0, clear */ /* error flags; if AC bit 11=0, DECtape */ /* control flag is cleared. */ { FIXED, "DTLA", 06766 }, /* Combination of DTCA and DTXA */ { FIXED, "DTSF", 06771 }, /* Skip if error flag is 1 or if DECtape */ /* control flag is 1 */ { FIXED, "DTRB", 06772 }, /* Contents of status register B is */ /* ORed into AC */ { FIXED, "DTLB", 06774 }, /* Memory field portion of status */ /* register B loaded from AC bits 6-8 */ /* Disk File and Control, Type DF32 */ { FIXED, "DCMA", 06601 }, /* CLEAR DISK MEMORY REQUEST AND */ /* INTERRUPT FLAGS */ { FIXED, "DMAR", 06603 }, /* LOAD DISK FROM AC, CLEAR AC READ */ /* INTO CORE, CLEAR INTERRUPT FLAG */ { FIXED, "DMAW", 06605 }, /* LOAD DISK FROM AC, WRITE ONTO DISK */ /* FROM CORE, CLEAR INTERRUPT FLAG */ { FIXED, "DCEA", 06611 }, /* CLEAR DISK EXTENDED ADDRESS AND */ { FIXED, "DSAC", 06612 }, /* SKIP IF ADDRESS CONFIRMED FLAG = 1 */ /* MEMORY ADDRESS EXTENSION REGISTER */ { FIXED, "DEAL", 06615 }, /* CLEAR DISK EXTENDED ADDRESS AND */ /* MEMORY ADDRESS EXTENSION REGISTER */ /* AND LOAD SAME FROM AC */ { FIXED, "DEAC", 06616 }, /* CLEAR AC, LOAD AC FROM DISK EXTENDED */ /* ADDRESS REGISTER, SKIP IF ADDRESS */ /* CONFIRMED FLAG = 1 */ { FIXED, "DFSE", 06621 }, /* SKIP IF PARITY ERROR, DATA REQUEST */ /* LATE, OR WRITE LOCK SWITCH FLAG = 0 */ /* (NO ERROR) */ { FIXED, "DFSC", 06622 }, /* SKIP IF COMPLETION FLAG = 1 (DATA */ /* TRANSFER COMPLETE) */ { FIXED, "DMAC", 06626 }, /* CLEAR AC, LOAD AC FROM DISK MEMORY */ /* ADDRESS REGISTER */ /* Disk File and Control, Type RF08 */ { FIXED, "DCIM", 06611 }, { FIXED, "DIML", 06615 }, { FIXED, "DIMA", 06616 }, { FIXED, "DISK", 06623 }, { FIXED, "DCXA", 06641 }, { FIXED, "DXAL", 06643 }, { FIXED, "DXAC", 06645 }, { FIXED, "DMMT", 06646 }, /* Memory Extension Control, Type 183 */ { FIXED, "CDF", 06201 }, /* CHANGE DATA FIELD */ { FIXED, "CIF", 06202 }, /* CHANGE INSTRUCTION FIELD */ { FIXED, "CDI", 06203 }, /* Change data & instrution field. */ { FIXED, "RDF", 06214 }, /* READ DATA FIELD */ { FIXED, "RIF", 06224 }, /* READ INSTRUCTION FIELD */ { FIXED, "RIB", 06234 }, /* READ INTERRUPT BUFFER */ { FIXED, "RMF", 06244 }, /* RESTORE MEMORY FIELD */ /* Memory Parity, Type MP8/I (MP8/L) */ { FIXED, "SMP", 06101 }, /* SKIP IF MEMORY PARITY FLAG = 0 */ { FIXED, "CMP", 06104 }, /* CLEAR MEMORY PAIRTY FLAG */ /* Memory Parity, Type MP8-E (PDP8/e) */ { FIXED, "DPI", 06100 }, /* Disable parity interrupt. */ { FIXED, "SNP", 06101 }, /* Skip if no parity error. */ { FIXED, "EPI", 06103 }, /* Enable parity interrupt. */ { FIXED, "CNP", 06104 }, /* Clear parity error flag. */ { FIXED, "CEP", 06106 }, /* Check for even parity. */ { FIXED, "SPO", 06107 }, /* Skip on parity option. */ /* Data Communications Systems, Type 680I */ { FIXED, "TTINCR", 06401 }, /* The content of the line select */ /* register is incremented by one. */ { FIXED, "TTI", 06402 }, /* The line status word is read and */ /* sampled. If the line is active for */ /* the fourth time, the line bit is */ /* shifted into the character assembly */ /* word. If the line bit is active for */ /* a number of times less than four, */ /* the count is incremented. If the */ /* line is not active, the active/inac- */ /* tive status of the line is recorded */ { FIXED, "TTO", 06404 }, /* The character in the AC is shifted */ /* right one position, zeros are shifted */ /* into vacated positions, and the orig- */ /* inal content of AC11 is transferred */ /* out of the computer on the TTY line. */ { FIXED, "TTCL", 06411 }, /* The line select register is cleared. */ { FIXED, "TTSL", 06412 }, /* The line select register is loaded by */ /* an OR transfer from the content of */ /* of AC5-11, the the AC is cleared. */ { FIXED, "TTRL", 06414 }, /* The content of the line select regis- */ /* ter is read into AC5-11 by an OR */ /* transfer. */ { FIXED, "TTSKP", 06421 }, /* Skip if clock flag is a 1. */ { FIXED, "TTXON", 06424 }, /* Clock 1 is enabled to request a prog- */ /* ram interrupt and clock 1 flag is */ /* cleared. */ { FIXED, "TTXOF", 06422 }, /* Clock 1 is disabled from causing a */ /* program interrupt and clock 1 flag */ /* is cleared. */ }; /* End-of-Symbols for Permanent Symbol Table */ /* Global variables */ SYM_T *symtab; /* Symbol Table */ int symbol_top; /* Number of entries in symbol table. */ SYM_T *fixed_symbols; /* Start of the fixed symbol table entries. */ int number_of_fixed_symbols; /*----------------------------------------------------------------------------*/ WORD16 *xreftab; /* Start of the concordance table. */ ERRSAVE_T error_list[20]; int save_error_count; #define GET_PAGE_INDEX(x) (((x) & 07600) >> 7) #define MAX_PAGES 32 LPOOL_T cp[MAX_PAGES]; /* Storage for page constants. */ int max_page_used[MAX_PAGES]; char s_detected[] = "detected"; char s_error[] = "error"; char s_errors[] = "errors"; char s_no[] = "No"; char s_page[] = "Page"; char s_symtable[] = "Symbol Table"; char s_xref[] = "Cross Reference"; char s_generated[] = "generated"; char s_link[] = "link"; char s_links[] = "links"; /* Assembler diagnostic messages. */ /* Some attempt has been made to keep continuity with the PAL-III and */ /* MACRO-8 diagnostic messages. If a diagnostic indicator, (e.g., IC) */ /* exists, then the indicator is put in the listing as the first two */ /* characters of the diagnostic message. The PAL-III indicators where used */ /* when there was a choice between using MACRO-8 and PAL-III indicators. */ /* The character pairs and their meanings are: */ /* DT Duplicate Tag (symbol) */ /* IC Illegal Character */ /* ID Illegal Redefinition of a symbol. An attempt was made to give */ /* a symbol a new value not via =. */ /* IE Illegal Equals An equal sign was used in the wrong context, */ /* (e.g., A+B=C, or TAD A+=B) */ /* II Illegal Indirect An off page reference was made, but a literal */ /* could not be generated because the indirect bit was already set. */ /* IR Illegal Reference (address is not on current page or page zero) */ /* ND No $ (the program terminator) at end of file. */ /* PE Current, Non-Zero Page Exceeded (literal table flowed into code) */ /* RD ReDefintion of a symbol */ /* ST Symbol Table full */ /* UA Undefined Address (undefined symbol) */ /* ZE Zero Page Exceeded (see above, or out of space) */ EMSG_T duplicate_label = { "DT duplicate", "duplicate label" }; EMSG_T illegal_blank = { "IC illegal blank", "illegal blank" }; EMSG_T illegal_character = { "IC illegal char", "illegal character" }; EMSG_T illegal_expression = { "IC in expression", "illegal expression" }; EMSG_T label_syntax = { "IC label syntax", "label syntax" }; EMSG_T not_a_number = { "IC numeric syntax", "numeric syntax of" }; EMSG_T number_not_radix = { "IC radix", "number not in current radix"}; EMSG_T symbol_syntax = { "IC symbol syntax", "symbol syntax" }; EMSG_T illegal_equals = { "IE illegal =", "illegal equals" }; EMSG_T illegal_indirect = { "II off page", "illegal indirect" }; EMSG_T illegal_reference = { "IR off page", "illegal reference" }; EMSG_T undefined_symbol = { "UD undefined", "undefined symbol" }; EMSG_T redefined_symbol = { "RD redefined", "redefined symbol" }; EMSG_T illegal_redefine = { "ID redefined", "Illegal redefine of symbol" }; EMSG_T literal_overflow = { "PE page exceeded", "current page literal capacity exceeded" }; EMSG_T pz_literal_overflow = { "ZE page exceeded", "page zero capacity exceeded" }; EMSG_T dubl_overflow = { "dubl overflow", "DUBL value overflow" }; EMSG_T fltg_overflow = { "fltg overflow", "FLTG value overflow" }; EMSG_T zblock_too_small = { "expr too small", "ZBLOCK value too small" }; EMSG_T zblock_too_large = { "expr too large", "ZBLOCK value too large" }; EMSG_T end_of_file = { "ND no $ at EOF", "No $ at End-of-File" }; EMSG_T no_pseudo_op = { "not implemented", "not implemented pseudo-op" }; EMSG_T illegal_field_value = { "expr out of range", "field value not in range of 0 through 7" }; EMSG_T literal_gen_off = { "literals off", "literal generation is off" }; EMSG_T no_literal_value = { "no value", "no literal value" }; EMSG_T text_string = { "no delimiter", "text string delimiters not matched" }; EMSG_T in_rim_mode = { "not OK in rim mode" "FIELD pseudo-op not valid in RIM mode" }; EMSG_T lt_expected = { "'<' expected", "'<' expected" }; EMSG_T symbol_table_full = { "ST Symbol Tbl Full", "Symbol Table Full" }; /*----------------------------------------------------------------------------*/ FILE *errorfile; FILE *infile; FILE *listfile; FILE *listsave; FILE *objectfile; FILE *objectsave; char errorpathname[NAMELEN]; char filename[NAMELEN]; char listpathname[NAMELEN]; char objectpathname[NAMELEN]; char *pathname; char permpathname[NAMELEN]; int tabstops; /* number of characters to expand a tab to */ int list_lineno; int list_pageno; char list_title[LINELEN]; BOOL list_title_set; /* Set if TITLE pseudo-op used. */ char line[LINELEN]; /* Input line. */ int lineno; /* Current line number. */ int page_lineno; /* print line number on current page. */ BOOL listed; /* Listed flag. */ BOOL listedsave; int cc; /* Column Counter (char position in line). */ WORD16 checksum; /* Generated checksum */ BOOL binary_data_output; /* Set true when data has been output. */ WORD16 clc; /* Location counter */ WORD16 cplc; /* Current page literal counter. */ char delimiter; /* Character immediately after eval'd term. */ int errors; /* Number of errors found so far. */ int links; /* Number of links generated so far. */ BOOL error_in_line; /* TRUE if error on current line. */ int errors_pass_1; /* Number of errors on pass 1. */ WORD16 field; /* Current field */ WORD16 fieldlc; /* location counter without field portion. */ BOOL fltg_input; /* TRUE when doing floating point input. */ BOOL indirect_generated; /* TRUE if an off page address generated. */ int last_xref_lexstart; /* Column where last xref symbol was located. */ int last_xref_lineno; /* Line where last xref symbol was located. */ int lexstartprev; /* Where previous lexeme started. */ int lextermprev; /* Where previous lexeme ended. */ int lexstart; /* Index of current lexeme on line. */ int lexterm; /* Index of character after current lexeme. */ BOOL literals_ok; /* Generate literals, ignore ID redefine err */ BOOL perm_redef_error; /* Make redefining perm sym with labels error */ int maxcc; /* Current line length. */ BOOL overflow; /* Overflow flag for math routines. */ int pass; /* Number of current pass. */ BOOL print_permanent_symbols; WORD16 pzlc; /* Page Zero literal counter. */ WORD16 radix; /* Default number radix. */ WORD16 reloc; /* The relocation distance. */ BOOL rim_mode; /* Generate rim format, defaults to bin */ BOOL dollar_not_required; /* $ not required at end of file */ BOOL additional_enabled; /* True if extended functions over PAL8 */ /* enabled */ BOOL symtab_print; /* Print symbol table flag */ BOOL xref; FLTG_T fltg_ac; /* Value holder for evalFltg() */ SYM_T sym_eval = { DEFINED, "", 0 }; /* Value holder for eval() */ SYM_T sym_getexpr = { DEFINED, "", 0 }; /* Value holder for getexpr() */ SYM_T sym_undefined = { UNDEFINED, "", 0 };/* Symbol Table Terminator */ /******************************************************************************/ /* */ /* Function: main */ /* */ /* Synopsis: Starting point. Controls order of assembly. */ /* */ /******************************************************************************/ int main( int argc, char *argv[] ) { int ix; int space; /* Set the default values for global symbols. */ binary_data_output = FALSE; fltg_input = FALSE; literals_ok = TRUE; perm_redef_error = FALSE; print_permanent_symbols = FALSE; rim_mode = FALSE; dollar_not_required = FALSE; additional_enabled = FALSE; symtab_print = FALSE; xref = FALSE; pathname = NULL; /* Get the options and pathnames */ getArgs( argc, argv ); /* Setup the error file in case symbol table overflows while installing the */ /* permanent symbols. */ errorfile = fopen( errorpathname, "w" ); if (errorfile == NULL) { fprintf( stderr, "Could not open error file %s: %s\n", errorpathname, strerror(errno)); exit( -1 ); } errors = 0; save_error_count = 0; pass = 0; /* This is required for symbol table initialization. */ symtab = (SYM_T *) malloc( sizeof( SYM_T ) * SYMBOL_TABLE_SIZE ); if( symtab == NULL ) { fprintf( stderr, "Could not allocate memory for symbol table.\n"); exit( -1 ); } /* Place end marker in symbol table. */ symtab[0] = sym_undefined; symbol_top = 0; number_of_fixed_symbols = symbol_top; fixed_symbols = &symtab[symbol_top - 1]; /* Enter the pseudo-ops into the symbol table */ for( ix = 0; ix < DIM( pseudo ) - (additional_enabled ? 0 : NUMBER_ADDITIONAL_PSEUDO) ; ix++ ) { defineSymbol( pseudo[ix].name, pseudo[ix].val, pseudo[ix].type, 0 ); } /* Enter the predefined symbols into the table. */ /* Also make them part of the permanent symbol table. */ for( ix = 0; ix < DIM( really_permanent_symbols ); ix++ ) { defineSymbol( really_permanent_symbols[ix].name, really_permanent_symbols[ix].val, really_permanent_symbols[ix].type | DEFFIX , 0 ); } /* Enter the predefined symbols into the table. */ /* Also make them part of the permanent symbol table. */ for( ix = 0; ix < DIM( permanent_symbols ); ix++ ) { defineSymbol( permanent_symbols[ix].name, permanent_symbols[ix].val, permanent_symbols[ix].type | DEFFIX , 0 ); } number_of_fixed_symbols = symbol_top; fixed_symbols = &symtab[symbol_top - 1]; /* Do pass one of the assembly */ checksum = 0; pass = 1; page_lineno = LIST_LINES_PER_PAGE; onePass(); errors_pass_1 = errors; /* Set up for pass two */ rewind( infile ); /*Opened in main errorfile = fopen( errorpathname, "w" );*/ objectfile = fopen( objectpathname, "wb" ); if (objectfile == NULL) { fprintf( stderr, "Could not open object file %s: %s\n", objectpathname, strerror(errno)); exit( -1 ); } objectsave = objectfile; listfile = fopen( listpathname, "w" ); if (listfile == NULL) { fprintf( stderr, "Could not open list file %s: %s\n", listpathname, strerror(errno)); exit( -1 ); } listsave = NULL; punchLeader( 0 ); checksum = 0; /* Do pass two of the assembly */ errors = 0; save_error_count = 0; page_lineno = LIST_LINES_PER_PAGE; if( xref ) { /* Get the amount of space that will be required for the concordance. */ for( space = 0, ix = 0; ix < symbol_top; ix++ ) { symtab[ix].xref_index = space; /* Index into concordance table. */ space += symtab[ix].xref_count + 1; symtab[ix].xref_count = 0; /* Clear the count for pass 2. */ } /* Allocate the necessary space. */ xreftab = (WORD16 *) malloc( sizeof( WORD16 ) * space ); /* Clear the cross reference space. */ for( ix = 0; ix < space; ix++ ) { xreftab[ix] = 0; } } pass = 2; onePass(); /* Undo effects of NOPUNCH for any following checksum */ objectfile = objectsave; punchChecksum(); /* Works great for trailer. */ punchLeader( 8 ); /* undo effects of XLIST for any following output to listing file. */ if( listfile == NULL ) { listfile = listsave; } /* Display value of error counter. */ if( errors == 0 ) { fprintf( listfile, "\n %s %s %s\n", s_no, s_detected, s_errors ); } else { fprintf( errorfile, "\n %d %s %s\n", errors, s_detected, ( errors == 1 ? s_error : s_errors )); fprintf( listfile, "\n %d %s %s\n", errors, s_detected, ( errors == 1 ? s_error : s_errors )); fprintf( stderr, " %d %s %s\n", errors, s_detected, ( errors == 1 ? s_error : s_errors )); } /* Display value of link counter. */ if( links == 0 ) { fprintf( listfile, " %s %s %s\n", s_no, s_links, s_generated ); } else { fprintf( errorfile, " %d %s %s\n", links, ( links == 1 ? s_link : s_links ), s_generated); fprintf( listfile, " %d %s %s\n", links, ( links == 1 ? s_link : s_links ), s_generated); fprintf( stderr, " %d %s %s\n", links, ( links == 1 ? s_link : s_links ), s_generated); } if( symtab_print ) { printSymbolTable(); } if( print_permanent_symbols ) { printPermanentSymbolTable(); } if( xref ) { printCrossReference(); } fclose( objectfile ); fclose( listfile ); fclose( errorfile ); if( errors == 0 && errors_pass_1 == 0 ) { remove( errorpathname ); } return( errors != 0 ); } /* main() */ /******************************************************************************/ /* */ /* Function: getArgs */ /* */ /* Synopsis: Parse command line, set flags accordingly and setup input and */ /* output files. */ /* */ /******************************************************************************/ void getArgs( int argc, char *argv[] ) { int len; int ix, jx; /* Set the defaults */ errorfile = NULL; infile = NULL; listfile = NULL; listsave = NULL; objectfile = NULL; objectsave = NULL; tabstops = 8; for( ix = 1; ix < argc; ix++ ) { if( argv[ix][0] == '-' ) { for( jx = 1; argv[ix][jx] != 0; jx++ ) { switch( argv[ix][jx] ) { case '$': dollar_not_required = TRUE; break; case 'd': symtab_print = TRUE; break; case 'a': additional_enabled = TRUE; break; case 'r': rim_mode = TRUE; break; case 'e': literals_ok = FALSE; break; case 'l': literals_ok = TRUE; break; case 'n': perm_redef_error = TRUE; break; case 'p': print_permanent_symbols = TRUE; break; /* Added -tN; RK 20071029 */ /* Damn, this is ugly, we should use getopt() */ case 't': if (argv [ix][jx + 1]) { tabstops = atoi (argv [ix] + (jx + 1)); /* advance past numbers */ for (jx++; argv [ix][jx]; jx++) ; jx--; } else { ix++; if (ix >= argc) { fprintf( stderr, "%s: missing argument for -t, expected number of tabsopts\n", argv[0] ); exit( -1 ); } for (jx = 0; argv [ix][jx]; jx++) ; jx--; tabstops = atoi (argv [ix]); } break; case 'x': xref = TRUE; break; case 'v': fprintf( stderr, "%s\n", release ); fflush( stderr ); exit( -1 ); break; default: fprintf( stderr, "%s: unknown flag: %s\n", argv[0], argv[ix] ); case 'h': fprintf( stderr, " -$ -- allow file to not end with $\n" ); fprintf( stderr, " -a -- enable additional function not in PAL8\n" ); fprintf( stderr, " -d -- dump symbol table\n" ); fprintf( stderr, " -e -- error if link generated\n" ); fprintf( stderr, " -h -- show this help\n" ); fprintf( stderr, " -l -- generate literal/link (default)\n" ); fprintf( stderr, " -n -- no redefining with label permanent symbols\n" ); fprintf( stderr, " -p -- output permanent symbols to file\n" ); fprintf( stderr, " -r -- output rim format file\n" ); fprintf( stderr, " -t N -- set tab stops to N\n" ); fprintf( stderr, " -v -- display version\n" ); fprintf( stderr, " -x -- output cross reference to file\n" ); fflush( stderr ); exit( -1 ); } /* end switch */ } /* end for */ } else { if( pathname != NULL ) { fprintf( stderr, "%s: too many input files\n", argv[0] ); exit( -1 ); } pathname = &argv[ix][0]; } } /* end for */ if( pathname == NULL ) { fprintf( stderr, "%s: no input file specified\n", argv[0] ); exit( -1 ); } len = strlen( pathname ); if( len > NAMELEN - 5 ) { fprintf( stderr, "%s: pathname \"%s\" too long\n", argv[0], pathname ); exit( -1 ); } /* Now open the input file. */ if(( infile = fopen( pathname, "r" )) == NULL ) { fprintf( stderr, "%s: cannot open \"%s\": %s\n", argv[0], pathname, strerror(errno) ); exit( -1 ); } /* Now make the pathnames */ /* Find last '.', if it exists. */ jx = len - 1; while( pathname[jx] != '.' && pathname[jx] != '/' && pathname[jx] != '\\' && jx >= 0 ) { jx--; } switch( pathname[jx] ) { case '.': break; case '/': case '\\': jx = len; break; default: break; } /* Add the pathname extensions. */ strncpy( objectpathname, pathname, jx ); objectpathname[jx] = '\0'; strcat( objectpathname, rim_mode ? ".rim" : ".bin" ); strncpy( listpathname, pathname, jx ); listpathname[jx] = '\0'; strcat( listpathname, ".lst" ); strncpy( errorpathname, pathname, jx ); errorpathname[jx] = '\0'; strcat( errorpathname, ".err" ); strncpy( permpathname, pathname, jx ); permpathname[jx] = '\0'; strcat( permpathname, ".prm" ); /* Extract the filename from the path. */ if( isalpha( pathname[0] ) && pathname[1] == ':' && pathname[2] != '\\' ) { pathname[1] = '\\'; /* MS-DOS style pathname */ } jx = len - 1; while( pathname[jx] != '/' && pathname[jx] != '\\' && jx >= 0 ) { jx--; } strcpy( filename, &pathname[jx + 1] ); } /* getArgs() */ /******************************************************************************/ /* */ /* Function: clearLiteralTable */ /* */ /* Synopsis: Clear the cp and max_page_used data storing literal */ /* information. */ /* */ /******************************************************************************/ void clearLiteralTable() { int i; for (i = 0; i < DIM(cp); i++) { cp[i].loc = 0200; /* Points to end of page for [] operands. */ cp[i].last_punched = 0200; /* Points to end of page for [] operands. */ } memset(max_page_used, 0, sizeof(max_page_used)); } /******************************************************************************/ /* */ /* Function: onePass */ /* */ /* Synopsis: Do one assembly pass. */ /* */ /******************************************************************************/ void onePass() { char name[SYMLEN]; WORD16 newclc; BOOL scanning_line; int start; SYM_T *sym; int term; WORD16 val; clc = 0200; /* Default starting address is 200 octal. */ field = 0; fieldlc = clc & 07777; reloc = 0; clearLiteralTable(); listed = TRUE; lineno = 0; list_pageno = 0; list_lineno = 0; last_xref_lexstart = 0; last_xref_lineno = 0; list_title_set = FALSE; radix = 8; /* Initial radix is octal (base 8). */ if( !rim_mode ) { /* Put out initial origin if not in rim mode. */ punchOrigin( clc ); } while( TRUE ) { readLine(); nextLexeme(); scanning_line = TRUE; while( scanning_line ) { if( isend( line[lexstart] )) { scanning_line = FALSE; } else { switch( line[lexstart] ) { case '/': scanning_line = FALSE; break; case ';': nextLexeme(); break; case '$': endOfBinary(); return; case '*': nextLexeme(); /* Skip '*', (set origin symbol) */ newclc = ((getExpr())->val & 07777 ) | field; /* Do not change Current Location Counter if an error occurred. */ if( !error_in_line ) { if(( newclc & 07600 ) != ( clc & 07600 ) ) { /* Current page has changed. */ punchLiteralPool( cp, 0 ); } clc = newclc - reloc; fieldlc = clc & 07777; if( !rim_mode ) { /* Not rim mode, put out origin. */ punchOrigin( clc ); } printLine( line, 0, fieldlc, LINE_VAL ); } break; default: switch( line[lexterm] ) { case ',': if( isalpha( line[lexstart] )) { /* Use lookup so symbol will not be counted as reference. */ sym = lookup( lexemeToName( name, lexstart, lexterm )); if( M_DEFINED( sym->type )) { if( (sym->val & 07777) != ( ( clc+reloc ) & 07777) && pass == 2 ) { errorSymbol( &duplicate_label, sym->name, lexstart ); } sym->type = sym->type | DUPLICATE; } /* Must call define on pass 2 to generate concordance. */ defineLexeme( lexstart, lexterm, ( clc + reloc ), LABEL ); } else { errorLexeme( &label_syntax, lexstart ); } nextLexeme(); /* skip label */ nextLexeme(); /* skip comma */ break; case '=': if( isalpha( line[lexstart] )) { start = lexstart; term = lexterm; delimiter = line[lexterm]; nextLexBlank(); /* skip symbol */ nextLexeme(); /* skip trailing =, allow blank */ delimiter = line[lexterm]; val = getExprs(); defineLexeme( start, term, val, DEFINED ); printLine( line, 0, val, LINE_VAL ); } else { errorLexeme( &symbol_syntax, lexstartprev ); nextLexeme(); /* skip symbol */ nextLexeme(); /* skip trailing = */ getExprs(); /* skip expression */ } break; default: if( isalpha( line[lexstart] )) { sym = evalSymbol(); val = sym->val; if( M_PSEUDO( sym->type )) { nextLexeme(); /* Skip symbol */ scanning_line = pseudoOperators( (PSEUDO_T)val & 07777 ); } else { /* Identifier is not a pseudo-op, interpret as load value */ punchOutObject( clc, getExprs() & 07777 ); incrementClc(); } } else { /* Identifier is a value, interpret as load value */ punchOutObject( clc, getExprs() & 07777 ); incrementClc(); } break; } /* end switch */ break; } /* end switch */ } /* end if */ } /* end while( scanning_line ) */ } /* end while( TRUE ) */ } /* onePass() */ /******************************************************************************/ /* */ /* Function: fixMRIInstruction */ /* */ /* Synopsis: Now that we have the final value figure out if page 0, current */ /* page, or indirect needed and max final instruction */ /* */ /******************************************************************************/ WORD16 fixMRIInstruction(WORD16 instruction, WORD16 value) { /* Now have the address part of the MRI instruction. */ if( value < 00200 ) { instruction |= value; /* Page zero MRI. */ } else if( (( fieldlc + reloc ) & 07600 ) <= value && value <= ((( fieldlc + reloc ) & 07600) | 0177 )) { instruction |= ( PAGE_BIT | (value & ADDRESS_FIELD )); /* Current page MRI */ } else { if(( instruction & INDIRECT_BIT ) == INDIRECT_BIT ) { /* Already indirect, can't generate */ errorSymbol( &illegal_indirect, NULL, lexstartprev ); } else { if( literals_ok ) { /* Now fix off page reference. */ /* Search current page literal pool for needed instruction. */ /* Set Indirect Current Page */ instruction |= ( 00600 | insertLiteral( cp, value, GET_PAGE_INDEX(clc) )); indirect_generated = TRUE; if (pass == 2) { links++; } } else { errorSymbol( &illegal_reference, NULL, lexstartprev ); instruction |= ( value & 0177 ); } } } return instruction; } /******************************************************************************/ /* */ /* Function: getExprs */ /* */ /* Synopsis: Or together a list of blank separated expressions, from the */ /* current lexeme onward. Leave the current lexeme as */ /* the last one in the list. */ /* */ /******************************************************************************/ WORD16 getExprs() { SYM_T *symv; SYM_T *symt; WORD16 temp; SYMTYP temp_type; WORD16 value; SYMTYP value_type; BOOL MRI_held = FALSE; WORD16 held_value = 0; symv = getExpr(); value = symv->val; value_type = symv->type; while( TRUE ) { if( isdone( line[lexstart] )) { if (MRI_held) { value = fixMRIInstruction(value, held_value); } return( value ); } switch( line[lexstart] ) { case ')': case ']': case '<': if (MRI_held) { value = fixMRIInstruction(value, held_value); } return( value ); default: break; } /* Interpret space as logical or */ symt = getExpr(); temp = symt->val & 07777; temp_type = symt->type; switch( value_type & (MRI | MRIFIX)) { case MRI: case MRIFIX: /* Previous symbol was a Memory Reference Instruction. */ switch( temp_type & (MRI | MRIFIX) ) { case MRI: case MRIFIX: /* If we have held value don't or in more MRI's to instuction, they */ /* are now instuction value */ if (MRI_held) { held_value |= temp; } else { /* Current symbol is also a Memory Reference Instruction. */ value |= temp; /* Just OR the MRI instructions. */ } break; default: held_value |= temp; MRI_held = TRUE; break; } break; default: if (value_type == UNDEFINED || temp_type == UNDEFINED) { value = 0; } else { value |= temp; /* Normal 12 bit value. */ } break; } } /* end while */ } /* getExprs() */ /******************************************************************************/ /* */ /* Function: getExpr */ /* */ /* Synopsis: Get an expression, from the current lexeme onward, leave the */ /* current lexeme as the one after the expression. Expressions */ /* contain terminal symbols (identifiers) separated by operators. */ /* */ /******************************************************************************/ SYM_T *getExpr() { SYM_T *sym; delimiter = line[lexterm]; if( line[lexstart] == '-' ) { nextLexBlank(); sym_getexpr = *(eval()); sym_getexpr.val = ( - sym_getexpr.val ) & 07777; } else { if( line[lexstart] == '+' ) { nextLexBlank(); } sym_getexpr = *(eval()); sym_getexpr.val = sym_getexpr.val & 07777; } if( is_blank( delimiter )) { return( &sym_getexpr ); } /* Here we assume the current lexeme is the operator separating the */ /* previous operator from the next, if any. */ while( TRUE ) { /* assert line[lexstart] == delimiter */ if( is_blank( delimiter )) { return( &sym_getexpr ); } switch( line[lexstart] ) { case '+': /* add */ nextLexBlank(); /* skip over the operator */ sym = eval(); sym_getexpr.val += sym->val; if (sym_getexpr.type == UNDEFINED || sym->type == UNDEFINED) { sym_getexpr.val = 0; sym_getexpr.type = UNDEFINED; } break; case '-': /* subtract */ nextLexBlank(); /* skip over the operator */ sym = eval(); sym_getexpr.val -= sym->val; if (sym_getexpr.type == UNDEFINED || sym->type == UNDEFINED) { sym_getexpr.val = 0; sym_getexpr.type = UNDEFINED; } break; case '^': /* multiply */ nextLexBlank(); /* skip over the operator */ sym = eval(); sym_getexpr.val *= sym->val; if (sym_getexpr.type == UNDEFINED || sym->type == UNDEFINED) { sym_getexpr.val = 0; sym_getexpr.type = UNDEFINED; } break; case '%': /* divide */ nextLexBlank(); /* skip over the operator */ sym = eval(); sym_getexpr.val /= sym->val; if (sym_getexpr.type == UNDEFINED || sym->type == UNDEFINED) { sym_getexpr.val = 0; sym_getexpr.type = UNDEFINED; } break; case '&': /* and */ nextLexBlank(); /* skip over the operator */ sym = eval(); sym_getexpr.val &= sym->val; if (sym_getexpr.type == UNDEFINED || sym->type == UNDEFINED) { sym_getexpr.val = 0; sym_getexpr.type = UNDEFINED; } break; case '!': /* or */ nextLexBlank(); /* skip over the operator */ sym = eval(); sym_getexpr.val |= sym->val; if (sym_getexpr.type == UNDEFINED || sym->type == UNDEFINED) { sym_getexpr.val = 0; sym_getexpr.type = UNDEFINED; } break; default: if( isend( line[lexstart] )) { return( &sym_getexpr ); } switch( line[lexstart] ) { case '/': case ';': case ')': case ']': case '<': break; case '=': errorMessage( &illegal_equals, lexstart ); moveToEndOfLine(); sym_getexpr.val = 0; break; default: errorMessage( &illegal_expression, lexstart ); moveToEndOfLine(); sym_getexpr.val = 0; break; } return( &sym_getexpr ); } } /* end while */ } /* getExpr() */ /******************************************************************************/ /* */ /* Function: eval */ /* */ /* Synopsis: Get the value of the current lexeme, set delimiter and advance.*/ /* */ /******************************************************************************/ SYM_T *eval() { WORD16 digit; int from; WORD16 loc; SYM_T *sym; WORD16 val; val = 0; delimiter = line[lexterm]; if( isalpha( line[lexstart] )) { sym = evalSymbol(); if( M_UNDEFINED( sym->type ) && pass == 2 ) { errorSymbol( &undefined_symbol, sym->name, lexstart ); nextLexeme(); return( sym ); } else { nextLexeme(); return( sym ); } } else if( isdigit( line[lexstart] )) { from = lexstart; val = 0; while( from < lexterm ) { if( isdigit( line[from] )) { digit = (WORD16) line[from++] - (WORD16) '0'; if( digit < radix ) { val = val * radix + digit; } else { errorLexeme( &number_not_radix, from - 1 ); val = 0; from = lexterm; } } else { errorLexeme( ¬_a_number, lexstart ); val = 0; from = lexterm; } } nextLexeme(); sym_eval.val = val; return( &sym_eval ); } else { switch( line[lexstart] ) { case '"': /* Character literal */ if( cc + 1 <= maxcc ) { val = line[lexstart + 1] | 0200; delimiter = line[lexstart + 2]; cc = lexstart + 2; } else { errorMessage( &no_literal_value, lexstart ); } nextLexeme(); break; case '.': /* Value of Current Location Counter */ val = (clc & 07777) + reloc; nextLexeme(); break; case '[': /* Generate literal on page zero. */ if( !literals_ok && LITERAL_ERROR) { errorMessage( &literal_gen_off, lexstart ); } nextLexBlank(); /* Skip bracket */ val = getExprs() & 07777; if( line[lexstart] == ']' ) { nextLexBlank(); /* Skip end bracket */ } sym_eval.val = (literals_ok || !LITERAL_ERROR) ? insertLiteral( cp , val, GET_PAGE_INDEX(field)) : 0; return( &sym_eval ); case '(': /* Generate literal on current page. */ if( !literals_ok && LITERAL_ERROR) { errorMessage( &literal_gen_off, lexstart ); } nextLexBlank(); /* Skip paren */ val = getExprs() & 07777; if( line[lexstart] == ')' ) { nextLexBlank(); /* Skip end paren */ } loc = (literals_ok || !LITERAL_ERROR) ? insertLiteral( cp, val, GET_PAGE_INDEX(clc) ) : 0; sym_eval.val = loc + (( clc + reloc ) & 077600 ); return( &sym_eval ); default: switch( line[lexstart] ) { case '=': errorMessage( &illegal_equals, lexstart ); moveToEndOfLine(); break; default: errorMessage( &illegal_character, lexstart ); break; } val = 0; /* On error, set value to zero. */ nextLexBlank(); /* Go past illegal character. */ } } sym_eval.val = val; return( &sym_eval ); } /* eval() */ /******************************************************************************/ /* */ /* Function: inputDubl */ /* */ /* Synopsis: Get the value of the current lexeme as a double word. */ /* */ /******************************************************************************/ void inputDubl() { WORD32 dublvalue; BOOL scanning_line; scanning_line = TRUE; do { while( scanning_line ) { if( isend( line[lexstart] )) { scanning_line = FALSE; } else { switch( line[lexstart] ) { case '/': scanning_line = FALSE; break; case ';': nextLexeme(); break; case '+': delimiter = line[lexterm]; nextLexBlank(); case '-': default: if( isdigit( line[lexstart] ) || line[lexstart] == '-' ) { dublvalue = getDublExprs(); punchOutObject( clc, (WORD16)(( dublvalue >> 12 ) & 07777 )); incrementClc(); punchOutObject( clc, (WORD16)( dublvalue & 07777 )); incrementClc(); } else { return; /* Non-numeric input, back to assembly. */ } break; } /* end switch */ } /* end if */ if( error_in_line ) { return; /* Error occurred, exit DUBL input mode. */ } } /* end while( scanning_line ) */ readLine(); nextLexeme(); scanning_line = TRUE; } while( TRUE ); } /* inputDubl() */ /******************************************************************************/ /* */ /* Function: getDublExprs */ /* */ /* Synopsis: Get a DUBL expression. */ /* */ /******************************************************************************/ WORD32 getDublExprs() { WORD32 dublvalue; dublvalue = getDublExpr(); while( TRUE ) { if( isdone( line[lexstart] )) { return( dublvalue ); } else { errorMessage( &illegal_expression, lexstart - 1 ); return( 0 ); } } /* end while */ } /* getDublExprs() */ /******************************************************************************/ /* */ /* Function: getDublExpr */ /* */ /* Synopsis: Get the value of the current lexeme as a double word. The */ /* number is always considered to have a decimal radix. */ /* */ /******************************************************************************/ WORD32 getDublExpr() { WORD32 dublvalue; delimiter = line[lexterm]; if( line[lexstart] == '-' ) { nextLexBlank(); dublvalue = evalDubl( 0 ); nextLexeme(); /* Test for any value greater than 23 bits in length. */ if( (unsigned long int)dublvalue > 040000000L ) { errorMessage( &dubl_overflow, lexstart ); dublvalue = 0; } dublvalue = -dublvalue; } else { dublvalue = evalDubl( 0 ); nextLexeme(); /* Test for any value greater than 23 bits in length. */ if( (unsigned long int)dublvalue > 037777777L ) { errorMessage( &dubl_overflow, lexstart ); dublvalue = 0; } } if( is_blank( delimiter )) { return( dublvalue ); } /* Here we assume the current lexeme is the operator separating the */ /* previous operator from the next, if any. */ while( TRUE ) { /* assert line[lexstart] == delimiter */ if( is_blank( delimiter )) { errorMessage( &illegal_expression, lexstart ); moveToEndOfLine(); dublvalue = 0; return( dublvalue ); } switch( line[lexstart] ) { case '+': /* add */ case '-': /* subtract */ case '^': /* multiply */ case '%': /* divide */ case '&': /* and */ case '!': /* or */ errorMessage( &illegal_expression, lexstart ); moveToEndOfLine(); dublvalue = 0; break; default: if( isend( line[lexstart] )) { return( dublvalue ); } switch( line[lexstart] ) { case '/': case ';': break; default: errorMessage( &illegal_expression, lexstart ); moveToEndOfLine(); dublvalue = 0; break; } return( dublvalue ); } } /* end while */ } /* getDublExpr() */ /******************************************************************************/ /* */ /* Function: evalDubl */ /* */ /* Synopsis: Get the value of the current lexeme as a double word. The */ /* number is always considered to have a decimal radix. */ /* */ /******************************************************************************/ WORD32 evalDubl( WORD32 initial_value ) { WORD32 digit; int from; WORD32 dublvalue; WORD32 olddublvalue; overflow = FALSE; delimiter = line[lexterm]; from = lexstart; dublvalue = initial_value; while( from < lexterm ) { if( isdigit( line[from] )) { olddublvalue = dublvalue; digit = (WORD32)( line[from++] - '0' ); dublvalue = dublvalue * 10 + digit; if( dublvalue < olddublvalue ) { overflow = TRUE; } } else { errorLexeme( ¬_a_number, from ); dublvalue = 0; from = lexterm; } } return( dublvalue ); } /* evalDubl() */ /******************************************************************************/ /* */ /* Function: inputFltg */ /* */ /* Synopsis: Get the value of the current lexeme as a Floating Point const. */ /* */ /******************************************************************************/ void inputFltg() { FLTG_T *fltg; BOOL scanning_line; fltg_input = TRUE; /* Set lexeme scanner for floating point. */ scanning_line = TRUE; while( TRUE ) { while( scanning_line ) { if( isend( line[lexstart] )) { scanning_line = FALSE; } else { switch( line[lexstart] ) { case '/': scanning_line = FALSE; break; case ';': nextLexeme(); break; case '+': delimiter = line[lexterm]; nextLexBlank(); case '-': default: if( isdigit( line[lexstart] ) || line[lexstart] == '-' ) { fltg = getFltgExprs(); punchOutObject( clc, ( fltg->exponent & 07777 )); incrementClc(); punchOutObject( clc, (WORD16)(( fltg->mantissa >> 12 ) & 07777 )); incrementClc(); punchOutObject( clc, (WORD16)( fltg->mantissa & 07777 )); incrementClc(); } else { fltg_input = FALSE; /* Reset lexeme scanner. */ return; /* Non-numeric input, back to assembly. */ } break; } /* end switch */ } /* end if */ if( error_in_line ) { fltg_input = FALSE; /* Reset lexeme scanner. */ return; /* Error occurred, exit FLTG input mode. */ } } /* end while( scanning_line ) */ readLine(); nextLexeme(); scanning_line = TRUE; } } /* inputFltg() */ /******************************************************************************/ /* */ /* Function: getFltgExprs */ /* */ /* Synopsis: Get a FLTG expression. */ /* */ /******************************************************************************/ FLTG_T *getFltgExprs() { FLTG_T *fltg; fltg = getFltgExpr(); while( TRUE ) { if( isdone( line[lexstart] )) { return( fltg ); } else { errorMessage( &illegal_expression, lexstart - 1 ); return( 0 ); } } /* end while */ } /* getFltgExprs() */ /******************************************************************************/ /* */ /* Function: getFltgExpr */ /* */ /* Synopsis: Get the value of the current lexeme as a double word. The */ /* number is always considered to have a decimal radix. */ /* */ /******************************************************************************/ FLTG_T *getFltgExpr() { FLTG_T *fltg; delimiter = line[lexterm]; fltg = evalFltg(); /* Test for any value greater than 23 bits in length. */ if( (unsigned long int)fltg->mantissa> 077777777L ) { errorMessage( &fltg_overflow, lexstart ); } if( is_blank( delimiter )) { return( fltg ); } /* Here we assume the current lexeme is the operator separating the */ /* previous operator from the next, if any. */ while( TRUE ) { /* assert line[lexstart] == delimiter */ if( is_blank( delimiter )) { errorMessage( &illegal_expression, lexstart ); moveToEndOfLine(); fltg = 0; return( fltg ); } switch( line[lexstart] ) { case '+': /* add */ case '-': /* subtract */ case '^': /* multiply */ case '%': /* divide */ case '&': /* and */ case '!': /* or */ errorMessage( &illegal_expression, lexstart ); moveToEndOfLine(); fltg = NULL; break; default: if( isend( line[lexstart] )) { return( fltg ); } switch( line[lexstart] ) { case '/': case ';': break; default: errorMessage( &illegal_expression, lexstart ); moveToEndOfLine(); fltg = NULL; break; } return( fltg ); } } /* end while */ } /* getFltgExpr() */ /******************************************************************************/ /* */ /* Function: evalFltg */ /* */ /* Synopsis: Get the value of the current lexeme as a floating point value. */ /* Floating point input is alwasy considered decimal. */ /* The general format of a floating point number is: */ /* +-ddd.dddE+-dd where each d is a decimal digit. */ /* */ /******************************************************************************/ FLTG_T *evalFltg() { int current_state; int current_col; WORD16 exponent; FLTG_T *fltg; WORD32 input_value; BOOL negate; BOOL negate_exponent; int next_state; int right_digits; /* This uses a lexical analyzer to parse the floating point format. */ static BYTE state_table[][10] = { /* 0 1 2 3 4 5 6 Oolumn index */ /* + - d . E sp p State Comment */ { 2, 1, 3, 4, 10, 10, 10 }, /* 0 Initial state. */ { 11, 11, 3, 4, 11, 11, 11 }, /* 1 - */ { 11, 11, 3, 4, 11, 11, 11 }, /* 2 + */ { 10, 10, 10, 4, 6, 10, 10 }, /* 3 # (+-ddd) */ { 11, 11, 5, 11, 11, 10, 10 }, /* 4 . (+-ddd.) */ { 11, 11, 11, 11, 6, 10, 11 }, /* 5 # (+-ddd.ddd) */ { 8, 7, 9, 11, 11, 11, 11 }, /* 6 E (+-ddd.dddE) */ { 11, 11, 9, 11, 11, 11, 11 }, /* 7 - (+-ddd.dddE- */ { 11, 11, 9, 11, 11, 11, 11 }, /* 8 + (+-ddd.dddE+ */ { 11, 11, 11, 11, 11, 10, 11 } /* 9 # (+-ddd.dddE+-dd */ /* 10 Completion state */ /* 11 Error state. */ }; delimiter = line[lexterm]; fltg = &fltg_ac; fltg->exponent = 0; fltg->mantissa = 0; input_value = 0; negate = FALSE; negate_exponent = FALSE; next_state = 0; exponent = 0; right_digits = 0; current_state = 0; while( TRUE ) { /* Classify character. This is the column index. */ switch( line[lexstart] ) { case '+': current_col = 0; break; case '-': current_col = 1; break; case '.': current_col = 3; break; case 'E': case 'e': current_col = 4; break; default: if( isdigit( line[lexstart] )) { current_col = 2; } else if( isdone( line[lexstart] )) { current_col = 5; } else { current_col = 6; } break; } next_state = state_table[current_state][current_col]; switch( next_state ) { case 1: /* - */ negate = TRUE; case 2: /* + */ delimiter = line[lexterm]; /* Move past the + or - character. */ nextLexBlank(); break; case 3: /* Number (+-ddd) */ input_value = evalDubl( 0 ); /* Integer part of the number. */ nextLexeme(); /* Move past previous lexeme. */ break; case 4: delimiter = line[lexterm]; nextLexBlank(); /* Move past the . character. */ break; case 5: /* . (+-ddd.ddd) */ /* Fractional part of the number. */ input_value = evalDubl( input_value ); right_digits = lexterm - lexstart;/* Digit count to right of decimal. */ nextLexeme(); /* Move past previous lexeme. */ break; case 6: /* E (+-ddd.dddE) */ delimiter = line[lexterm]; /* Move past the E. */ nextLexBlank(); break; case 7: /* - (+-ddd.dddE-) */ negate_exponent = TRUE; case 8: /* + (+-ddd.dddE+) */ delimiter = line[lexterm]; /* Move past the + or - character. */ nextLexBlank(); break; case 9: /* # (+-ddd.dddE+-dd) */ exponent = (int)evalDubl( 0 ); /* Exponent of floating point number. */ if( negate_exponent ) { exponent = - exponent; } nextLexeme(); /* Move past previous lexeme. */ break; case 10: /* Floating number parsed, convert */ /* the number. */ /* Get the exponent for the number as input. */ exponent -= right_digits; /* Remove trailing zeros and adjust the exponent accordingly. */ while(( input_value % 10 ) == 0 ) { input_value /= 10; exponent++; } /* Convert the number to floating point. The number is calculated with */ /* a 27 bit mantissa to improve precision. The extra 3 bits are */ /* discarded after the result has been calculated. */ fltg->exponent = 26; fltg->mantissa = input_value << 3; normalizeFltg( fltg ); while( exponent != 0 ) { if( exponent < 0 ) { /* Decimal point is to the left. */ fltg->mantissa /= 10; normalizeFltg( fltg ); exponent++; } else if( exponent > 0 ) { /* Decimal point is to the right. */ fltg->mantissa *= 10; normalizeFltg( fltg ); exponent--; } } /* Discard the extra precsion used for calculating the number. */ fltg->mantissa >>= 3; fltg->exponent -= 3; if( negate ) { fltg->mantissa = (- fltg->mantissa ) & 077777777L; } return( fltg ); case 11: /* Error in format. */ /* Not a properly constructued floating point number. */ return( fltg ); default: break; } /* Set state for next pass through the loop. */ current_state = next_state; } } /* evalFltg() */ /******************************************************************************/ /* */ /* Function: normalizeFltg */ /* */ /* Synopsis: Normalize a PDP-8 double precision floating point number. */ /* */ /******************************************************************************/ void normalizeFltg( FLTG_T *fltg ) { /* Normalize the floating point number. */ if( fltg->mantissa != 0 ) { if(( fltg->mantissa & ~0x3FFFFFFL ) == 0 ) { while(( fltg->mantissa & ~0x1FFFFFFL ) == 0 ) { fltg->mantissa <<= 1; fltg->exponent--; } } else { while(( fltg->mantissa & ~0x3FFFFFFL ) != 0 ) { fltg->mantissa >>= 1; fltg->exponent++; } } } else { fltg->exponent = 0; } return; } /******************************************************************************/ /* */ /* Function: incrementClc */ /* */ /* Synopsis: Set the next assembly location. Test for collision with */ /* the literal tables. */ /* */ /******************************************************************************/ WORD16 incrementClc() { testForLiteralCollision( clc ); /* Incrementing the location counter is not to change field setting. */ clc = ( clc & 070000 ) + (( clc + 1 ) & 07777 ); fieldlc = clc & 07777; return( clc ); } /* incrementClc() */ /******************************************************************************/ /* */ /* Function: testForLiteralCollision */ /* */ /* Synopsis: Test the given location for collision with the literal tables. */ /* */ /******************************************************************************/ BOOL testForLiteralCollision( WORD16 loc ) { WORD16 pagelc; BOOL result = FALSE; WORD16 tmppage; int tmpfield; tmpfield = GET_PAGE_INDEX(loc); tmppage = loc & 07600; pagelc = loc & 00177; if ( pagelc > max_page_used[tmpfield] ) { max_page_used[tmpfield] = pagelc; } if ( pagelc >= cp[tmpfield].loc ) { if ( tmppage == 0 ) { errorMessage( &pz_literal_overflow, -1 ); } else { errorMessage( &literal_overflow, -1 ); } result = TRUE; } return( result ); } /* testForLiteralCollision() */ /******************************************************************************/ /* */ /* Function: readLine */ /* */ /* Synopsis: Get next line of input. Print previous line if needed. */ /* */ /******************************************************************************/ void readLine() { WORD16 ix; WORD16 iy; char inpline[LINELEN]; listLine(); /* List previous line if needed. */ lineno++; /* Count lines read. */ indirect_generated = FALSE; /* Mark no indirect address generated. */ listed = FALSE; /* Mark as not listed. */ cc = 0; /* Initialize column counter. */ lexstartprev = 0; error_in_line = FALSE; if(( fgets( inpline, LINELEN - 1, infile )) == NULL ) { inpline[0] = '$'; inpline[1] = '\n'; inpline[2] = '\0'; if (!dollar_not_required) { error_in_line = TRUE; } } /* Remove any tabs from the input line by inserting the required number */ /* of spaces to simulate N character tab stops, where N defaults to 8 and */ /* is set by the command line option -t. (RK 20071029) */ /* Ignore \r if there is one. (DPI 20150501) */ for( ix = 0, iy = 0; inpline[ix] != '\0' && iy < (LINELEN - 2); ix++ ) { switch( inpline[ix] ) { case '\t': do { line[iy] = ' '; iy++; } while(( iy % tabstops ) != 0 && iy < (LINELEN - 2)); break; case '\r': /* dont copy the carriage return */ break; default: line[iy] = inpline[ix]; iy++; break; } } if (iy >= (LINELEN - 2)) { line [iy] = '\n'; iy++; } line[iy] = '\0'; maxcc = iy; /* Save the current line length. */ /* Save the first line for possible use as the listing title. */ if( lineno == 1 ) { strcpy( list_title, line ); } } /* readLine() */ /******************************************************************************/ /* */ /* Function: listLine */ /* */ /* Synopsis: Output a line to the listing file. */ /* */ /******************************************************************************/ void listLine() /* generate a line of listing if not already done! */ { if( listfile != NULL && listed == FALSE ) { printLine( line, 0, 0, LINE ); } } /* listLine() */ /******************************************************************************/ /* */ /* Function: printPageBreak */ /* */ /* Synopsis: Output a Top of Form and listing header if new page necessary. */ /* */ /******************************************************************************/ void printPageBreak() { if( page_lineno >= LIST_LINES_PER_PAGE ) /* ( list_lineno % LIST_LINES_PER_PAGE ) == 0 ) */ { if( !list_title_set ) { /* strcpy( list_title, line ); */ if( list_title[strlen(list_title) - 1] == '\n' ) { list_title[strlen(list_title) - 1] = '\0'; } if( strlen( list_title ) > TITLELEN ) { list_title[TITLELEN] = '\0'; } list_title_set = TRUE; } topOfForm( list_title, NULL ); } } /* printPageBreak() */ /******************************************************************************/ /* */ /* Function: printLine */ /* */ /* Synopsis: Output a line to the listing file with new page if necessary. */ /* */ /******************************************************************************/ void printLine( char *line, WORD16 loc, WORD16 val, LINESTYLE_T linestyle ) { char rlc; if( listfile == NULL ) { save_error_count = 0; return; } printPageBreak(); list_lineno++; page_lineno++; if (reloc == 0) { rlc = ' '; } else { rlc = '*'; } switch( linestyle ) { default: case LINE: fprintf(listfile, "%5d ", lineno ); fputs( line, listfile ); listed = TRUE; break; case LINE_VAL: fprintf(listfile, "%5d %4.4o ", lineno, val ); fputs( line, listfile ); listed = TRUE; break; case LINE_LOC_VAL: if( !listed ) { if( indirect_generated ) { fprintf( listfile, "%5d %5.5o%c %4.4o@ ", lineno, loc, rlc, val ); } else { fprintf( listfile, "%5d %5.5o%c %4.4o ", lineno, loc, rlc, val ); } fputs( line, listfile ); listed = TRUE; } else { fprintf( listfile, " %5.5o%c %4.4o\n", loc, rlc, val ); } break; case LOC_VAL: fprintf( listfile, " %5.5o%c %4.4o\n", loc, rlc, val ); break; } printErrorMessages(); } /* printLine() */ /******************************************************************************/ /* */ /* Function: printErrorMessages */ /* */ /* Synopsis: Output any error messages from the current list of errors. */ /* */ /******************************************************************************/ void printErrorMessages() { WORD16 ix; WORD16 iy; if( listfile != NULL ) { /* If any errors, display them now. */ for( iy = 0; iy < save_error_count; iy++ ) { printPageBreak(); fprintf( listfile, "%-18.18s", error_list[iy].mesg ); if( error_list[iy].col >= 0 ) { for( ix = 0; ix < error_list[iy].col; ix++ ) { if( line[ix] == '\t' ) { putc( '\t', listfile ); } else { putc( ' ', listfile ); } } fputs( "^", listfile ); list_lineno++; page_lineno++; } fputs( "\n", listfile ); } } save_error_count = 0; } /* printErrorMessages() */ /******************************************************************************/ /* */ /* Function: endOfBinary */ /* */ /* Synopsis: Outputs both literal tables at the end of a binary segment. */ /* */ /******************************************************************************/ void endOfBinary() { /* Punch page 0 also. */ punchLiteralPool( cp, 1 ); if( error_in_line ) { listed = TRUE; clc = ( clc & 070000 ) + (( clc - 1 ) & 07777 ); errorMessage( &end_of_file, -1 ); clc = ( clc & 070000 ) + (( clc + 1 ) & 07777 ); } else { listLine(); /* List line if not done yet. */ } return; } /* endOfBinary() */ /******************************************************************************/ /* */ /* Function: punchChecksum */ /* */ /* Synopsis: Output a checksum if the current mode requires it and an */ /* object file exists. */ /* */ /******************************************************************************/ void punchChecksum() { /* If the assembler has output any BIN data output the checksum. */ if( binary_data_output && !rim_mode ) { punchLocObject( 0, checksum ); } binary_data_output = FALSE; checksum = 0; } /* punchChecksum() */ /******************************************************************************/ /* */ /* Function: punchLeader */ /* */ /* Synopsis: Generate 2 feet of leader on object file, as per DEC */ /* documentation. Paper tape has 10 punches per inch. */ /* */ /******************************************************************************/ void punchLeader( int count ) { int ix; /* If value is zero, set to the default of 2 feet of leader. */ count = ( count == 0 ) ? 240 : count; if( objectfile != NULL ) { for( ix = 0; ix < count; ix++ ) { fputc( 0200, objectfile ); } } } /* punchLeader() */ /******************************************************************************/ /* */ /* Function: punchOrigin */ /* */ /* Synopsis: Output an origin to the object file. */ /* */ /******************************************************************************/ void punchOrigin( WORD16 loc ) { punchObject((( loc >> 6 ) & 0077 ) | 0100 ); punchObject( loc & 0077 ); } /* punchOrigin() */ /******************************************************************************/ /* */ /* Function: punchObject */ /* */ /* Synopsis: Put one character to object file and include it in checksum. */ /* */ /******************************************************************************/ void punchObject( WORD16 val ) { val &= 0377; if( objectfile != NULL ) { fputc( val, objectfile ); checksum += val; } binary_data_output = TRUE; } /* punchObject() */ /******************************************************************************/ /* */ /* Function: punchOutObject */ /* */ /* Synopsis: Output the current line and then then punch value to the */ /* object file. */ /* */ /******************************************************************************/ void punchOutObject( WORD16 loc, WORD16 val ) { /* Adding reloc makes printout agree with PAL8 where is prints the */ /* relocated address, not the address in the BIN file */ printLine( line,( ( field | loc ) + reloc ), val, LINE_LOC_VAL ); punchLocObject( loc, val ); } /* punchOutObject() */ /******************************************************************************/ /* */ /* Function: punchLocObject */ /* */ /* Synopsis: Output the word (with origin if rim format) to the object file.*/ /* */ /******************************************************************************/ void punchLocObject( WORD16 loc, WORD16 val ) { if( rim_mode ) { punchOrigin( loc ); } punchObject(( val >> 6 ) & 0077 ); punchObject( val & 0077 ); } /* punchLocObject() */ /******************************************************************************/ /* */ /* Function: punchLiteralPool */ /* */ /* Synopsis: Output the current page data. */ /* */ /******************************************************************************/ void punchLiteralPool( LPOOL_T *p, BOOL punch_page0 ) { WORD16 loc; WORD16 tmplc; int lpool_page = 0; /* Silence false uninitialized error from GCC */ int i; for (i = MAX_PAGES-1; i >= 0; i--) { lpool_page = (i << 7) & 07600; if ( p[i].loc != p[i].last_punched && (punch_page0 || lpool_page != 0) ) { if( !rim_mode ) { /* Put out origin if not in rim mode. */ punchOrigin( p[i].loc | lpool_page ); } /* Put the literals in the object file. */ for( loc = p[i].loc; loc < p[i].last_punched; loc++ ) { tmplc = loc + lpool_page; printLine( line, (field | tmplc), p[i].pool[loc], LOC_VAL ); punchLocObject( tmplc, p[i].pool[loc] ); } p[i].last_punched = p[i].loc; } } } /* punchLiteralPool() */ /******************************************************************************/ /* */ /* Function: insertLiteral */ /* */ /* Synopsis: Add a value to the given literal pool if not already in pool. */ /* Return the location of the value in the pool. */ /* */ /******************************************************************************/ WORD16 insertLiteral( LPOOL_T *pool, WORD16 value, int fieldpage_index ) { WORD16 ix; LPOOL_T *p; p = &pool[fieldpage_index]; /* Search the literal pool for any occurence of the needed value. */ ix = PAGE_SIZE - 1; while( ix >= p->loc && p->pool[ix] != value ) { ix--; } /* Check if value found in literal pool. If not, then insert value. */ if( ix < p->loc ) { (p->loc)--; p->pool[p->loc] = value; ix = p->loc; if( max_page_used[fieldpage_index] >= p->loc ) { if ( (fieldpage_index & 017) == 0 ) { errorMessage( &pz_literal_overflow, -1 ); } else { errorMessage( &literal_overflow, -1 ); } } } return( ix ); } /* insertLiteral() */ /******************************************************************************/ /* */ /* Function: printSymbolTable */ /* */ /* Synopsis: Output the symbol table. */ /* */ /******************************************************************************/ void printSymbolTable() { int col; int cx; char *fmt; int ix; char mark; int page; int row; int symbol_base; int symbol_lines; symbol_base = number_of_fixed_symbols; for( page=0, list_lineno=0, col=0, ix=symbol_base; ix < symbol_top; page++ ) { topOfForm( list_title, s_symtable ); symbol_lines = LIST_LINES_PER_PAGE - page_lineno; for( row = 0; page_lineno < LIST_LINES_PER_PAGE && ix < symbol_top; row++) { list_lineno++; page_lineno++; fprintf( listfile, "%5d", list_lineno ); for( col = 0; col < SYMBOL_COLUMNS && ix < symbol_top; col++ ) { /* Get index of symbol for the current line and column */ cx = symbol_lines * ( SYMBOL_COLUMNS * page + col ) + row; cx += symbol_base; /* Make sure that there is a symbol to be printed. */ if( number_of_fixed_symbols <= cx && cx < symbol_top ) { switch( symtab[cx].type & LABEL ) { case LABEL: fmt = " %c%-6.6s %5.5o "; break; default: fmt = " %c%-6.6s %4.4o "; break; } switch( symtab[cx].type & ( DEFINED | REDEFINED )) { case UNDEFINED: mark = '?'; break; case REDEFINED: mark = '#'; break; default: mark = ' '; break; } fprintf( listfile, fmt, mark, symtab[cx].name, symtab[cx].val ); ix++; } } fprintf( listfile, "\n" ); } } } /* printSymbolTable() */ /******************************************************************************/ /* */ /* Function: printPermanentSymbolTable */ /* */ /* Synopsis: Output the permanent symbol table to a file suitable for */ /* being input after the EXPUNGE pseudo-op. */ /* */ /******************************************************************************/ void printPermanentSymbolTable() { int ix; FILE *permfile; char *s_type; if(( permfile = fopen( permpathname, "w" )) == NULL ) { exit( 2 ); } fprintf( permfile, "/ PERMANENT SYMBOL TABLE\n/\n" ); fprintf( permfile, " EXPUNGE\n/\n" ); /* Print the memory reference instructions first. */ s_type = "FIXMRI"; for( ix = 0; ix < symbol_top; ix++ ) { if( M_MRI( symtab[ix].type )) { fprintf( permfile, "%-7s %s=%4.4o\n", s_type, symtab[ix].name, symtab[ix].val ); } } s_type = " "; for( ix = 0; ix < symbol_top; ix++ ) { if( M_FIXED( symtab[ix].type )) { if( !M_MRI( symtab[ix].type ) && !M_PSEUDO( symtab[ix].type )) { fprintf( permfile, "%-7s %s=%4.4o\n", s_type, symtab[ix].name, symtab[ix].val ); } } } fprintf( permfile, "/\n FIXTAB\n" ); fclose( permfile ); } /* printPermanentSymbolTable() */ /******************************************************************************/ /* */ /* Function: printCrossReference */ /* */ /* Synopsis: Output a cross reference (concordance) for the file being */ /* assembled. */ /* */ /******************************************************************************/ void printCrossReference() { int ix; int symbol_base; int xc; int xc_index; int xc_refcount; int xc_cols; /* Force top of form for first page. */ page_lineno = LIST_LINES_PER_PAGE; list_lineno = 0; symbol_base = number_of_fixed_symbols; for( ix = symbol_base; ix < symbol_top; ix++ ) { list_lineno++; page_lineno++; if( page_lineno >= LIST_LINES_PER_PAGE ) { topOfForm( list_title, s_xref ); } fprintf( listfile, "%5d", list_lineno ); /* Get reference count & index into concordance table for this symbol. */ xc_refcount = symtab[ix].xref_count; xc_index = symtab[ix].xref_index; /* Determine how to label symbol on concordance. */ switch( symtab[ix].type & ( DEFINED | REDEFINED )) { case UNDEFINED: fprintf( listfile, " U "); break; case REDEFINED: fprintf( listfile, " M %5d ", xreftab[xc_index] ); break; default: fprintf( listfile, " A %5d ", xreftab[xc_index] ); break; } fprintf( listfile, "%-6.6s ", symtab[ix].name ); /* Output the references, 8 numbers per line after symbol name. */ for( xc_cols = 0, xc = 1; xc < xc_refcount + 1; xc++, xc_cols++ ) { if( xc_cols >= XREF_COLUMNS ) { xc_cols = 0; page_lineno++; if( page_lineno >= LIST_LINES_PER_PAGE ) { topOfForm( list_title, s_xref); } list_lineno++; fprintf( listfile, "\n%5d%-19s", list_lineno, " " ); } fprintf( listfile, " %5d", xreftab[xc_index + xc] ); } fprintf( listfile, "\n" ); } } /* printCrossReference() */ /******************************************************************************/ /* */ /* Function: topOfForm */ /* */ /* Synopsis: Prints title and sub-title on top of next page of listing. */ /* */ /******************************************************************************/ void topOfForm( char *title, char *sub_title ) { char temp[10]; list_pageno++; strcpy( temp, s_page ); sprintf( temp, "%s %d", s_page, list_pageno ); /* Output a top of form if not the first page of the listing. */ if( list_pageno > 1 ) { fprintf( listfile, "\f" ); } fprintf( listfile, "\n\n\n %-63s %10s\n", title, temp ); /* Reset the current page line counter. */ page_lineno = 3; if( sub_title != NULL ) { fprintf( listfile, "%80s\n", sub_title ); page_lineno++; } else { fprintf( listfile, "\n" ); page_lineno++; } fprintf( listfile, "\n" ); page_lineno++; } /* topOfForm() */ /******************************************************************************/ /* */ /* Function: lexemeToName */ /* */ /* Synopsis: Convert the current lexeme into a string. */ /* */ /******************************************************************************/ char *lexemeToName( char *name, int from, int term ) { int to; to = 0; while( from < term && to < ( SYMLEN - 1 )) { name[to++] = toupper( line[from++] ); } while( to < SYMLEN ) { name[to++] = '\0'; } return( name ); } /* lexemeToName() */ /******************************************************************************/ /* */ /* Function: defineLexeme */ /* */ /* Synopsis: Put lexeme into symbol table with a value. */ /* */ /******************************************************************************/ SYM_T *defineLexeme( int start, /* start of lexeme being defined. */ int term, /* end+1 of lexeme being defined. */ WORD16 val, /* value of lexeme being defined. */ SYMTYP type ) /* how symbol is being defined. */ { char name[SYMLEN]; lexemeToName( name, start, term); return( defineSymbol( name, val, type, start )); } /* defineLexeme() */ /******************************************************************************/ /* */ /* Function: defineSymbol */ /* */ /* Synopsis: Define a symbol in the symbol table, enter symbol name if not */ /* not already in table. */ /* */ /******************************************************************************/ SYM_T *defineSymbol( char *name, WORD16 val, SYMTYP type, WORD16 start ) { SYM_T *sym; int xref_count; if( strlen( name ) < 1 ) { return( &sym_undefined ); /* Protect against non-existent names. */ } sym = lookup( name ); /* OS/8 PAL8 seems to allow permanent symbold to be redefined without error */ if( ( M_FIXED( sym->type ) && pass == 1 && perm_redef_error ) || (M_PERM_REDEFINED( sym->type ) && (sym->val != val)) ) { type |= PERM_REDEFINED; } xref_count = 0; /* Set concordance for normal defintion. */ if( M_DEFINED( sym->type )) { if( pass == 2 && ( (sym->val & 07777) != (val & 07777) || M_PERM_REDEFINED(sym->type)) ) { /* Generate diagnostic if redefining a symbol. */ if( M_PERM_REDEFINED( sym->type ) && (M_LABEL(sym->type) || M_LABEL(type)) ) { errorSymbol( &illegal_redefine, sym->name, start ); } else { /* Generate diagnostic if redefining a symbol. */ if( M_REDEFINED( sym->type ) && (M_LABEL(sym->type) || M_LABEL(type)) ) { errorSymbol( &redefined_symbol, sym->name, start ); } } type = type | REDEFINED; sym->xref_count++; /* Referenced suymbol, count it. */ xref_count = sym->xref_count; } } if( pass == 2 && xref ) { /* Put the definition line number in the concordance table. */ /* Defined symbols are not counted as references. */ xreftab[sym->xref_index] = lineno; /* Put the line number in the concordance table. */ xreftab[sym->xref_index + xref_count] = lineno; } /* Now set the value and the type. */ sym->val = ( M_LABEL(type) ) ? val : val & 07777; sym->type = ( pass == 1 ) ? ( type | CONDITION ) : type; return( sym ); } /* defineSymbol() */ /******************************************************************************/ /* */ /* Function: lookup */ /* */ /* Synopsis: Find a symbol in table. If not in table, enter symbol in */ /* table as undefined. Return address of symbol in table. */ /* */ /******************************************************************************/ SYM_T *lookup( char *name ) { int ix; /* Insertion index */ int lx; /* Left index */ int rx; /* Right index */ /* First search the permanent symbols. */ lx = 0; ix = binarySearch( name, lx, number_of_fixed_symbols ); /* If symbol not in permanent symbol table. */ if( ix < 0 ) { /* Now try the user symbol table. */ ix = binarySearch( name, number_of_fixed_symbols, symbol_top ); /* If symbol not in user symbol table. */ if( ix < 0 ) { /* Must put symbol in table if index is negative. */ ix = ~ix; if( symbol_top + 1 >= SYMBOL_TABLE_SIZE ) { errorSymbol( &symbol_table_full, name, lexstart ); exit( 1 ); } for( rx = symbol_top; rx >= ix; rx-- ) { symtab[rx + 1] = symtab[rx]; } symbol_top++; /* Enter the symbol as UNDEFINED with a value of zero. */ strcpy( symtab[ix].name, name ); symtab[ix].type = UNDEFINED; symtab[ix].val = 0; symtab[ix].xref_count = 0; if( xref && pass == 2 ) { xreftab[symtab[ix].xref_index] = 0; } } } return( &symtab[ix] ); /* Return the location of the symbol. */ } /* lookup() */ /******************************************************************************/ /* */ /* Function: binarySearch */ /* */ /* Synopsis: Searches the symbol table within the limits given. If the */ /* symbol is not in the table, it returns the insertion point. */ /* */ /******************************************************************************/ int binarySearch( char *name, int start, int symbol_count ) { int lx; /* Left index */ int mx; /* Middle index */ int rx; /* Right index */ int compare; /* Results of comparison */ lx = start; rx = symbol_count - 1; while( lx <= rx ) { mx = ( lx + rx ) / 2; /* Find center of search area. */ compare = strcmp( name, symtab[mx].name ); if( compare < 0 ) { rx = mx - 1; } else if( compare > 0 ) { lx = mx + 1; } else { return( mx ); /* Found a match in symbol table. */ } } /* end while */ return( ~lx ); /* Return insertion point. */ } /* binarySearch() */ /******************************************************************************/ /* */ /* Function: compareSymbols */ /* */ /* Synopsis: Used to presort the symbol table when starting assembler. */ /* */ /******************************************************************************/ int compareSymbols( const void *a, const void *b ) { return( strcmp( ((SYM_T *) a)->name, ((SYM_T *) b)->name )); } /* compareSymbols() */ /******************************************************************************/ /* */ /* Function: evalSymbol */ /* */ /* Synopsis: Get the pointer for the symbol table entry if exists. */ /* If symbol doesn't exist, return a pointer to the undefined sym */ /* */ /******************************************************************************/ SYM_T *evalSymbol() { char name[SYMLEN]; SYM_T *sym; sym = lookup( lexemeToName( name, lexstart, lexterm )); /* The symbol goes in the concordance iff it is in a different position in */ /* the assembler source file. */ if( lexstart != last_xref_lexstart || lineno != last_xref_lineno ) { sym->xref_count++; /* Count the number of references to symbol. */ last_xref_lexstart = lexstart; last_xref_lineno = lineno; /* Put the line number in the concordance table. */ if( xref && pass == 2 ) { xreftab[sym->xref_index + sym->xref_count] = lineno; } } return( sym ); } /* evalSymbol() */ /******************************************************************************/ /* */ /* Function: moveToEndOfLine */ /* */ /* Synopsis: Move the parser input to the end of the current input line. */ /* */ /******************************************************************************/ void moveToEndOfLine() { while( !isend( line[cc] )) cc++; lexstart = cc; lexterm = cc; lexstartprev = lexstart; } /* moveToEndOfLine() */ /******************************************************************************/ /* */ /* Function: nextLexeme */ /* */ /* Synopsis: Get the next lexical element from input line. */ /* */ /******************************************************************************/ void nextLexeme() { /* Save start column of previous lexeme for diagnostic messages. */ lexstartprev = lexstart; lextermprev = lexterm; while( is_blank( line[cc] )) { cc++; } lexstart = cc; if( isalnum( line[cc] )) { while( isalnum( line[cc] )) { cc++; } } else if( isend( line[cc] )) { /* End-of-Line, don't advance cc! */ } else { switch( line[cc] ) { case '"': /* Quoted letter */ if( cc + 2 < maxcc ) { cc++; cc++; } else { errorMessage( &no_literal_value, lexstart ); cc++; } break; case '/': /* Comment, don't advance cc! */ break; default: /* All other punctuation. */ cc++; break; } } lexterm = cc; } /* nextLexeme() */ /******************************************************************************/ /* */ /* Function: nextLexBlank */ /* */ /* Synopsis: Used to prevent illegal blanks in expressions. */ /* */ /******************************************************************************/ void nextLexBlank() { nextLexeme(); if( is_blank( delimiter )) { errorMessage( &illegal_blank, lexstart - 1 ); } delimiter = line[lexterm]; } /* nextLexBlank() */ /******************************************************************************/ /* */ /* Function: pseudoOperators */ /* */ /* Synopsis: Process pseudo-ops (directives). */ /* */ /******************************************************************************/ BOOL pseudoOperators( PSEUDO_T val ) { int count, count2; int delim; int index; int ix; int lexstartsave; WORD16 newfield; WORD16 oldclc; int pack; BOOL status; SYM_T *sym; FILE *temp; int term; WORD16 value; char os8_name[8]; int reloc_clc; status = TRUE; switch( (PSEUDO_T) val ) { case ASCII: /* added 18-Jan-2003 PNT -- derived from TEXT */ delim = line[lexstart]; index = lexstart + 1; while( line[index] != delim && !isend( line[index] )) { punchOutObject( clc, (line[index] & 127) | 128 ); incrementClc(); index++; } if( isend( line[index] )) { cc = index; lexterm = cc; errorMessage( &text_string, cc ); } else { cc = index + 1; lexterm = cc; } nextLexeme(); break; case BANK: errorSymbol( &no_pseudo_op, "BANK", lexstartprev ); /* should select a different 32K out of 128K */ break; case BINPUNCH: /* If there has been data output and this is a mode switch, set up to */ /* output data in BIN mode. */ if( binary_data_output && rim_mode ) { clearLiteralTable(); punchLeader( 8 ); /* Generate a short leader/trailer. */ checksum = 0; binary_data_output = FALSE; } rim_mode = FALSE; break; case DECIMAL: radix = 10; break; case DUBL: inputDubl(); break; case EJECT: page_lineno = LIST_LINES_PER_PAGE; /* This will force a page break. */ status = FALSE; /* This will force reading of next line */ break; case ENPUNCH: if( pass == 2 ) { objectfile = objectsave; } break; case EXPUNGE: /* Erase symbol table */ if( pass == 1 ) { symtab[0] = sym_undefined; symbol_top = 0; number_of_fixed_symbols = symbol_top; fixed_symbols = &symtab[symbol_top - 1]; /* Enter the pseudo-ops into the symbol table. */ for( ix = 0; ix < DIM( pseudo ); ix++ ) { defineSymbol( pseudo[ix].name, pseudo[ix].val, pseudo[ix].type, 0 ); } /* Enter the really permanent symbols into the table. */ /* Also make them part of the permanent symbol table. */ for( ix = 0; ix < DIM( really_permanent_symbols ); ix++ ) { defineSymbol( really_permanent_symbols[ix].name, really_permanent_symbols[ix].val, really_permanent_symbols[ix].type | DEFFIX , 0 ); } number_of_fixed_symbols = symbol_top; fixed_symbols = &symtab[symbol_top - 1]; } break; case FIELD: /* Punch page 0 also */ punchLiteralPool( cp, 1 ); newfield = field >> 12; lexstartsave = lexstartprev; if( isdone( line[lexstart] )) { newfield += 1; /* Blank FIELD directive. */ } else { newfield = (getExpr())->val; /* FIELD with argument. */ } if( rim_mode ) { errorMessage( &in_rim_mode, lexstartsave ); /* Can't change fields. */ } else if( newfield > 7 || newfield < 0 ) { errorMessage( &illegal_field_value, lexstartprev ); } else { value = (( newfield & 0007 ) << 3 ) | 00300; punchObject( value ); if( objectfile != NULL ) /* Only fix checksum if punching */ { checksum -= value; /* Field punches are not added to checksum. */ } field = newfield << 12; } clc = 0200 | field; fieldlc = clc & 07777; if( !rim_mode ) { punchOrigin( clc ); } clearLiteralTable(); break; case FIXMRI: if( line[lexterm] == '=' && isalpha( line[lexstart] )) { lexstartsave = lexstart; term = lexterm; nextLexeme(); /* Skip symbol. */ nextLexeme(); /* Skip trailing = */ defineLexeme( lexstartsave, term, getExprs(), MRI ); } else { errorLexeme( &symbol_syntax, lexstart ); nextLexeme(); /* Skip symbol. */ nextLexeme(); /* Skip trailing = */ (void) getExprs(); /* Skip expression. */ } break; case FIXTAB: if (pass == 1) /* Only fix on first pass, on second all are defined */ { /* Mark all current symbols as permanent symbols. */ for( ix = 0; ix < symbol_top; ix++ ) { symtab[ix].type = symtab[ix].type | FIXED; } number_of_fixed_symbols = symbol_top; fixed_symbols = &symtab[symbol_top - 1]; /* Re-sort the symbol table */ qsort( symtab, symbol_top, sizeof(symtab[0]), compareSymbols ); } break; case FLTG: inputFltg(); /* errorSymbol( &no_pseudo_op, "FLTG", lexstartprev ); */ break; case IFDEF: if( isalpha( line[lexstart] )) { sym = evalSymbol(); nextLexeme(); if( M_DEFINED_CONDITIONALLY( sym->type )) { conditionTrue(); } else { conditionFalse(); } } else { errorLexeme( &label_syntax, lexstart ); } break; case IFNDEF: if( isalpha( line[lexstart] )) { sym = evalSymbol(); nextLexeme(); if( M_DEFINED_CONDITIONALLY( sym->type )) { conditionFalse(); } else { conditionTrue(); } } else { errorLexeme( &label_syntax, lexstart ); } break; case IFNZERO: if( getExprs() == 0 ) { conditionFalse(); } else { conditionTrue(); } break; case IFZERO: if( getExprs() == 0 ) { conditionTrue(); } else { conditionFalse(); } break; case NOPUNCH: if( pass == 2 ) { objectfile = NULL; } break; case OCTAL: radix = 8; break; case PAGE: reloc_clc = clc + reloc; punchLiteralPool( cp, 0 ); oldclc = clc; if( isdone( line[lexstart] )) { clc = (( reloc_clc + 0177 ) & 077600) - reloc; /* No argumnet. */ fieldlc = clc & 07777; } else { value = (getExpr())->val; clc = field + (( value & 037 ) << 7 ) - reloc; fieldlc = clc & 07777; } testForLiteralCollision( clc + reloc ); if( !rim_mode && clc != oldclc ) { punchOrigin( clc ); } break; case PAUSE: break; case RELOC: if( isdone( line[lexstart] )) { reloc = 0; /* Blank RELOC directive. */ } else { value = (getExpr())->val; /* RELOC with argument. */ reloc = (value & 07777) - ( clc & 07777); } break; case RIMPUNCH: /* If the assembler has output any BIN data, output the literal tables */ /* and the checksum for what has been assembled and setup for RIM mode. */ if( binary_data_output && !rim_mode ) { endOfBinary(); clearLiteralTable(); punchChecksum(); punchLeader( 8 ); /* Generate a short leader/trailer. */ } rim_mode = TRUE; break; case SEGMNT: punchLiteralPool( cp, 0 ); if( isdone( line[lexstart] )) { /* No argument. */ clc = ( clc & 06000 ) + 02000; fieldlc = clc & 07777; } else { getExpr(); clc = ( val & 003 ) << 10; fieldlc = clc & 07777; } if( !rim_mode ) { punchOrigin( clc ); } testForLiteralCollision( clc ); break; case TEXT: delim = line[lexstart]; pack = 0; count = 0; index = lexstart + 1; while( line[index] != delim && !isend( line[index] )) { pack = ( pack << 6 ) | ( line[index] & 077 ); count++; if( count > 1 ) { punchOutObject( clc, pack ); incrementClc(); count = 0; pack = 0; } index++; } if( count != 0 ) { punchOutObject( clc, pack << 6 ); incrementClc(); } else { punchOutObject( clc, 0 ); incrementClc(); } if( isend( line[index] )) { cc = index; lexterm = cc; errorMessage( &text_string, cc ); } else { cc = index + 1; lexterm = cc; } nextLexeme(); break; case FILENAME: memset(os8_name, 0, sizeof(os8_name)); delimiter=line[lexstart]; if (delimiter != '.') { for (index = lexstart, count = 0; index < lexterm && count < 6; index++) { os8_name[count++] = line[index]; } delimiter=line[lexterm]; if (delimiter == '.') { nextLexeme(); /* Skip . */ } } nextLexeme(); if (delimiter == '.') { for (index = lexstart, count = 6; index < lexterm && count < 8; index++) { os8_name[count++] = line[index]; } } pack = 0; count = 0; for (count2 = 0; count2 < 8; count2++) { pack = ( pack << 6 ) | ( os8_name[count2] & 077 ); count++; if( count > 1 ) { punchOutObject( clc, pack ); incrementClc(); count = 0; pack = 0; } } nextLexeme(); break; case DEVICE: memset(os8_name, 0, sizeof(os8_name)); for (index = lexstart, count = 0; index < lexterm && count < 4; index++) { os8_name[count++] = line[index]; } pack = 0; count = 0; for (count2 = 0; count2 < 4; count2++) { pack = ( pack << 6 ) | ( os8_name[count2] & 077 ); count++; if( count > 1 ) { punchOutObject( clc, pack ); incrementClc(); count = 0; pack = 0; } } nextLexeme(); break; case TITLE: delim = line[lexstart]; ix = lexstart + 1; /* Find string delimiter. */ do { if( list_title[ix] == delim && list_title[ix + 1] == delim ) { ix++; } ix++; } while( line[ix] != delim && !isend(line[ix]) ); if( line[ix] == delim ) { count = 0; ix = lexstart + 1; do { if( list_title[ix] == delim && list_title[ix + 1] == delim ) { ix++; } list_title[count] = line[ix]; count++; ix++; list_title[count] = '\0'; } while( line[ix] != delim && !isend(line[ix]) ); if( strlen( list_title ) > TITLELEN ) { list_title[TITLELEN] = '\0'; } cc = ix + 1; lexterm = cc; page_lineno = LIST_LINES_PER_PAGE;/* Force top of page for new titles. */ list_title_set = TRUE; } else { cc = ix; lexterm = cc; errorMessage( &text_string, cc ); } nextLexeme(); break; case XLIST: if( isdone( line[lexstart] )) { temp = listfile; /* Blank XLIST directive. */ listfile = listsave; listsave = temp; } else { if( (getExpr())->val == 0 ) { if( listfile == NULL ) { listfile = listsave; listsave = NULL; } } else { if( listfile != NULL ) { listsave = listfile; listfile = NULL; } } } break; case ZBLOCK: value = (getExpr())->val; if( value < 0 ) { errorMessage( &zblock_too_small, lexstartprev ); } else if( value + ( clc & 07777 ) - 1 > 07777 ) { errorMessage( &zblock_too_large, lexstartprev ); } else { for( ; value > 0; value-- ) { punchOutObject( clc, 0 ); incrementClc(); } } break; default: break; } /* end switch for pseudo-ops */ return( status ); } /* pseudoOperators() */ /******************************************************************************/ /* */ /* Function: conditionFalse */ /* */ /* Synopsis: Called when a false conditional has been evaluated. */ /* Lex should be the opening <; ignore all text until */ /* the closing >. */ /* */ /******************************************************************************/ void conditionFalse() { int level; if( line[lexstart] == '<' ) { /* Invariant: line[cc] is the next unexamined character. */ level = 1; while( level > 0 ) { if( isend( line[cc] )) { readLine(); } else { switch( line[cc] ) { case '>': level--; cc++; break; case '<': level++; cc++; break; case '$': level = 0; cc++; break; default: cc++; break; } /* end switch */ } /* end if */ } /* end while */ nextLexeme(); } else { errorMessage( <_expected, lexstart ); } } /* conditionFalse() */ /******************************************************************************/ /* */ /* Function: conditionTrue */ /* */ /* Synopsis: Called when a true conditional has been evaluated. */ /* Lex should be the opening <; skip it and setup for */ /* normal assembly. */ /* */ /******************************************************************************/ void conditionTrue() { if( line[lexstart] == '<' ) { nextLexeme(); /* Skip the opening '<' */ } else { errorMessage( <_expected, lexstart ); } } /* conditionTrue() */ /******************************************************************************/ /* */ /* Function: errorLexeme */ /* */ /* Synopsis: Display an error message using the current lexical element. */ /* */ /******************************************************************************/ void errorLexeme( EMSG_T *mesg, int col ) { char name[SYMLEN]; errorSymbol( mesg, lexemeToName( name, lexstart, lexterm ), col ); } /* errorLexeme() */ /******************************************************************************/ /* */ /* Function: errorSymbol */ /* */ /* Synopsis: Display an error message with a given string. */ /* */ /******************************************************************************/ void errorSymbol( EMSG_T *mesg, char *name, int col ) { char linecol[12]; char *s; if( pass == 2 ) { s = ( name == NULL ) ? "" : name ; errors++; sprintf( linecol, "(%d:%d)", lineno, col + 1 ); fprintf( errorfile, "%s%-9s : error: %s \"%s\" at Loc = %5.5o\n", filename, linecol, mesg->file, s, clc ); saveError( mesg->list, col ); } error_in_line = TRUE; } /* errorSymbol() */ /******************************************************************************/ /* */ /* Function: errorMessage */ /* */ /* Synopsis: Display an error message without a name argument. */ /* */ /******************************************************************************/ void errorMessage( EMSG_T *mesg, int col ) { char linecol[12]; if( pass == 2 ) { errors++; sprintf( linecol, "(%d:%d)", lineno, col + 1 ); fprintf( errorfile, "%s%-9s : error: %s at Loc = %5.5o\n", filename, linecol, mesg->file, clc ); saveError( mesg->list, col ); } error_in_line = TRUE; } /* errorMessage() */ /******************************************************************************/ /* */ /* Function: saveError */ /* */ /* Synopsis: Save the current error in a list so it may displayed after the */ /* the current line is printed. */ /* */ /******************************************************************************/ void saveError( char *mesg, int col ) { if( save_error_count < DIM( error_list )) { error_list[save_error_count].mesg = mesg; error_list[save_error_count].col = col; save_error_count++; } error_in_line = TRUE; if( listed ) { printErrorMessages(); } } /* saveError() */ /* End-of-File */ |
Changes to src/PDP8/pdp8_cpu.c.
︙ | ︙ | |||
408 409 410 411 412 413 414 | if ((reason = sim_process_event ())) { /* ---PiDP add--------------------------------------------------------------------------------------------- */ // We're about to leave the loop, so repaint one last time // in case this is a Ctrl-E and we later get a "cont" // command. Set a flag that will let us auto-resume. extern int resumeFromInstructionLoopExit, swStop, swSingInst; resumeFromInstructionLoopExit = swStop = swSingInst = 1; | | | 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | if ((reason = sim_process_event ())) { /* ---PiDP add--------------------------------------------------------------------------------------------- */ // We're about to leave the loop, so repaint one last time // in case this is a Ctrl-E and we later get a "cont" // command. Set a flag that will let us auto-resume. extern int resumeFromInstructionLoopExit, swStop, swSingInst; resumeFromInstructionLoopExit = swStop = swSingInst = 1; set_pidp8i_leds (PC, MA, MB, IR, LAC, MQ, IF, DF, SC, int_req, Pause); // Also copy SR hardware value to software register in case // the user tries poking at it from the sim> prompt. SR = get_switch_register(); /* ---PiDP end---------------------------------------------------------------------------------------------- */ break; |
︙ | ︙ | |||
434 435 436 437 438 439 440 | sim_interval = sim_interval - 1; // Have to keep display updated while stopped. This does // mean if the software starts with the STOP switch held // down, we'll put garbage onto the display for MA, MB, and // IR, but that's what the real hardware does, too. See // https://github.com/simh/simh/issues/386 | | | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | sim_interval = sim_interval - 1; // Have to keep display updated while stopped. This does // mean if the software starts with the STOP switch held // down, we'll put garbage onto the display for MA, MB, and // IR, but that's what the real hardware does, too. See // https://github.com/simh/simh/issues/386 set_pidp8i_leds (PC, MA, MB, IR, LAC, MQ, IF, DF, SC, int_req, Pause); // Go no further in STOP mode. In particular, fetch no more // instructions, and do not touch PC! continue; case pft_halt: |
︙ | ︙ | |||
1526 1527 1528 1529 1530 1531 1532 | if (++skip_count >= (max_skips - dither)) { // Save skips to inst counter and reset inst_count += skip_count; skip_count = 0; // We need to update the LED data again | | > < | 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 | if (++skip_count >= (max_skips - dither)) { // Save skips to inst counter and reset inst_count += skip_count; skip_count = 0; // We need to update the LED data again set_pidp8i_leds (PC, MA, MB, IR, LAC, MQ, IF, DF, SC, int_req, Pause); Pause = 0; // Has it been ~1s since we updated our max_skips value? time_t now; if (time(&now) > last_update) { // Yep; simulator IPS may have changed, so freshen it. last_update = now; max_skips = inst_count / pidp8i_updates_per_sec; //printf("Inst./repaint: %zu - %zu; %.2f MIPS\r\n", // max_skips, dither, inst_count / 1e6); inst_count = 0; } dither = max_skips > 32 ? lrand48() % (max_skips >> 3) : 0; // 12.5% } /* ---PiDP end---------------------------------------------------------------------------------------------- */ } /* end while */ /* Simulation halted */ saved_PC = IF | (PC & 07777); /* save copies */ saved_DF = DF & 070000; |
︙ | ︙ |
Changes to src/PDP8/pidp8i.c.in.
︙ | ︙ | |||
245 246 247 248 249 250 251 | //// set_pidp8i_leds /////////////////////////////////////////////////// // Given all of the PDP-8's internal registers that affect the front // panel display, modify the GPIO thread's LED state values accordingly. // // Also update the LED brightness values based on those new states. | | | | | < < < < < | < | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | //// set_pidp8i_leds /////////////////////////////////////////////////// // Given all of the PDP-8's internal registers that affect the front // panel display, modify the GPIO thread's LED state values accordingly. // // Also update the LED brightness values based on those new states. void set_pidp8i_leds (uint32 sPC, uint32 sMA, uint16 sMB, uint16 sIR, int32 sLAC, int32 sMQ, int32 sIF, int32 sDF, int32 sSC, int32 int_req, int Pause) { // Bump the instruction count. This should always be equal to the // Fetch LED's value, but integers are too cheap to get cute here. // // Note that we only update pdis_update directly once in this whole // process. This is in case the display swap happens while we're // working: we want to finish work on the same display even though // it's now called the paint-from display, so it's consistent. display* pd = pdis_update; ++pd->inst_count; // Rows 0-4, easy cases: single-register LED strings set_pidp8i_row_leds (pd, 0, sPC); set_pidp8i_row_leds (pd, 1, sMA); set_pidp8i_row_leds (pd, 2, sMB); set_pidp8i_row_leds (pd, 3, sLAC & 07777); set_pidp8i_row_leds (pd, 4, sMQ); #if 0 // debugging static time_t last = 0, now; if (time(&now) != last) { uint16* pcurr = pd->curr; printf("\r\nSET: [PC:%04o] [MA:%04o] [MB:%04o] [AC:%04o] [MQ:%04o]", pcurr[0], pcurr[1], pcurr[2], pcurr[3], pcurr[4]); |
︙ | ︙ | |||
303 304 305 306 307 308 309 | // Row 5b: set the Defer LED if... if ((inst_type <= 05000) && // it's a memory reference instruction (sIR & 00400)) { // and indirect addressing flag is set set_pidp8i_led (pd, 5, 1); } | | | < < | | < < < < > < | | < | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | // Row 5b: set the Defer LED if... if ((inst_type <= 05000) && // it's a memory reference instruction (sIR & 00400)) { // and indirect addressing flag is set set_pidp8i_led (pd, 5, 1); } // Row 5c: The Fetch LED is bumped once per CPU instruction, as is // Execute while we're not in STOP state. They're set at different // times, but they're twiddled so rapidly that they both just become // a 50% blur in normal operation, so we don't make the CPU core set // these "on-time." It just doesn't matter. extern int swStop, swSingInst; int running = !swStop && !swSingInst; if (running) set_pidp8i_led (pd, 5, 2); // Execute set_pidp8i_led (pd, 5, 3); // Fetch // Row 6a: Remaining LEDs in upper right block pd->curr[6] = 0; if (running) set_pidp8i_led (pd, 6, 7); // bump Run LED if (Pause) set_pidp8i_led (pd, 6, 8); // bump Pause LED if (int_req & INT_ION) set_pidp8i_led (pd, 6, 9); // bump ION LED |
︙ | ︙ | |||
345 346 347 348 349 350 351 | if (!running || resumeFromInstructionLoopExit) { memcpy(pdis_paint, pdis_update, sizeof(struct display)); } } //// mount_usb_stick_file ////////////////////////////////////////////// | | | | | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | if (!running || resumeFromInstructionLoopExit) { memcpy(pdis_paint, pdis_update, sizeof(struct display)); } } //// mount_usb_stick_file ////////////////////////////////////////////// // Search for a PDP-8 media image in one of the Pi's USB auto-mount // directories and attempt to ATTACH it to the simulator. static void mount_usb_stick_file (int devNo, char *devCode) { char sFoundFile[CBUFSIZE] = { '\0' }; char sUSBPath[CBUFSIZE]; // will be "/media/usb0" etc char fileExtension[4]; // will be ".RX" etc int i, j; // Build expected file name extension from the first two characters of // the passed-in device code. fileExtension[0] = '.'; // extension starts with a . strncpy (fileExtension + 1, devCode, 2); // extension is PT, RX, RL etc |
︙ | ︙ | |||
374 375 376 377 378 379 380 | // we keep track is so we don't have the same media image file attached // to both devices of a given type we support. That is, you can't have // a given floppy image file attached to both RX01 drives, but you *can* // repeatedly re-ATTACH the same floppy image to the first RX01 drive. static char mountedFiles[8][CBUFSIZE]; mountedFiles[devNo][0] = '\0'; | < < < < < < | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | > | < > | | < < | | | < | < < | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | // we keep track is so we don't have the same media image file attached // to both devices of a given type we support. That is, you can't have // a given floppy image file attached to both RX01 drives, but you *can* // repeatedly re-ATTACH the same floppy image to the first RX01 drive. static char mountedFiles[8][CBUFSIZE]; mountedFiles[devNo][0] = '\0'; for (i = 0; i < 8 && sFoundFile[0] == '\0'; ++i) { // search all 8 USB mount points, numbered 0-7 snprintf (sUSBPath, sizeof (sUSBPath), "/media/usb%d", i); DIR *pDir = opendir (sUSBPath); if (pDir) { struct dirent* pDirent; while ((pDirent = readdir (pDir)) != 0) { // search all files in directory if (pDirent->d_name[0] == '.') continue; // dotfiles clutter debug output char* pext = strstr (pDirent->d_name, fileExtension); if (pext && (pext == (pDirent->d_name + strlen (pDirent->d_name) - 3))) { snprintf (sFoundFile, sizeof (sFoundFile), "%s/%s", sUSBPath, pDirent->d_name); #if 0 // debugging printf("\r\nFound candidate file %s for dev %s, ext *%s...", sFoundFile, devCode, fileExtension); #endif for (j = 0; j < 7; ++j) { if (strncmp (mountedFiles[j], sFoundFile, CBUFSIZE) == 0) { #if 0 // debugging printf("\r\nAlready have %s mounted, slot %d; will not remount.", sFoundFile, j); #endif sFoundFile[0] = '\0'; // don't leave outer loop; keep looking break; } } if (j == 7) { // Media image file is not already mounted, so leave while // loop with path set to mount it break; } } #if 0 // debugging else { printf("\r\nFile %s on %s doesn't match *%s...", pDirent->d_name, sUSBPath, fileExtension); } #endif } closedir (pDir); } else { // Not a Pi or the USB auto-mounting software isn't installed printf ("\r\nCannot open %s: %s\r\n", sUSBPath, strerror (errno)); return; } } if (sFoundFile[0]) { // no file found, exit if (access (sFoundFile, R_OK) == 0) { char sAttachCmd[CBUFSIZE] = { '\0' }; snprintf (sAttachCmd, sizeof(sAttachCmd), "%s %s", devCode, sFoundFile); t_stat scpCode = attach_cmd ((int32) 0, sAttachCmd); |
︙ | ︙ |
Changes to src/PDP8/pidp8i.h.
︙ | ︙ | |||
43 44 45 46 47 48 49 | extern int32 get_switch_register (void); extern size_t get_pidp8i_initial_max_skips (size_t updates_per_sec); extern pidp8i_flow_t handle_flow_control_switches (uint16* pM, uint32 *pPC, uint32 *pMA, int32 *pMB, int32 *pLAC, int32 *pIF, int32 *pDF, int32* pint_req); | | | | | 43 44 45 46 47 48 49 50 51 52 53 54 | extern int32 get_switch_register (void); extern size_t get_pidp8i_initial_max_skips (size_t updates_per_sec); extern pidp8i_flow_t handle_flow_control_switches (uint16* pM, uint32 *pPC, uint32 *pMA, int32 *pMB, int32 *pLAC, int32 *pIF, int32 *pDF, int32* pint_req); extern void set_pidp8i_leds (uint32 sPC, uint32 sMA, uint16 sMB, uint16 sIR, int32 sLAC, int32 sMQ, int32 sIF, int32 sDF, int32 sSC, int32 int_req, int Pause); #endif // !defined(PIDP8I_H) |
Deleted src/cc8/GPL3.txt.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/Makefile.in.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/README.md.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/README.md.
|
| < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/code8.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/ctype.h.
|
| < |
Deleted src/cc8/cross/data.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/data.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/defs.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/error.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/expr.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/function.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/gen.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/io.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/lex.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/main.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/preproc.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/primary.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/stmt.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/sym.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/cross/while.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/examples/README.md.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/examples/basic.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/examples/calc.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/examples/fib.c.
|
| < < < < < < < < < < < < < < < |
Deleted src/cc8/examples/init.pa.
|
| < |
Deleted src/cc8/examples/libc.h.
|
| < |
Deleted src/cc8/examples/ps.c.
|
| < < < < < < < < < < < < < < < < |
Deleted src/cc8/include/init.pa.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/include/libc.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/os8/Makefile.in.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/os8/bldcc8.bi.
|
| < < < < < < < < < < < < < < < |
Deleted src/cc8/os8/c8.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/os8/header.sb.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/os8/init.pa.
|
| < |
Deleted src/cc8/os8/libc.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/os8/libc.h.
|
| < |
Deleted src/cc8/os8/n8.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/cc8/os8/p8.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/d8tape/LICENSE.md.
|
| < < < < < < < < < < < < |
Deleted src/d8tape/d8tape.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/d8tape/dasm.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/d8tape/flow.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/d8tape/iot.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/d8tape/main.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/d8tape/version.c.
|
| < |
Deleted src/palbart/LICENSE.md.
|
| < < < < < < < < < < < < < < < < |
Deleted src/palbart/palbart.1.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/palbart/palbart.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/ptp2txt.c.
1 | /* | | < | | | | | | | < | < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Program to convert between linux ASCII txt files * and the output of OS/8 PIP to the Paper Tape Punch. * The OS/8 paper tape punch format is: * leader: a bunch of ASCII NUL chars to be ignored. * ASCII with the 8th bit set. * trailer: a bunch of ASCII NUL chars to be ignored. * This program can be used as a filter from stdin to stdout or * it will create a new file with name ending in .txt if going to linux txt * or .ptp if going to OS/8 PIP Paper Tape format. * If the program is called with the name "txt2ptp" * 100 bytes of leader trailer is prepended and appended to the file, * and the 8th bit of every character is set. * If called by any other name, the ASCII NUL character is * ignored anywhere in the file, and the 8th bit is cleared. * This program helps work around the issue that the * OS/8 Paper Tape reader handler assumes the last * character in the buffer is junk, so that when you send * a plain text file into PDP-8 SIMH OS/8 with the * ptr device, the last character is lost. */ |
︙ | ︙ | |||
114 115 116 117 118 119 120 | void make_lt (FILE *fpout) { fwrite (global_ltbuf, sizeof(char), LTCOUNT, fpout); } void make_ptp (FILE *fpin, FILE *fpout) { | | | < < < < < < < < < < < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | void make_lt (FILE *fpout) { fwrite (global_ltbuf, sizeof(char), LTCOUNT, fpout); } void make_ptp (FILE *fpin, FILE *fpout) { int inchar, outchar; int read_ct, n; char *obuffp; char ibuff[BLOCK_SIZE], obuff[BLOCK_SIZE]; make_lt (fpout); while ((read_ct = fread (ibuff, sizeof(char), BLOCK_SIZE, fpin))) { obuffp = obuff; for (n = 0; n < read_ct; n++) { inchar = *(ibuff + n); *obuffp++ = inchar | 0200; } fwrite (obuff, sizeof(char), obuffp - obuff, fpout); } make_lt (fpout); } void process_file (char *fname, int flag) { FILE *fpin, *fpout; |
︙ | ︙ |
Changes to tools/bosi.
︙ | ︙ | |||
162 163 164 165 166 167 168 | sudo dd if=/dev/zero of=/junk bs=1M || true # it *will* error-out! sudo rm -f /junk encpass=$(openssl passwd -1 edsonDeCastro1968) sudo usermod -p $encpass pidp8i sudo passwd -e pidp8i | < < < < < < | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | sudo dd if=/dev/zero of=/junk bs=1M || true # it *will* error-out! sudo rm -f /junk encpass=$(openssl passwd -1 edsonDeCastro1968) sudo usermod -p $encpass pidp8i sudo passwd -e pidp8i sudo poweroff } # Shrink the filesystem on the OS SD card we're about to image to just a # bit bigger than required to hold its present contents. # |
︙ | ︙ |
Deleted tools/cc8-tu56-update.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted tools/cmplz.
|
| < < < < < < < < < < < < < < |
Deleted tools/diffstat-since-release.
|
| < < < |
Deleted tools/mkadrules.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted tools/publish-os8.
|
| < < < < |
Changes to tools/test-mkos8.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ######################################################################## use strict; use warnings; # Modules from CPAN use Math::Subsets::List; | < < < | < < < | > < | < | | < | < | > > > > | < < < < < < < < < < < < < < < < | < > < | | | | < | < < < < < | < | < < < | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < | < < < < < | < < < < < < < < | < | < < < | < < < < < < < < < | < < < < < < < | | | | | > > > | | < | < | < < | < < < | | < | < < < < | < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | ######################################################################## use strict; use warnings; # Modules from CPAN use Math::Subsets::List; # Core modules use Digest::SHA qw(sha256_hex); use File::Compare; use File::Copy; use Getopt::Std; # Perl::Critic rules we're willing to bend ## no critic (InputOutput::RequireBriefOpen ) #### GLOBALS ########################################################### my $tests_mf; my $currdsk = 'bin/os8v3d-bin.rk05'; my $currdlz = 'bin/os8v3d-bin.rklz'; my $currlog = 'obj/mkos8-bin.log'; # Command line option values my ($dry_run, $generate_only); #### sanitize_log ###################################################### # Copy the given input log file to the ouptut file, expurgating bits # that change from one run to the next without being meaningful. sub sanitize_log { my ($ifile, $ofile) = @_; open my $if, '<', $ifile or die "Cannot read $ifile: $!\n"; open my $of, '>', $ofile or die "Cannot write $ofile: $!\n"; while (<$if>) { # Don't care about the simulator's configuration line: as # far as we know, it doesn't affect the OS/8 disks. s{^PiDP-8/I .*}{PiDP-8/I [test-mkos8]}x; # These tend to happen during OS/8's keyboard busy-wait # loop, which means there's a 50/50 chance of which # instruction will happen to be running at the time of the # interrupt. Doesn't matter which. s{Simulation stopped, .*}{Simulation stopped.}x; # Squish configuration line in the INIT.TX output. s{CONFIGURED BY .*}{CONFIGURED BY tester\@mkos8}x; print $of $_; } close $if; close $of; return; } #### test ############################################################## # Test a single permutation sub test { my @opts = @_; # Distill this option set to a hash value after which we will # name the output files. We don't want to name files with a # leading hyphen or with long variable-length names, potentially # multiple lines long. my $optstr = join ' ', @opts; my $hash = sha256_hex($optstr); my $hdir = "test/$hash"; my $testlog = "$hdir/last.log"; my $testdlz = "$hdir/last.rklz"; # Skip this one if it already exists and we're in -g mode. if ($generate_only && -e $hdir) { print "Skipping $hash; already done.\n"; return; } # Do the test my $optdesc = $optstr || "default media"; print "Configuring $optdesc...\n"; return if $dry_run; mkdir $hdir; system "./configure $optstr > test/cfg.log 2>&1" and die "Failed to configure $optdesc!\n"; print "Building...\n"; system "make $currdsk > test/make.log 2>&1" and die "Failed to build $currdsk!\n"; # Quickly compress the test disk: we don't want to store all the # "air" in an RK05 in our test corpus. system("lz4 $currdsk > $currdlz"); if (not -f $testlog or not -f $testdlz) { # This test hasn't run here yet, so blindly assume its # output is correct, and thus that it should be our exemplar # henceforth. Store in LZ format copy ($currdlz, $testdlz); sanitize_log ($currlog, $testlog); # Log the mapping between the hash and the options it # represents, so the user can reverse it. print $tests_mf "$hash $optdesc\n"; } elsif (compare ($currdlz, $testdlz) == 0) { print "mkos8 $optdesc test passed.\n"; } else { my $fdiff = "$hdir/fail.diff"; my $faillog = "$hdir/fail.log"; sanitize_log ($currlog, $faillog); system "diff -wu $testlog $faillog > $fdiff"; print "MKOS8 ", uc($optdesc), " DIFFERS! See $fdiff.\n"; } return; } #### main ############################################################## # Parse command line my %clopts; getopts('gn', \%clopts) or die "Failed to parse command line!\n"; $dry_run = $clopts{n}; $generate_only = $clopts{g}; # Get all current --*-os8-* options, filtering out those we know should # not be tried for this: # # * No --os8-minimal because that just turns on all --disable-os8-* # options, so it's already covered. # * No --disable-os8-src because we don't test the src disk; it's |
︙ | ︙ | |||
381 382 383 384 385 386 387 | "grep -v -e 'os8-minimal' -e 'os8-src' -e 'os8-focal\$'" ); open my $ocmd, '-|', join('|', @cmd) or die "Failed to get os8 option set: $!\n"; my @cfgOpts = <$ocmd>; close $ocmd; chomp @cfgOpts; | | | | < | < < < < < < | < > | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | "grep -v -e 'os8-minimal' -e 'os8-src' -e 'os8-focal\$'" ); open my $ocmd, '-|', join('|', @cmd) or die "Failed to get os8 option set: $!\n"; my @cfgOpts = <$ocmd>; close $ocmd; chomp @cfgOpts; # Init global resources mkdir 'test'; open $tests_mf, '>>', 'test/tests-manifest.txt' or die "Cannot append to test manifest: $!\n"; # Test all possible permutations of those options. subsets \&test, @cfgOpts; |
Deleted tools/test-os8-send-file.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to tools/version.
︙ | ︙ | |||
28 29 30 31 32 33 34 | # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## use strict; use warnings; | | < < < < < < < < < < | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | # use or other dealings in this Software without prior written # authorization from those authors. ######################################################################## use strict; use warnings; use Cwd 'abs_path'; use File::Basename; my $topdir = dirname($0) . '/..'; if (-e "$topdir/.fslckout") { # Get version info from Fossil my ($branch, $checkout, $version, $comment); chdir $topdir; # we might be building out-of-tree open my $s, '-|', 'fossil status 2> /dev/null' |
︙ | ︙ |