• Please review our updated Terms and Rules here

What did I do to my PDP-8 today.

BASIC.UF is an optional file that contains any user written/defined functions that you want to be able to access from your BASIC program.
It don't even need to exist.

I wonder - this serial disk thing... Do people know/understand how things work in OS/8 enough to add a new device properly? Does the serial disk appear to look like an exsting device (like the RK05)? Does it then also have all the signatures of that driver, so that other programs like PIP understands it? PIP have a list of all known devices, along with the size of each one, so that a zero of the device creates a proper directory mapping all of the disk. RESORC is another program that actually knows more about devices, and also picks through the device driver to figure out what device it is.
There might be a few more, I can't really remember. But it's not enough to just write a device driver if it is for a device that is supposed to have a file structure on it.
OS/8 is a little primitive in that way. Not enough information is kept around in some common place. Instead various programs that needs extra information have it in themselves...
 
I wonder - this serial disk thing... Do people know/understand how things work in OS/8 enough to add a new device properly?
Kyle figured most of it out when he wrote it. I wrote a handler in 1976 and it was a major pain because I didn't have enough of the documentation and I had no sources to look at. I had to reverse engineer the handlers we used. It is for this reason that I have been working on a book that details OS/8 ( and of course PS/8 ) handlers. I will be getting back to that soon.
Does the serial disk appear to look like an existing device (like the RK05)?
Kyle chose to use the RK05 geometry so that disk images could be directly mounted. For SYS the device type name is SDSK with three entry points supported. SYS of course and SDA0 and SDB0. There is a table of device codes that RESORC uses. The codes from 000 to 037 are allocated to DEC devices and the range of codes from 040 to 077 are for user defined devices. Kyle chose to use 64. I don't know why but it really doesn't matter. The other critical thing in a block structured handler is the entry point word. For DEC devices there are specific places where the entry points need to be for that device. For user defined handlers this is not important except that all handler entry points in a system must be unique. The best reason I could find for this is that the USR caches the last directory entry read from a device and it keeps track of this using the entry point somehow. If two entry points in different handlers have the same relative offset then the USR could use the other devices directory and chaos will ensue. Kyle also wrote boot code which build will place on an image and allow you to boot. I believe Roland's boot board has the boot0 code but you could toggle it in if you wanted to. I punched it in once on my 8/a.
For the Non-sys handler it is also called SDSK with four devices supported. SDA0, SDA1, SDB0 and SDB1. I have a version of serial disk that Charles Lasner massaged which allows for 8 entry points but I don't think anyone has ever tried it. To do so would require changes to the server. I started making changes but it was not an easy change to make on the existing code so I decided to write it over from scratch with 8 devices in mind.

Does it then also have all the signatures of that driver, so that other programs like PIP understands it? PIP have a list of all known devices, along with the size of each one, so that a zero of the device creates a proper directory mapping all of the disk. RESORC is another program that actually knows more about devices, and also picks through the device driver to figure out what device it is.
No. PIP would need to be patched in order to understand how to zero this device correctly. There are instructions about this in one of the DEC documents. I will need to put this info in my book.

My temptation would be to reuse the RK05 device names and handler entry points so that PIP would not need to be patched. This fails spectacularly if you also want to have a real RK05 on your machine at the same time. That is not an issue with the chosen naming scheme.

If you are interested the serial disk sources are on github.

Here is a link to the google doc of my book as it currently stands. OS/8 handler info
I have not inserted many of the example handlers as I am still working on and testing them. Comments and criticism are welcome!
 
Wasn't someone asking somewhere recently about 101 BASIC Computer Games?

Since I had become aware of it and now it became feasible for me to do it reasonably, I have reconstructed
DECUS-BASIC8-55. Which is to say, you can find the games here:
http://svn.so-much-stuff.com/svn/trunk/pdp8/src/decus/basic8-55
You can also get there from http://so-much-stuff.com/pdp8/software/decus.php#decus-basic8-1 by scrolling down a bit.

Some of the source documents were mangled, so I had to do some repairs. Only zoop is completely reconstructed (from the OCR) though, so I think all or almost all of it is in good shape now. They came from OS/8 media, so I think they should run there.

I used the manual to determine which were missing, so there are programs there not listed in the abstract. Mostly alternate versions -- salvo and salvo1, etc., where they seem to have lost the alternate from the abstract.

Vince
 
The palbart suite comes with a script to fire up SIMH and extract the binary produced by PAL8, and it comes with "correct" binaries allegedly produced this way. I'm not sure all the binaries actually come from the script, as even in the "good" directory, some of those reference binaries are "off" in subtle ways that I wouldn't have expected from PAL8. Then there's another script to run palbart and see if they get the same answer, and if so, the case goes in the "good" directory, otherwise it goes in the "bad" directory.

Vince

I checked. I get identical binaries rerunning my scripts. I did find a couple listing were from edited version of the .pa file where the edits changed the listing but not the binary. Files updated. I wouldn't expect the problem to be simh. Could be what version of pal is used.

http://www.pdp8online.com/ftp/software/palbart/
 
@DougIngram “For the Non-sys handler it is also called SDSK with four devices supported. SDA0, SDA1, SDB0 and SDB1. I have a version of serial disk that Charles Lasner massaged which allows for 8 entry points but I don't think anyone has ever tried it. To do so would require changes to the server. I started making changes but it was not an easy change to make on the existing code so I decided to write it over from scratch with 8 devices in mind.”

In fact I did the 8 entry point non-sys handler which Charles subsequently modified to run on a non-omnibus machine (which I tried to do by simply replacing the BSWs with rotates but it needed more expertise). More or less a hack of the standard DEC multiple-entry-servicing code. I also modded the sys handler to have 4 entries (equivalent to 2xRK05) which for most purposes minimises the number of handlers that need to be in memory simultaneously. The changes to the server side were minimal I thought - only really a matter of replicating the code which recognises which ID the handler has requested and associated file pointers. I use it as standard - works fine.
 
Last edited:
@DougIngram “For the Non-sys handler it is also called SDSK with four devices supported. SDA0, SDA1, SDB0 and SDB1. I have a version of serial disk that Charles Lasner massaged which allows for 8 entry points but I don't think anyone has ever tried it. To do so would require changes to the server. I started making changes but it was not an easy change to make on the existing code so I decided to write it over from scratch with 8 devices in mind.”

In fact I did the 8 entry point non-sys handler which Charles subsequently modified to run on a non-omnibus machine (which I tried to do by simply replacing the BSWs with rotates but it needed more expertise). More or less a hack of the standard DEC multiple-entry-servicing code. I also modded the sys handler to have 4 entries (equivalent to 2xRK05) which for most purposes minimises the number of handlers that need to be in memory simultaneously. The changes to the server side were minimal I thought - only really a matter of replicating the code which recognises which ID the handler has requested and associated file pointers. I use it as standard - works fine.

This means you must be Bob Adamson per the Charles comments. Thanks for setting me straight. The version found on Github is still the 4 device one from Dec 24 of 2015. Is there another repository with your updates?

I just went back and re-read Charles revisions history. He mentions that you did the update to 4 devices but nowhere is the 8 device support mentioned. I just assumed that Charles did that. Sorry about that.

At some point I will be uploading my modified version and I would hate to leave out your contributions. My version does 3 byte to 2 word mapping over the serial port making it 25% faster. But it has not been tested because this requires the more significant changes to the server side. It was this more than the increase to 8 devices which prompted the rewrite. To clarify, in some places you need to still do the current dual six bit transfers and during the large block transfers the server has to do the two words to three byte packing and three byte to two word unpacking. Unfortunately, the SYS handler has to be quite a bit shorter and there simply isn't enough room to add the packing and unpacking operations. A one page non sys handler is 128 words while the sys handler loses 7 words from the front (down to 121) and 28 words from the end making it have to fit in 93 words. A sys handler can use the data break addresses (7750-7755) for non-persistent temporary storage. What this means to the server is that it has to treat SYS and NON-SYS requests differently. And boot would need to be treated the dual 6 bit way until the transition to the boot2 code loaded from the server. And I wanted the new server to be compatible with the old handlers. So it would need to recognize different wake up codes to identify the handler.

Best Wishes!
 
Thanks Doug, yes that’s me. I don’t have a GitHub account so my hacks emerged first to Michael Thompson to try on the 8/i when he’d failed to get SerialDisk to work on it, and thence to CJL when they didn’t work. If you’re intending to cope with pre-omnibus machines, which would be good, you need to follow CJL’s stuff as (I believe) the TTY I/O stuff needed consideration as well as simply avoiding BSWs.

As an aside I also rewrote a version to operate with the 8/a parallel port which is very quick, but I’ve since sold my 8/a on so that one’s been discontinued as it was model specific. I’ve had intermittent errors trying to run the serial interface (perhaps too) fast although the Raspberry Pi I serve from is only a foot or so from the M8650. I’ve put an extra command (Q) in the server code to allow the pdp8 to shut the pi down cleanly.

Lastly I notice your comments on ^C handling in your write up. I tried for a while to handle it in SerialDisk but had to give up in the end because the handshaking requires both ends to agree that they’re aborting which was just too awkward. I feel it’s untidy to need to rely on the front panel to escape from a software hang.

Bob
 
I don’t have a GitHub account so my hacks emerged first to Michael Thompson to try on the 8/i when he’d failed to get SerialDisk to work on it, and thence to CJL when they didn’t work.

We have been using the non-Omnibus serialdisk on a PDP-12 for quite a while on a 9600 baud serial interface. Works just fine.
 
We have been using the non-Omnibus serialdisk on a PDP-12 for quite a while on a 9600 baud serial interface. Works just fine.

Am I being extra thick today, or is there some other repository than Kyle's in which these changes can be found? (I don't see them in Kyle's github.)

Vince
 
is there some other repository than Kyle's in which these changes can be found? (I don't see them in Kyle's github.)

I had a conversation with Kyle, and found a copy of both revisions that Michael had sent me some months ago. I'm thinking I should just coordinate with Kyle to make them gnerally available?

Bob, are you OK with that?

Michael, are you still having the interrupt interaction with Fortran on your 8/I? According to my reading of the code you would be.

Vince
 
I think that the interrupt issue was on the PDP-12, so that behavior should be common to many of the PDP-8s.

Sure. I think I know how to fix that. I'm working to install CJL's revision "H" drivers on SIMH. I believe that driver will still crash the FORTRAN run-time unless you happen to be on an Omnibus machine (or SIMH). I believe a two line change would make it work properly on any family-of-eight machine, and possibly even on the 8/S (if you could find or create one with enough memory).

Anyway, I don't at the moment have an operational OS/8 pre-Omnibus machine to test things on, so maybe I could send you a fix to test? (Kyle has indicated he's willing to pull code if it has been tested.)

Vince
 
My understanding of the Fortran run time issue is that Fortran runs with interrupts enabled. The serial ports on omnibus machines wake up so they will cause an interrupt when used by default. Fortran would catch the interrupt caused by the first character received from the serial disk server and wig out because it doesn't know what to do with it. The patch was to add the instruction to disable interrupt generation on the serial disk serial port. The RKIE (6405) needs to be executed to disable interrupt generation on a character received from the Serial disk server. The problem with using RKIE on pre Omnibus machines is that they don't know what that instruction is and it gets interpreted as the Skip if character received and read buffer command combined. Not a usual combination. If there happened to be a character in the buffer it would skip the next instruction. The way this got made sort of safe was to place a harmless constant after the RKIE. That way if it skipped it was fine on the pre-omnibus machines.

The only operating pre-omnibus machine I have does not have a second serial port so no way to test there. I guess the 8/i doesn't have a second serial port either so even if it was working...

I have the version found on github (Non sys is version D and SYS is version E) which does not have this patch and I have the version that Charles worked over (Version G) but I don't have a server for that one. Where do I go to download the version that Bob did with the server before Charles worked on it. And it sounds like Vince has Version H?

I agree with Vince that the changes I have seen will not address the issue on pre-omnibus machines. There was no provision to disable interrupt generation on a per device basis on the older machines. This makes me curious as to what Vince has in mind for a fix.
 
My understanding of the Fortran run time issue is that Fortran runs with interrupts enabled. The serial ports on omnibus machines wake up so they will cause an interrupt when used by default. Fortran would catch the interrupt caused by the first character received from the serial disk server and wig out because it doesn't know what to do with it.

Almost. What I believe is happening is that Fortran disables interrupts, calls the driver, then enables interrupts after the return. The issue, then, is that when the interrupts get re-enabled, there is an output completion flag set from the last character sent from the driver to the serialdisk server. This triggers and interrupt, which Fortran doesn't have handler code for. When the Fortran interrupt routine returns, the flag is still set, the interrupt recurrs, and the system is hung (except maybe for servicing other interrupts, which would still happen).

The patch was to add the instruction to disable interrupt generation on the serial disk serial port. The RKIE (6405) needs to be executed to disable interrupt generation on a character received from the Serial disk server. The problem with using RKIE on pre Omnibus machines is that they don't know what that instruction is and it gets interpreted as the Skip if character received and read buffer command combined. Not a usual combination. If there happened to be a character in the buffer it would skip the next instruction. The way this got made sort of safe was to place a harmless constant after the RKIE. That way if it skipped it was fine on the pre-omnibus machines.

Yeah, the RKIE is just the wrong way to go about it. The "family of eight" way is to not return from the serialdisk driver with flags set. The input flag should not be troublesome, as presumably the server does not send input without being asked. The correct fix, I believe, is to remove the RKIE instruction near the beginning, and instead execute an STCF instruction prior to the return. This is the "2 line fix" I mentioned before. None of the extant serialdisk drivers do that, but it should be an easy change.

In principal, there's a NOP later after an ISZ, where that inline constant could go, which would likely save a word. No too important as there are several words to spare at the moment.

The only operating pre-omnibus machine I have does not have a second serial port so no way to test there. I guess the 8/i doesn't have a second serial port either so even if it was working...
So maybe Michael's PDP-12 is the place to test it, though he won't see the problem if his serialdisk serial port is on the Omnibus. (Or maybe the DECmate?)

I have the version found on github (Non sys is version D and SYS is version E) which does not have this patch and I have the version that Charles worked over (Version G) but I don't have a server for that one. Where do I go to download the version that Bob did with the server before Charles worked on it. And it sounds like Vince has Version H?

That's the problem I'm working on, that the new code isn't generally available. Kyle is amenable to taking it, as long as it is tested and I can generate a github pull request with the various versions in it.
Charles' changes for Version H vs version G are pretty trivial. As usual, he couldn't leave the comments alone, but the actual code change is I think three lines to save a word, by having an output routine return the value that was output, rather than clearing the AC.

I agree with Vince that the changes I have seen will not address the issue on pre-omnibus machines. There was no provision to disable interrupt generation on a per device basis on the older machines. This makes me curious as to what Vince has in mind for a fix.

Hopefully I was clear above?

Vince
 
Almost. What I believe is happening is that Fortran disables interrupts, calls the driver, then enables interrupts after the return. The issue, then, is that when the interrupts get re-enabled, there is an output completion flag set from the last character sent from the driver to the serialdisk server. This triggers and interrupt, which Fortran doesn't have handler code for. When the Fortran interrupt routine returns, the flag is still set, the interrupt recurrs, and the system is hung (except maybe for servicing other interrupts, which would still happen).

Correct, in as far as what the FORTRAN runtime system does. When calling OS/8 drivers, interrupts needs to be off, since the drivers are written with that assumption.

But I don't get it. The serial disk driver uses a KL8E or KL8JA, right? And it's not interrupt driven in itself, I would assume (since OS/8 is not interrupt driven at all).
So I fail to understand how the serial disk could generate any interrupts. The KL8E and KL8JA do not generate any interrupts, unless you explicitly turn that on. Why would anything do that?
Or is this when used with some other serial controller, which always generates interrupts?
 
But I don't get it. The serial disk driver uses a KL8E or KL8JA, right? And it's not interrupt driven in itself, I would assume (since OS/8 is not interrupt driven at all).
So I fail to understand how the serial disk could generate any interrupts. The KL8E and KL8JA do not generate any interrupts, unless you explicitly turn that on. Why would anything do that?
Or is this when used with some other serial controller, which always generates interrupts?

Mostly it has been used to date with KL8E or KL8J, or cards (or software) that emulate them.

You are incorrect, in that these cards *do* default to a mode where the flag raises an interrupt request when it is set. So if interrupts become enabled, there will be one. That's what the RKIE kludge was about -- doing an RKIE instruction with AC clear, on controllers that support it, switches the "flag generates interrupt request" behavior off.

Arguably, that's a sub-optimal default. However, older PDP-8's and their serial controllers don't implement RKIE or any other method of changing the behavior, and their default was "flag implies interrupt request" (else there's no way to get one). So this default means that the Omnibus serial devices default to the behavior of their predecessors.

Which is all fine, if we don't use interrupts, or if our interrupt handler knows what to do for every device we use. When we use OS/8 to control devices Fortran's interrupt system knows nothing about, we need to be sure we don't leave flags/requests around that Fortran will be stymied by.

Vince
 
I had a conversation with Kyle, and found a copy of both revisions that Michael had sent me some months ago. I'm thinking I should just coordinate with Kyle to make them gnerally available?

Bob, are you OK with that?

Vince

I’m not concerned what use people make of any hacks I’ve done so whatever you think is helpful just go ahead.
 
Almost. What I believe is happening is that Fortran disables interrupts, calls the driver, then enables interrupts after the return. The issue, then, is that when the interrupts get re-enabled, there is an output completion flag set from the last character sent from the driver to the serialdisk server. This triggers and interrupt, which Fortran doesn't have handler code for. When the Fortran interrupt routine returns, the flag is still set, the interrupt recurrs, and the system is hung (except maybe for servicing other interrupts, which would still happen).
Ok I understand. Here is the SENDC code from the CJL version I have.
Code:
SENDC,  .-.                             /TRANSMIT A CHARACTER ROUTINE.
        RTLS                            /SEND THE CHARACTER IN THE AC.
        RTSF                            /SEND FLAG UP?
        JMP     .-1                     /NO, WAIT FOR IT.
        JMP I   SENDC                   /YES, RETURN TO CALLER WITH AC INTACT.
The RTLS sends the character to the server. The RTSF loop waits until all bits have been sent. The flag is set at this point and when you return the Fortran runtime will enable interrupts and instantly an interrupt will occur. Since Fortran does not know what to do with an interrupt from device code 41 it fails to clear the interrupt and hangs. The solution is to clear the flag by adding an RTCF instruction before the return.
Code:
SENDC,  .-.                             /TRANSMIT A CHARACTER ROUTINE.
        RTLS                            /SEND THE CHARACTER IN THE AC.
        RTSF                            /SEND FLAG UP?
        JMP     .-1                     /NO, WAIT FOR IT.
        RTCF                            /CLEAR THE FLAG
        JMP I   SENDC                   /YES, RETURN TO CALLER WITH AC INTACT.
For the receive operation the current code is
Code:
GETNUM, .-.                             /RECEIVE 12-BIT WORD FROM TWO CHARACTERS ROUTINE.
        RKCC                            /CLEAR THE RECEIVE FLAG, AC.
        RKSF                            /RECEIVE FLAG UP?
        JMP     .-1                     /NO, WAIT FOR IT.
        RKRB                            /YES, READ IN FIRST SIXBIT CHARACTER.
        CLL RTL;RTL;RTL                 /MOVE UP TO HIGH-ORDER BITS.
        RKSF                            /RECEIVE FLAG UP?
        JMP     .-1                     /NO, WAIT FOR IT.
        RKRS                            /.OR. SECOND SIXBIT CHARACTER INTO AC.
        JMP I   GETNUM                  /RETURN TO CALLER.
The seemingly obvious way to fix this is to just add an additional RKCC before the return (JMP I GETNUM). Looks like this:
Code:
GETNUM, .-.                             /RECEIVE 12-BIT WORD FROM TWO CHARACTERS ROUTINE.
        RKCC                            /CLEAR THE RECEIVE FLAG, AC.
        RKSF                            /RECEIVE FLAG UP?
        JMP     .-1                     /NO, WAIT FOR IT.
        RKRB                            /YES, READ IN FIRST SIXBIT CHARACTER.
        CLL RTL;RTL;RTL                 /MOVE UP TO HIGH-ORDER BITS.
        RKSF                            /RECEIVE FLAG UP?
        JMP     .-1                     /NO, WAIT FOR IT.
        RKRS                            /.OR. SECOND SIXBIT CHARACTER INTO AC.
        RKCC                            /CLEAR FLAG SO FORTRAN DOESN'T HANG
        JMP I   GETNUM                  /RETURN TO CALLER.
The problem with this is that it doesn't work because while the RKCC clears the flag it also clears the AC. To add this instruction at this point would require saving the AC, Clear the flag with the RKCC and then reloading the value. Not a good use of the limited code space if we can help it. For our purposes the best place to clear both of these flags is right before the return from the handler. Unfortunately, there are two return points in most handlers. One is the regular return and the other is the control C return. The control C return is the one that would confuse you because if you control C out of the handler and leave the flags set, everything will work fine until you run a Fortran program. Then Fortran will hang as soon as it enables the interrupts. Lets just rewrite the GETNUM routine to eliminate the issue.
Code:
GETC,   .-.                             /GET A CHARACTER FROM THE SERVER
        RKSF                            /CHECK THE FLAG AND SKIP IF SET
        JMP .-1                         /WAIT FOR THE FLAG
        RKRB                            /CLEAR AC, READ THE CHARACTER AND CLEAR THE FLAG
        JMP I GETC                      /RETURN

GETNUM, .-.                             /RECEIVE 12-BIT WORD FROM TWO CHARACTERS ROUTINE.
        JMS GETC                        /GET THE FIRST 6 BITS
        CLL RTL;RTL;RTL                 /SHIFT LEFT 6 BITS
        DCA SENDC                       /USE SENDC RETURN ADDRESS AS A TEMP
        JMS GETC                        /GET THE LOWER 6 BITS
        TAD SENDC                       /COMBINE THE TWO FRAMES
        JMP I   GETNUM                  /RETURN TO CALLER.
The original is 13 words long and the new version is 14 words. We don't need to clear the flag on GETC entry because it must already be clear. The only problem now is the assumption that the flag was initially clear. It should be because when you start the machine from the front panel one thing that happens is all devices are supposed to be reset. And since GETC always exits with it clear it should stay that way unless the server sends something. The one other place that could leave the flag set would be the serial disk boot code if you are booting from it. And I just checked the boot code in the handler and it does leave the receive flag set. We could change the boot but it would be easier to just replace the RKIE on handler entry with RKCC as sort of an initializer. So what did we overlook?
 
So maybe Michael's PDP-12 is the place to test it, though he won't see the problem if his serialdisk serial port is on the Omnibus. (Or maybe the DECmate?)

Both serial ports are in the processor chassis in the PDP-12, and not in the Omnibus expansion chassis.
 
Back
Top