Well, to no one's surprise at least among those who have been following this blog, I am not going to complete my project. I did actually get some coding done on Hammurabi, but honestly I didn't get very far. It's not a big game, and I think I'm finally well positioned to get some serious work done on it, so it would still be possible to knock it out today if I had the time, but I just don't. So I'll just accept that it's not going to get done.
But by no means do I consider this project a failure. To refresh our memory, my project was to develop a text-based game (Hammurabi) in Fortran on a PDP-8 running OS/8 using the simh simulator instead of a real machine (since I don't have one and don't have several thousand in spare cash to get one). But the real point of the project, from my standpoint at least, was really to learn about a system and language that I knew nothing about. And in that I think I succeeded.
When I started at the beginning of July, all I knew of the PDP-8 was that it was a minicomputer from 1965 that had been an important step in computer history. I had actually seen several at VCF SE a few months ago, but hadn't touched or worked on any. I hadn't even seen the front panel light up - and I wouldn't have known what the lights meant if it had!
Similarly, I had never worked in - nor knew anything about - Fortran. In fact, when I first contemplated this project, I actually wanted to use COBOL, but I couldn't find a COBOL for the PDP-8. Then I thought about ALGOL, given it seems to have been an influential language, but I finally settled on Fortran only because the OS/8 Handbook had two large sections on Fortran (though, as it turned out, it was for two different versions of Fortran, so really only one section was of use to me).
By the end of this retrochallenge, I feel I'm pretty comfortable with OS/8, TECO, and Fortran. I still have a lot to learn, but I can get around the system and do common things pretty easily. My only regret in this regard is that by choosing a high level language like Fortran, I really didn't gain as much knowledge of the PDP-8 architecture as I might have if I'd done a project in PAL8 assembly language. But still I'm very happy with what I accomplished and where I ended up, even if I didn't actually finish the project.
Having spent a month with the PDP-8 and OS/8, I can say that I really like the system - better in some ways than most microcomputers, in fact. Most microcomputers use BASIC as their operating environment, and while I used BASIC extensively back in the day, I really don't like it much now. When I first got into vintage computing, I did a few BASIC projects for the sake of nostalgia and discovered that, unlike the microcomputer systems themselves, BASIC just hasn't aged well - for me, at least. So I like that OS/8 is an operating system that just include BASIC as another utility that you can run, but not something that you're forced to use. So I fully intend to do more with the PDP-8. I'm still looking forward to getting my PiDP-8 in the second run in October, and between then and now I want to continue to sharpen my PDP-8 skills.
I actually have several PDP-8 projects in mind. I'd like to attempt to build a full-screen editor, possibly with VT100 support, though that's not really a small project. I'd also like to write something to be able to transfer files between OS/8 disk images and the host filesystem. I don't like writing code that I can't put up on Github, and I certainly don't intend to port git to OS/8! Also I really like what Cat's Eye Technologies did for their challenge and thought about doing something similar for the PDP-8.
On the other hand, while I don't hate Fortran, I can't say I'm overly fond of it either. I could see using it as a glue language to bring assembly modules together - that's what Adventure did. But honestly I doubt I'll use it at all again. That doesn't mean I regret learning it, or that I think it's a horrible language. It actually has some cool features, though ultimately for me nothing that will compel me to use it. It probably falls into the class of languages that I would use if there was a specific purpose, but I won't go out of my way to use it.
So where to from here? Well, as I said, I will continue to work with the PDP-8. My two top projects will be to develop a file transfer utility, and to learn PAL8. There is an open source PAL-8 cross-assembler that I could use, if I get the file transfer utility done, but I probably will just stick with doing assembler on the PDP-8 itself for the moment. I plan to continue to blog about my PDP-8 experiences, using this very blog, so if you have any interest, feel free to check back.
Finally, with regards to the Retrochallenge itself, this is my first time participating and I can say without any hesitation that I love it! I'm not a particular focused person, and I often drift from project to project, but this was great for keeping me on target. And watching the other projects as they developer over the past month was very inspirational. My only regret is that the Retrochallenge only occurs twice a year! Already thinking about what to do for January...
Started during for the 2015/07 Retrochallenge, this is now ongoing blog for my work related to the PDP-8
Thursday, July 30, 2015
Wednesday, July 29, 2015
The BATCH utility
In my last post, I talked in some depth about how to build a multi-module Fortran program, and then at the end lamented a little bit about the lack of any way to automate builds. Well, as it turns out, I was wrong! There is an OS/8 utility called BATCH that allows you to do this. In my first pass through the OS/8 Handbook, I came across this utility, but since they really describe it as a batch processing utility, which isn't anything I'm really doing, I skipped over it and kind of forgot about it.
But after writing my post yesterday, I recalled that it was there and wondered if it could be used to automate builds. And, sure, enough it can - quite easily, in fact. It's not without its own quirks and pitfalls, but it is a pretty nice little utility that pretty much allows you to execute any set of commands.
To use this, you have to create a text file with your commands. There are a few tricks, but it's generally straightforward. First, the file has to be on a permanent device. So a hard disk (RK device) is acceptable, but a floppy (RX) is not. But on my system, the second partition, RKB0, wasn't acceptable either. It had to be on RKA0. Since I'm developing my source on a floppy image, it's a little annoying that the equivalent of my make file has to be on the main hard drive, but c'est la vie. There may be a way around this, but for now it's acceptable.
Using the BATCH utility is pretty simple. First, come up with your build script (I named mine simply BUILD), such as this one for my little test program:
$JOB
/ CLEAN EXISTING FILES
.DEL RXA0:TEST.RL
.DEL RXA0:TEST.LD
/ COMPILE
.R F4
*RXA0:TEST<RXA0:TEST
/ LOAD
.R LOAD
*RXA0:TEST<RXA0:TEST
*$
/ EXECUTE
.R FRTS
*<RXA0:TEST$
$END
If you're already familiar with OS/8, or you read my last post, then much of the above is already familiar. Also, I assume $JOB and $END are pretty self-explanatory. As you might also infer from the above, lines that start with a slash are comments. Everything else is pretty much the same OS/8 commands that you should recognize. The only two things to note is that you must precede each line with a '.' or '*' as the Keyboard Monitor or Command Decoder would do if you were entering the commands interactively. So when you run a program, it is ".R <program>", not just "R <program>". The parameters would be preceded by a "*". And, finally, when you need an ALTMODE character (ESC on modern keyboards), you just use a $, i.e., Shift-4.
Calling this file is even easier. The CCL command, SUBMIT, calls the BATCH utility, so you can execute your batch file by:
.SUBMIT BUILD
Of course, this still isn't a proper build system as we're used to now. There's no conditional compilation based on what's changed and no error checking. So if the compile fails, for example, it will still perform the LOAD and FRTS commands. But this is still much better than the alternative, typing in each command by hand every time.
But after writing my post yesterday, I recalled that it was there and wondered if it could be used to automate builds. And, sure, enough it can - quite easily, in fact. It's not without its own quirks and pitfalls, but it is a pretty nice little utility that pretty much allows you to execute any set of commands.
To use this, you have to create a text file with your commands. There are a few tricks, but it's generally straightforward. First, the file has to be on a permanent device. So a hard disk (RK device) is acceptable, but a floppy (RX) is not. But on my system, the second partition, RKB0, wasn't acceptable either. It had to be on RKA0. Since I'm developing my source on a floppy image, it's a little annoying that the equivalent of my make file has to be on the main hard drive, but c'est la vie. There may be a way around this, but for now it's acceptable.
Using the BATCH utility is pretty simple. First, come up with your build script (I named mine simply BUILD), such as this one for my little test program:
$JOB
/ CLEAN EXISTING FILES
.DEL RXA0:TEST.RL
.DEL RXA0:TEST.LD
/ COMPILE
.R F4
*RXA0:TEST<RXA0:TEST
/ LOAD
.R LOAD
*RXA0:TEST<RXA0:TEST
*$
/ EXECUTE
.R FRTS
*<RXA0:TEST$
$END
If you're already familiar with OS/8, or you read my last post, then much of the above is already familiar. Also, I assume $JOB and $END are pretty self-explanatory. As you might also infer from the above, lines that start with a slash are comments. Everything else is pretty much the same OS/8 commands that you should recognize. The only two things to note is that you must precede each line with a '.' or '*' as the Keyboard Monitor or Command Decoder would do if you were entering the commands interactively. So when you run a program, it is ".R <program>", not just "R <program>". The parameters would be preceded by a "*". And, finally, when you need an ALTMODE character (ESC on modern keyboards), you just use a $, i.e., Shift-4.
Calling this file is even easier. The CCL command, SUBMIT, calls the BATCH utility, so you can execute your batch file by:
.SUBMIT BUILD
Of course, this still isn't a proper build system as we're used to now. There's no conditional compilation based on what's changed and no error checking. So if the compile fails, for example, it will still perform the LOAD and FRTS commands. But this is still much better than the alternative, typing in each command by hand every time.
Tuesday, July 28, 2015
Some answers to old problems and why development shortcuts can be bad
This is a pretty long post, so for that I apologize, but two big topics to cover.
If you've been following this blog, in the last post I indicated that I was having a problem loading the Fortran standard library. The FORLIB.RL seemed to be missing from my system. I'm happy to report that I've gotten past this issue. I found a floppy disk image that had a complete OS/8 Fortran IV system, I copied the FORLIB.RL to my main partition, and it works.
Interestingly, it seems to work without me having to load it. As you may recall, to load all the modules for an application, you use the LOAD utility and specify all the modules, what order they are loaded (for purposes of overlaying code), and what the main program file name will be. In reading through this section in the Handbook, I didn't see anything about loading the standard library, so I assumed that it just happened automatically. Then, as I discussed in yesterday's blog, I ran into problems and noticed that in their sample LOAD session, they actually loaded the standard library explicitly but using a different file name (LIB.RL instead of FORLIB.RL). It gives no explanation why it does this, so then I assumed that you had to explicitly load the standard library.
So I wrote a little test program and tried to load the FORLIB.RL in LOAD, but kept getting a BAD INPUT FILE error. But then I noticed something: When I failed to load in the standard library, my little test program still ran correctly. Apparently it does load in the standard library automatically if it finds FORLIB.RL. This puzzled me because I wondered why would they load it in manually in the sample LOAD session, and why was it giving me the BAD INPUT FILE error?
After some thought, I think I have at least part of an answer. I have no clue about the BAD INPUT FILE, but I think I understand why they were loading it in manually in LOAD. This utility does two things. Most obviously it allows the developer to load all the modules. But it also allows for modules to be defined as overlays. Such a module would not be loaded into memory when the program first starts, but as the program executes it can be swapped into memory as needed. This allows a Fortran program to be as large as 300k even though there's only a maximum of 32k memory. The standard library is quite large, so I assume by loading the FORLIB.RL manually, the sample session was showing how to turn it into an overlay module so that it's not eating up memory for the whole life of the program. I'm still not sure why it was named LIB.RL though, but since I'm not really wanting to concern myself with overlays, I'm happy to ignore this issue.
But in looking at this issue, I did actually end up resolving an earlier issue concerning subroutines and functions. I talk about the issue in two of my prior blogs: Random Linking Woes and Still learning, still haven't gotten anywhere. Basically to do a subroutine or function, each has to be defined as a separate module. But I couldn't figure out how to load these modules.
The problem really comes from the fact that I was using the COMPILE and EXECUTE commands. These are nice commands sort of built in to OS/8. They allow you to build and execute simple programs without knowing what you're doing. In essence, they're development shortcuts. Now I'm not opposed to such shortcuts, but as a professional developer now for more than two decades, I've always followed the rule that you should only use such shortcuts when you know what they're doing. If you don't, then when things screw up as they inevitably do, you don't know how to fix it. Unfortunately I didn't follow that rule with this project, so when I ran into issues with subroutines, I didn't really know how to get around it.
But this issue forced me to really break down and understand in more depth about how to build a Fortran app, and that's led me back to the solution for subroutines and functions. As I mentioned in yesterday's blog, there are 3 steps to building an application:
If you've been following this blog, in the last post I indicated that I was having a problem loading the Fortran standard library. The FORLIB.RL seemed to be missing from my system. I'm happy to report that I've gotten past this issue. I found a floppy disk image that had a complete OS/8 Fortran IV system, I copied the FORLIB.RL to my main partition, and it works.
Interestingly, it seems to work without me having to load it. As you may recall, to load all the modules for an application, you use the LOAD utility and specify all the modules, what order they are loaded (for purposes of overlaying code), and what the main program file name will be. In reading through this section in the Handbook, I didn't see anything about loading the standard library, so I assumed that it just happened automatically. Then, as I discussed in yesterday's blog, I ran into problems and noticed that in their sample LOAD session, they actually loaded the standard library explicitly but using a different file name (LIB.RL instead of FORLIB.RL). It gives no explanation why it does this, so then I assumed that you had to explicitly load the standard library.
So I wrote a little test program and tried to load the FORLIB.RL in LOAD, but kept getting a BAD INPUT FILE error. But then I noticed something: When I failed to load in the standard library, my little test program still ran correctly. Apparently it does load in the standard library automatically if it finds FORLIB.RL. This puzzled me because I wondered why would they load it in manually in the sample LOAD session, and why was it giving me the BAD INPUT FILE error?
After some thought, I think I have at least part of an answer. I have no clue about the BAD INPUT FILE, but I think I understand why they were loading it in manually in LOAD. This utility does two things. Most obviously it allows the developer to load all the modules. But it also allows for modules to be defined as overlays. Such a module would not be loaded into memory when the program first starts, but as the program executes it can be swapped into memory as needed. This allows a Fortran program to be as large as 300k even though there's only a maximum of 32k memory. The standard library is quite large, so I assume by loading the FORLIB.RL manually, the sample session was showing how to turn it into an overlay module so that it's not eating up memory for the whole life of the program. I'm still not sure why it was named LIB.RL though, but since I'm not really wanting to concern myself with overlays, I'm happy to ignore this issue.
But in looking at this issue, I did actually end up resolving an earlier issue concerning subroutines and functions. I talk about the issue in two of my prior blogs: Random Linking Woes and Still learning, still haven't gotten anywhere. Basically to do a subroutine or function, each has to be defined as a separate module. But I couldn't figure out how to load these modules.
The problem really comes from the fact that I was using the COMPILE and EXECUTE commands. These are nice commands sort of built in to OS/8. They allow you to build and execute simple programs without knowing what you're doing. In essence, they're development shortcuts. Now I'm not opposed to such shortcuts, but as a professional developer now for more than two decades, I've always followed the rule that you should only use such shortcuts when you know what they're doing. If you don't, then when things screw up as they inevitably do, you don't know how to fix it. Unfortunately I didn't follow that rule with this project, so when I ran into issues with subroutines, I didn't really know how to get around it.
But this issue forced me to really break down and understand in more depth about how to build a Fortran app, and that's led me back to the solution for subroutines and functions. As I mentioned in yesterday's blog, there are 3 steps to building an application:
- Compile - The F4 utility
- Loading - The LOAD utility
- Execution - The FRTS utility
When you use the COMPILE command, it does the first step, but not the second or third. But the EXECUTE command does all three, and if successful, your app just "magically" runs without your really being aware of the steps involved. Unfortunately, EXECUTE doesn't seem to be a very intelligent command, so it doesn't seem to really know how to load separate modules. So it's perfectly good for simple applications, but not really useful for anything of any real size or complexity.
So let's assume you have a program with a MAIN.FT, a subroutine module SUB1.FT, and a function FUNC1.FT. We're going to assume that this will all be part of the main application segment; we'll keep things simple and not use any overlays. When building a Fortran application, you first use the F4 utility to build each module, like so:
.R F4
*PROG1<PROG1 <-- In OS/8, extensions are assumed so need them only if not standard
.R F4
*SUB1<SUB1
.R F4
*FUNC1<FUNC1
This produces an RL for each module. The next step is to load all the RL files:
.R LOAD
*PROG1<PROG1
*<SUB1,FUNC1
*$ <-- This is the ALTMODE key, which echoes as $ and is ESC in simh
Use TECO and you will become very familiar with this.
While I did the load in two lines above, it would have been equally valid to do them in one line with commas, or even in three separate lines. It doesn't make a difference.
Finally, you can execute PROG1.LD by:
.R FRTS
*PROG1
*$
And there you have it, all the steps to build a Fortran IV program on OS/8 complete with subroutines, functions, and whatever modules you want. To build in overlay support, as far as I know, all you have to do is do some more steps in LOAD. At that point, you could write a 300k Fotran program. But that's really beyond the scope of this blog - and of this project.
As a quick final note, the one issue I see with the above is that almost all of these steps has to be repeated every time you build the application. The only part you can skip is that you don't have to recompile a module if it hasn't changed, but otherwise everything above has to be done each time. Unfortunately, as far as I know, OS/8 doesn't have any way to automate this.
Monday, July 27, 2015
Time to write some code! Ok, maybe not quite yet...
So after nearly two weeks, I'm finally back to working on my project. First, I was waylaid for nearly a week with the flu, then I found myself tied up with real life (my least-favorite retro project ever). I will confess that I did also blow a few days on non-retro computer gaming, but now I'm back to see if I can wrap this up before the weekend. Unfortunately, with the way it's been going, I'm not optimistic.
As I indicated with my last post, I wanted to tackle the random number generator first. This seemed to be the biggest remaining hurdle, as I figured the rest of the coding would be pretty straightforward, but I really didn't expect it to take long. After doing a little research, I found that a linear congruent generator was probably my best bet. Mathematically, it's pretty simple.
Just multiplication, addition, and modular arithmetic. Now Fortran IV doesn't have a modulo operator (which surprised me a little, since math is supposed to be it's strong point), but it does have a MOD function in its standard library that takes two integers and returns a single integer. Excellent! Or so I thought...
When I tried to use it, I kept getting USER ERROR MAIN 0004 error. Obviously this isn't the most obvious error message ever, and I couldn't find specific information on that error, but I did finally track it down to the MOD function. Apparently it couldn't find the MOD function. Somewhat annoyingly, this doesn't occur in the compilation phase.
To understand, you have to appreciate how any but the most simple of computer applications are compiled. Whether you're dealing with a 50-year old PDP-8 or the latest computer, the basic steps are still the same. There are three basic phases: Compilation, linking/loading, and execution. For OS/8's Fortran IV system, they have F4 as their compiler, a utility called LOAD for loading, and then the FRTS (Fortran Run-Time System) program for linking and execution. Based on what I was seeing, I think they're using what we would today call Late Binding, because I got the error from the last phase, the FRTS utility. I don't recall seeing this term used in the Handbook, so I'm not sure what they would have called it in 1974 when it was written, but it basically means that external functions and subroutines are linked together at execution time rather than compile time (which would be called, not surprisingly, Early Binding).
So even though linking is done in the third phase, actual loading is done in the second phase with the LOAD utility. When doing so, you actually specify your output program, and then specify all the modules that go into it. Looking at a sample LOAD session in the Handbook, one of the modules that you include is the standard library. In the book, it says the standard library is contained in a file named FORLIB.RL, but in the example session they use LIB.RL instead. They have a comment explaining that they're using this name instead of FORLIB.RL, but give no indication why. In any case, after a quick search, neither file appears on the OS/8 hard disk image that I'm using. So I guess this is a slightly misconfigured installation of Fortran.
This leaves me with two options. First, I could try and locate FORLIB.RL and copy it to my system. Or, second, I could just write my own version of mod. Obviously, this isn't difficult, but I would like to be able to use the standard library. I don't really anticipate using it in any of the rest of my program, but it annoys me that I can't so I will at least take a stab at fixing the problem. But I don't really have that much time left, so if I don't fix it soon, I'll just write it myself.
As I indicated with my last post, I wanted to tackle the random number generator first. This seemed to be the biggest remaining hurdle, as I figured the rest of the coding would be pretty straightforward, but I really didn't expect it to take long. After doing a little research, I found that a linear congruent generator was probably my best bet. Mathematically, it's pretty simple.
Shamelessly stolen from Wikipedia entry for Linear Congruent Generator, entry linked above |
When I tried to use it, I kept getting USER ERROR MAIN 0004 error. Obviously this isn't the most obvious error message ever, and I couldn't find specific information on that error, but I did finally track it down to the MOD function. Apparently it couldn't find the MOD function. Somewhat annoyingly, this doesn't occur in the compilation phase.
To understand, you have to appreciate how any but the most simple of computer applications are compiled. Whether you're dealing with a 50-year old PDP-8 or the latest computer, the basic steps are still the same. There are three basic phases: Compilation, linking/loading, and execution. For OS/8's Fortran IV system, they have F4 as their compiler, a utility called LOAD for loading, and then the FRTS (Fortran Run-Time System) program for linking and execution. Based on what I was seeing, I think they're using what we would today call Late Binding, because I got the error from the last phase, the FRTS utility. I don't recall seeing this term used in the Handbook, so I'm not sure what they would have called it in 1974 when it was written, but it basically means that external functions and subroutines are linked together at execution time rather than compile time (which would be called, not surprisingly, Early Binding).
So even though linking is done in the third phase, actual loading is done in the second phase with the LOAD utility. When doing so, you actually specify your output program, and then specify all the modules that go into it. Looking at a sample LOAD session in the Handbook, one of the modules that you include is the standard library. In the book, it says the standard library is contained in a file named FORLIB.RL, but in the example session they use LIB.RL instead. They have a comment explaining that they're using this name instead of FORLIB.RL, but give no indication why. In any case, after a quick search, neither file appears on the OS/8 hard disk image that I'm using. So I guess this is a slightly misconfigured installation of Fortran.
This leaves me with two options. First, I could try and locate FORLIB.RL and copy it to my system. Or, second, I could just write my own version of mod. Obviously, this isn't difficult, but I would like to be able to use the standard library. I don't really anticipate using it in any of the rest of my program, but it annoys me that I can't so I will at least take a stab at fixing the problem. But I don't really have that much time left, so if I don't fix it soon, I'll just write it myself.
Tuesday, July 14, 2015
Still learning, still haven't gotten anywhere
So we're about half-way through the Retrochallenge and I've still gotten nowhere on my actual project. I've written a Hello World and struggled with doing a guessing game, but haven't actually written any code for the game I am supposed to be working on, my Hammurabi clone.
I don't feel too bad about this though because I have learned a lot. I knew coming in to this project that the code wasn't really my obstacle, it was getting to the point where I could write the code. The issue for me at the moment is that while I could just knock out the program in Fortran, I want to do it in a maintainable, structured fashion. Since I want to actually extend the program beyond just the simple model of Hammurabi, I want to have a code base that will be easily modifiable. But neither Fortran nor developing in a line editor is conducive to this. OS/8's Fortran IV does have support for subroutines and functions, but as far as I can tell these have to be in separate files and used as overlays. Or you can build a library. I spent quite a bit of time getting the overlays to work, with no success, and I didn't even want to try building a library yet. So I guess I'll be using GO TO's instead of subroutines and functions.
Well, you can still do good structured programming using GO TO's as long as your careful and disciplined, which is where TECO, a line editor, becomes an issue. Line editors are good enough git stfor making quick changes in small files, but really horrendous for making big changes in big files. So I had hoped to make my program out of bunch of small files, which is what led me down the overlay rabbit hole I mentioned above.
But it turns out there's an even easier solution, which I had read about but I guess just wasn't clear to me. You can execute the following command:
.COMPILE FILE1.FT,FILE2.FT,FILE3.FT
This appears to actually just merge all the files into one big one and then compile that into a program. Now this does present the limitation that my program can't be larger than, I believe, 30k, but I really don't see Prince (the name of my Hammurabi clone) exceeding that. But being able to break the code up into multiple files will make a editing the code though, so this is a pretty big deal for me.
Another little thing I discovered is also the @ notation for command line parameters. Basically you can specify your parameters in a file and then have the Command Decoder read the parameters from the file. That way you're not typing the file list in over and over.
So you could just create a file, say FILES.CM, with the text:
FILE1.FT,FILE2.FT,FILE3.FT
And then you just call the COMPILE command like so:
.COMPILE @FILES.CM
This is equivalent to the first command and should make building the multi-file project a lot easier.
So now I think I can finally get to writing my game, starting with the random number generator first.
I don't feel too bad about this though because I have learned a lot. I knew coming in to this project that the code wasn't really my obstacle, it was getting to the point where I could write the code. The issue for me at the moment is that while I could just knock out the program in Fortran, I want to do it in a maintainable, structured fashion. Since I want to actually extend the program beyond just the simple model of Hammurabi, I want to have a code base that will be easily modifiable. But neither Fortran nor developing in a line editor is conducive to this. OS/8's Fortran IV does have support for subroutines and functions, but as far as I can tell these have to be in separate files and used as overlays. Or you can build a library. I spent quite a bit of time getting the overlays to work, with no success, and I didn't even want to try building a library yet. So I guess I'll be using GO TO's instead of subroutines and functions.
Well, you can still do good structured programming using GO TO's as long as your careful and disciplined, which is where TECO, a line editor, becomes an issue. Line editors are good enough git stfor making quick changes in small files, but really horrendous for making big changes in big files. So I had hoped to make my program out of bunch of small files, which is what led me down the overlay rabbit hole I mentioned above.
But it turns out there's an even easier solution, which I had read about but I guess just wasn't clear to me. You can execute the following command:
.COMPILE FILE1.FT,FILE2.FT,FILE3.FT
This appears to actually just merge all the files into one big one and then compile that into a program. Now this does present the limitation that my program can't be larger than, I believe, 30k, but I really don't see Prince (the name of my Hammurabi clone) exceeding that. But being able to break the code up into multiple files will make a editing the code though, so this is a pretty big deal for me.
Another little thing I discovered is also the @ notation for command line parameters. Basically you can specify your parameters in a file and then have the Command Decoder read the parameters from the file. That way you're not typing the file list in over and over.
So you could just create a file, say FILES.CM, with the text:
FILE1.FT,FILE2.FT,FILE3.FT
And then you just call the COMPILE command like so:
.COMPILE @FILES.CM
This is equivalent to the first command and should make building the multi-file project a lot easier.
So now I think I can finally get to writing my game, starting with the random number generator first.
Sunday, July 12, 2015
Random linking woes
I don't have a whole lot to report. I started to build a simple guess-the-number game, just as an instructive exercise, and this opened up a bit of a can of worms. It started with random numbers. Since you have to guess what number the computer is thinking of, the computer has to generate a random number. But as far as I can tell, this version of Fortran doesn't have a random number generator. This makes sense, since I don't think the language designers envisioned games being developed on the PDP-8, but it means I have to develop a random number generator. I've never done this before, and math is definitely not my strong suit, but I figured it wouldn't be too much of a problem. I'm not looking for a perfect random generator, so I figured I could just find a relatively simple algorithm that I could translate to Fortran IV.
But that wasn't what actually proved to be my big obstacle for today. It was calling an external function. I built a simple shell of a function in a separate Fortran file, with the understanding that I could link them together, but I haven't gotten it to work yet. This will be a problem for me, because even with my relatively small game, I had envisioned breaking it up into several modules. I think EDIT and TECO will get too cumbersome with large source files, so I really want to keep the files relatively small.
So that's my immediate task, to figure out how to link modules together so that I can call subroutines and functions from one module in another. The OS/8 Handbook seems to indicate that I can, but I don't see how to actually do it. So I've downloaded the OS/8 Fortran Software Support Manual (I know, why didn't I download this before) and hope it will provide me with some answers.
But that wasn't what actually proved to be my big obstacle for today. It was calling an external function. I built a simple shell of a function in a separate Fortran file, with the understanding that I could link them together, but I haven't gotten it to work yet. This will be a problem for me, because even with my relatively small game, I had envisioned breaking it up into several modules. I think EDIT and TECO will get too cumbersome with large source files, so I really want to keep the files relatively small.
So that's my immediate task, to figure out how to link modules together so that I can call subroutines and functions from one module in another. The OS/8 Handbook seems to indicate that I can, but I don't see how to actually do it. So I've downloaded the OS/8 Fortran Software Support Manual (I know, why didn't I download this before) and hope it will provide me with some answers.
Friday, July 10, 2015
Moving to the Raspberry Pi
I don't actually have a whole lot to report today, as I was busy with other stuff. As a result of this other stuff, I was going to be away from my computer, but I still had some time to code. Up to this point, I've been running the simh PDP-8 emulator locally on my iMac desktop, but as I said I wouldn't be at my desktop. Now, of course, I could have just remoted in from my MacBook Pro, but I decided to move my simh instance out to a Raspberry Pi so I could connect to it from any of my computers.
The other reason I wanted to do this is for the PiDP-8. You may recall me mentioning it in an earlier post. It's a recreation of a PDP-8/I with a Raspberry Pi serving as the brains, and it's being sold as a kit. I've actually opted to wait for an assembled unit in October, given that my current situation isn't conducive to hardware projects, but I'm very anxious to get my hands on it. As I said, it was part of the inspiration for this project. In any case, the kit's maker has released the software package that he's using so anybody can download and use it. As he readily admits, it's really just simh anyway. Of course, I could have just downloaded simh and built it on the Pi myself, but if someone's done the work for me already, why bother? Besides, the kit requires that you supply your own RPi, so I can just plug this one and continue using it when my unit finally arrives. So now I have a Raspberry Pi 2 on my network that I can ssh to from any machine and find myself in OS/8.
The other thing I did was to move my development files off of the main system drive and onto a floppy. Especially as I get more and more files, having a dedicated storage device will make things easier I think, and OS/8 doesn't have support for directories where I can isolate my stuff. I'd thought about just attaching a second hard drive, but I decided to go with the floppy once again because of the PiDP-8. One of the features it is supposed to have is to auto-mount removable media such as paper tapes and floppies - we're talking about images, of course. You put them on a USB stick and when it's plugged in and you flip a few switches, the PiDP-8 will search the USB devices and auto-mount whatever images it finds. It just loads the first image on the USB device, so you really have to have a single USB stick per image. But that kind of appeals to me anyway. I can buy a bunch of cheap, low-capacity USB sticks and then swap them out as needed - kind of like they actually were floppies or tapes.
Hopefully in the next day or two, I'll start getting into more productive Fortran coding.
The other reason I wanted to do this is for the PiDP-8. You may recall me mentioning it in an earlier post. It's a recreation of a PDP-8/I with a Raspberry Pi serving as the brains, and it's being sold as a kit. I've actually opted to wait for an assembled unit in October, given that my current situation isn't conducive to hardware projects, but I'm very anxious to get my hands on it. As I said, it was part of the inspiration for this project. In any case, the kit's maker has released the software package that he's using so anybody can download and use it. As he readily admits, it's really just simh anyway. Of course, I could have just downloaded simh and built it on the Pi myself, but if someone's done the work for me already, why bother? Besides, the kit requires that you supply your own RPi, so I can just plug this one and continue using it when my unit finally arrives. So now I have a Raspberry Pi 2 on my network that I can ssh to from any machine and find myself in OS/8.
The other thing I did was to move my development files off of the main system drive and onto a floppy. Especially as I get more and more files, having a dedicated storage device will make things easier I think, and OS/8 doesn't have support for directories where I can isolate my stuff. I'd thought about just attaching a second hard drive, but I decided to go with the floppy once again because of the PiDP-8. One of the features it is supposed to have is to auto-mount removable media such as paper tapes and floppies - we're talking about images, of course. You put them on a USB stick and when it's plugged in and you flip a few switches, the PiDP-8 will search the USB devices and auto-mount whatever images it finds. It just loads the first image on the USB device, so you really have to have a single USB stick per image. But that kind of appeals to me anyway. I can buy a bunch of cheap, low-capacity USB sticks and then swap them out as needed - kind of like they actually were floppies or tapes.
Hopefully in the next day or two, I'll start getting into more productive Fortran coding.
Thursday, July 9, 2015
It's TECO Time!
Although it took some time, I have more or less figured out EDIT. But I also realize that writing any sizable amount of code in it is going to be painful. So I decided it was time to look at TECO, OS/8's other built-in editor. I looked over the section in the OS/8 Handbook, fired it up, and tried it out on my Hello World program.
While TECO is a lot more powerful than EDIT, it's also a lot more complex. And it was made even more so by the OS/8 Handbook, which turned out to just be wrong or incomplete. Even just loading a file was a major chore. According to the Handbook, you start up the editor with the command RUN TECO. This will give you the * prompt, at which point you type in either ERHELLO.FT$EWHELLO1.FT$$ or something like that. (One peculiar thing about TECO is that you have to hit the Escape key a lot, and this echoes on the screen as a $. So the command above is actually ERHELLO.FT<esc>EWHELLO1.FT<esc><esc>. Commands are always terminated with 2 Escape presses.) This is supposed to open HELLO.FT for reading, and HELLO1.FT for writing. It was annoying, because I would have to make a copy of my source file every time, but c'est la vie.
Well, as it turned out, I tried a number of variations of this command and none of them worked. After a quick Google I found both TECO's Wikipedia entry and especially the TECO Pocket Guide to be much more helpful. It turns out there's a simpler command, EBHELLO.FT$Y$$, which opens HELLO.FT for read/write and even creates a backup. Not really sure what the Y is for, but it seems to need it to work. So to open an existing file to edit:
.RUN TECO
*EBHELLO.FT$Y$$
But The TECO Pocket guide actually provided an even simpler way, which is the equivalent of the above:
.TECO HELLO.FT
If only the Handbook had given me that...
I have similarly found other commands that the Handbook was wrong about, so I've decided to rely on the Pocket Guide for commands. The Handbook might still be useful for TECO concepts, so I'm going to continue reading through the rather large section, but refer to the Pocket Guide as I'm actually using it.
Btw, even if you have no interest in using TECO (and unless you're working on a PDP-8 or similar computer, I can't see why you would), reading the Wikipedia entry is still interesting. Apparently TECO started with the PDP-1, not the PDP-8, and the famous Emacs actually started out as a set of macros for TECO until it was developed as a stand-alone editor.
Wednesday, July 8, 2015
Hello world!
I wrote and compiled my first Fortran program, the venerable Hello World program. Not surprisingly, it isn't long or complex, but the main purpose of the exercise was really to figure out how to write, compile, and execute a Fortran program. It was not a simple as I would have liked, but as the image shows, I did figure it out.
The first obstacle was just to create the program itself. OS/8 has two built-in editors, Edit and TECO. Both are line editors, that is, you basically work on a single line of text at a time. You have to set which line you're working with, then make your changes, then move to the next one. Fortunately, when you're creating a new file, you enter Append mode and you just type your text, so it's not much different than using a full-screen editor. But once you have to make a change, then the pain begins. I can see why programmers would write out their programs on paper forms first. Writing a program using a screen editor is a fairly interactive experience. You write some code, go back and make a quick edit, add lines in the middle, go to the bottom of the file and add a new function, return to where you started, etc. While you can do all this in a line editor, it is much more difficult. And Edit poses another problem: You can only work on one buffer at a time, and the buffers are only 3000 characters in length. So to move around in the file, for example, you'd have to write the current buffer, then read in the buffer that contains the location you want to go to.
I also ran into a bit of a problem with Edit on simh, specifically with keyboard mapping. Edit has two modes, Command and Edit. Command (designated by a leading # on the line) let's you do stuff like save/load buffers, delete lines, etc. Edit mode is for entering text, and obviously it treats whatever you type as text to be saved in the file. When you're done entering text, you have to switch back to Command mode, and according to the OS/8 handbook, you do this with the Ctrl-FORM key combo. But there is no FORM key, of course. I tried Ctrl with a bunch of keys - Home, End, Delete, etc. - but none of them worked. I finally found a blog Editing Files on a PDP-8 Using OS/8 EDIT where the guy was doing a lot of what I'm doing now, playing with OS/8 using the simh emulator. It was here that I found out that Ctrl-L will switch from Edit to Command mode. I'll probably start taking a look at TECO to see if it's any better.
It was actually trying to figure out Edit that took me the most time in getting my HELLO program to run, but it wasn't the only issue. The aforementioned blog also had a very nice post on writing Hello World in Fortran, including going through the steps of compiling and executing the program, but unfortunately this turned out not to work on my system. OS/8 has a command called COMPILE that, as you might have already guessed, compiles programs. But this command isn't specific to Fortran - it compiles any of the native OS/8 languages: the three or four assembly languages; Fortran II; and Fortran IV. It uses the source file's extension to figure out what actual compiler to invoke, and then runs it through the whole chain of programs (Fortran IV, for example, uses four or five separate programs to do a full compilation). But I recall reading in the OS/8 Handbook that the COMPILE command will only work if the compiler was installed at the time the system was setup. As the blogger indicates, his Fortran was not working when he first tried it, so he had to go and install it manually on his OS/8 system. So I assume this is why COMPILE did not work for him. Instead, he had to invoke the Fortran compiler directly using the command, RUN F4. So I did this, and while the command itself gave me no errors, the resulting HELLO.LD file would not run as his did when I did, EXECUTE HELLO. But my COMPILE did work, and it generated a HELLO.RL file which did work with the EXECUTE command, as shown above.
So I got the basic steps down, which means I can move on to actually writing my game. And on that front as well I have a little news - I have decided to write Hammurabi. For those who aren't familiar with it, this is a pretty simple game (usually written in BASIC) where the player has to rule a small kingdom, feed his people, plant crops, and try and keep everyone from starving (usually eventually failing). I remember having a lot of fun with it back in the day when I was a teenager. Unfortunately, it really does have a pretty simple strategy, and you'll either win or lose based mostly on luck. But I'm hoping to add features that will change that while hopefully still maintaining the essence of the game. But first, I just want to implement the basic game, so that's next.
The first obstacle was just to create the program itself. OS/8 has two built-in editors, Edit and TECO. Both are line editors, that is, you basically work on a single line of text at a time. You have to set which line you're working with, then make your changes, then move to the next one. Fortunately, when you're creating a new file, you enter Append mode and you just type your text, so it's not much different than using a full-screen editor. But once you have to make a change, then the pain begins. I can see why programmers would write out their programs on paper forms first. Writing a program using a screen editor is a fairly interactive experience. You write some code, go back and make a quick edit, add lines in the middle, go to the bottom of the file and add a new function, return to where you started, etc. While you can do all this in a line editor, it is much more difficult. And Edit poses another problem: You can only work on one buffer at a time, and the buffers are only 3000 characters in length. So to move around in the file, for example, you'd have to write the current buffer, then read in the buffer that contains the location you want to go to.
I also ran into a bit of a problem with Edit on simh, specifically with keyboard mapping. Edit has two modes, Command and Edit. Command (designated by a leading # on the line) let's you do stuff like save/load buffers, delete lines, etc. Edit mode is for entering text, and obviously it treats whatever you type as text to be saved in the file. When you're done entering text, you have to switch back to Command mode, and according to the OS/8 handbook, you do this with the Ctrl-FORM key combo. But there is no FORM key, of course. I tried Ctrl with a bunch of keys - Home, End, Delete, etc. - but none of them worked. I finally found a blog Editing Files on a PDP-8 Using OS/8 EDIT where the guy was doing a lot of what I'm doing now, playing with OS/8 using the simh emulator. It was here that I found out that Ctrl-L will switch from Edit to Command mode. I'll probably start taking a look at TECO to see if it's any better.
It was actually trying to figure out Edit that took me the most time in getting my HELLO program to run, but it wasn't the only issue. The aforementioned blog also had a very nice post on writing Hello World in Fortran, including going through the steps of compiling and executing the program, but unfortunately this turned out not to work on my system. OS/8 has a command called COMPILE that, as you might have already guessed, compiles programs. But this command isn't specific to Fortran - it compiles any of the native OS/8 languages: the three or four assembly languages; Fortran II; and Fortran IV. It uses the source file's extension to figure out what actual compiler to invoke, and then runs it through the whole chain of programs (Fortran IV, for example, uses four or five separate programs to do a full compilation). But I recall reading in the OS/8 Handbook that the COMPILE command will only work if the compiler was installed at the time the system was setup. As the blogger indicates, his Fortran was not working when he first tried it, so he had to go and install it manually on his OS/8 system. So I assume this is why COMPILE did not work for him. Instead, he had to invoke the Fortran compiler directly using the command, RUN F4. So I did this, and while the command itself gave me no errors, the resulting HELLO.LD file would not run as his did when I did, EXECUTE HELLO. But my COMPILE did work, and it generated a HELLO.RL file which did work with the EXECUTE command, as shown above.
So I got the basic steps down, which means I can move on to actually writing my game. And on that front as well I have a little news - I have decided to write Hammurabi. For those who aren't familiar with it, this is a pretty simple game (usually written in BASIC) where the player has to rule a small kingdom, feed his people, plant crops, and try and keep everyone from starving (usually eventually failing). I remember having a lot of fun with it back in the day when I was a teenager. Unfortunately, it really does have a pretty simple strategy, and you'll either win or lose based mostly on luck. But I'm hoping to add features that will change that while hopefully still maintaining the essence of the game. But first, I just want to implement the basic game, so that's next.
Monday, July 6, 2015
Finished My Reading Assignment
I haven't made any posts since my first, but that doesn't mean I've been inactive. Since my project involves a computer, an operating system, and a programming language that I don't know, I've been doing a lot of reading, specifically the OS/8 Handbook, which I finished yesterday. This is a rather large tome (954 pages), but I skipped a number of sections that I didn't really need: How to setup the PDP-8 and the sections on the several assemblers, for instance. Since I'm using a prebuilt OS/8 image and I'm doing my game in Fortran, I don't really need those sections.
The Fortran section was interesting. Being completely unfamiliar with the language, it was certainly interesting. It is a curious language, at least to one like me who only has experience with more modern languages. Honestly, it seems very different than anything I've worked with before. C, BASIC, or Pascal (not sure which came first) are probably the oldest languages I've ever worked with, so I had to wonder if some of the clunkier aspects of Fortran are common to languages designed in that era. I was surprised to see a number of interesting features though. For instance, you can define a line identifier (just a number), and you would use that in your flow control statement (GO TO or IF, for example). The cool thing about this, though, is that you can actually create a variable representing a line identifier (even though it's a number, it is distinct from other numeric types), and you can manipulate it mathematically. The most surprising thing to me, though, is that it allows function references to be passed as parameters. I realize that this is not particularly new, but it is a feature I wasn't really expecting with Fortran for some reason.
One curious aspect is that Fortran supports overlaying, meaning that it can swap out parts of the program with modules on disk. So you can build a program as large as 300k to run in a 32k system. This sort of system makes perfect sense, of course, but I'm curious why a limit of 300k? It seems like you should really only be limited by the size of your storage media.
So having finished this book, my next step is to do "Hello World" in Fortran. This will hopefully start getting me used to Edit or Teco (not sure which I'll use) and how to build and run a Fortran program. And lest you think I'm done reading, I'm moving on to another PDP-8 introductory handbook, this one I think more focused on the PDP-8 itself and less on OS/8.
As a final note, I wanted to acknowledge Oscar Vermeulen, the man behind the PiDP-8/I kit. Although the kit hasn't come out yet (and I've decided to wait several months until he has fully assembled units available), reading about his project and the thought of having a "real" PDP-8 has helped to stimulate my interest in the PDP-8. And his web page, documentation, and software have helped me with this project. If you're not familiar with his kit, definitely go take a look.
The Fortran section was interesting. Being completely unfamiliar with the language, it was certainly interesting. It is a curious language, at least to one like me who only has experience with more modern languages. Honestly, it seems very different than anything I've worked with before. C, BASIC, or Pascal (not sure which came first) are probably the oldest languages I've ever worked with, so I had to wonder if some of the clunkier aspects of Fortran are common to languages designed in that era. I was surprised to see a number of interesting features though. For instance, you can define a line identifier (just a number), and you would use that in your flow control statement (GO TO or IF, for example). The cool thing about this, though, is that you can actually create a variable representing a line identifier (even though it's a number, it is distinct from other numeric types), and you can manipulate it mathematically. The most surprising thing to me, though, is that it allows function references to be passed as parameters. I realize that this is not particularly new, but it is a feature I wasn't really expecting with Fortran for some reason.
One curious aspect is that Fortran supports overlaying, meaning that it can swap out parts of the program with modules on disk. So you can build a program as large as 300k to run in a 32k system. This sort of system makes perfect sense, of course, but I'm curious why a limit of 300k? It seems like you should really only be limited by the size of your storage media.
So having finished this book, my next step is to do "Hello World" in Fortran. This will hopefully start getting me used to Edit or Teco (not sure which I'll use) and how to build and run a Fortran program. And lest you think I'm done reading, I'm moving on to another PDP-8 introductory handbook, this one I think more focused on the PDP-8 itself and less on OS/8.
As a final note, I wanted to acknowledge Oscar Vermeulen, the man behind the PiDP-8/I kit. Although the kit hasn't come out yet (and I've decided to wait several months until he has fully assembled units available), reading about his project and the thought of having a "real" PDP-8 has helped to stimulate my interest in the PDP-8. And his web page, documentation, and software have helped me with this project. If you're not familiar with his kit, definitely go take a look.
Subscribe to:
Posts (Atom)