• Please review our updated Terms and Rules here

TSF never skips in pdp8 simh?

SpaceHobo

Experienced Member
Joined
Dec 10, 2021
Messages
53
Location
London, UK
I am trying to run the usual PAL-III "Hello, world" example via palbart and simh. I can load my hello.bin and run it at 0200, but it seems as though the TTO device is never ready for output.

When I step through, I just keep getting this in a tight loop:

Code:
Simulation stopped, PC: 00211 (TSF)
sim> s

Step expired, PC: 00212 (JMP 211)
sim> s

Step expired, PC: 00211 (TSF)
sim> s

Step expired, PC: 00212 (JMP 211)

I thought that by default TTI/TTO were bound by simh to my stdin/stdout, and I could just trust TLS to print a character. Is there more that I need to set up?
 
TSF will skip if the flag is set meaning the last character sent is done. When you start out the flag is clear. Until you send a character the flag will remain clear.

Show us your program.
 
I thought that by default TTI/TTO were bound by simh to my stdin/stdout, and I could just trust TLS to print a character. Is there more that I need to set up?

Correct behavior of the real hardware would be that the flag only comes up when a character has been output. Until a TLS has been done, TSF will never skip. (I thinkk there's also some other Omnibus-specific instruction that can also set the flag instead of the TLS -- but then you'd be needlessly restricting your code to only work on Omnibus machines.)

If you come from a TSS/8 environment, this is different from what you are used to. There, I believe, TSF just always skips, and TLS blocks if the relevant output buffer is currently full.

SIMH is mimicing the behavior of the real hardware, and I'm unaware of any bugs in it's TSF/TLS handling.

Vince
 
I notice that you are single stepping SIMH. I do have problems also when single stepping, but not when executing a program.

Please post your program and your SIMH configuration file. Can you also specify which variant and version of SIMH you are using?

Dave
 
Here's the LST result of my palbart assembly, which seems to have all the details of this. On vrs42's recommendation I moved the TLS to right before the TSF, in the hopes that it will speculatively execute it and only get into the ready-loop after a character has been posted.

On daver2's request, I've attached the config output. I noticed that I'd fiddled with TTO while flailing about on this.

I switched TTO back from 8B to KSR and the pre-TLS version worked!

Code:
sim> run 0200
ﬠ

HALT instruction, PC: 00206 (JMS 210)
sim> set tto ksr
sim> run 0200
HELLO, WORLD!

HALT instruction, PC: 00206 (JMS 210)
 

Attachments

  • hello.lst.txt
    2.3 KB · Views: 2
  • simh.configuration.txt
    1.7 KB · Views: 1
"I switched TTO back from 8B to KSR and the pre-TLS version worked!"

Did you quit and restart SIMH or did you run it after the previous code worked so the flag was still set?
8B vs KSR shouldn't change flag behavior.
 
I edited the code so that it did a TLS before checking the flag instead of after, so it always tried to send the first character. That's what fixed it. The 8B setting just confused my terminal to print the whole sequence as a UTF-8 Hebrew ayin, and flipping back to KSR did the character interpretation properly.
 
On real hardware pressing Start or Clear on the console will clear all I/O device flags. On Omnibus machines this could also be accomplished by executing the CAF instruction. In this regard SIMH behaves like real hardware in that when it wakes up all device flags are clear.

If the I/O flags are clear, then this code will hang.
Code:
        TSF
        JMP .-1
        TLS
This happens because you are waiting for an event that will never occur. The flag can never become true because you have never sent a character. This confusion was common among early assembly coders. My instructor just did the TLS;TSF;JMP .-1 sequence because he knew that worked. Everyone eventually wants to do it the other way because it is more efficient. It lets you take advantage of the time between the TLS and the time to send the character. At 110 baud this time is considerable (~100 ms). On the high speed punch you can hear a difference. It does not run quite as smoothly.

The reason to treat the flags this way is because of interrupts. If the machine wakes up with the flag set, an interrupt will occur as soon as they are enabled. The interrupt routine will discover a TTY output interrupt is pending and dispatch to the TTY out routine. This would clear the interrupt with a TCF. At this point the output buffer would be checked and since there are no characters in the buffer it will return from the interrupt having wasted that time. If the machine wakes up with the flag clear, no interrupt occurs.

I have seen code that gets around this issue by sending a null right after the program starts running. Changing your program in this way.
Code:
HELLO,  CLA CLL         / Clear the AC and the Link bit
        TLS             / PRIME THE PUMP BY SENDING A NULL
        TAD (DATA-1)    / Point at AC just "BEFORE" the data (accounting for later pre-increment behavior)

...

OUT1,   0               / Will be replaced by caller's updated PC
        TSF             / Skip if the previous character is done
        JMP .-1         / Wait for flag
        TLS             / Send the character in the AC
        CLA CLL         / Clear AC and Link for the next pass
        JMP I OUT1      / Return to caller
I am guessing that this is what you are doing in your OUT1 output routine and why it doesn't work on a fresh start of SIMH.
I always disliked this fix because the teletype makes an additional jiggle of the mechanism.

Kudos on your usage of the Auto index register. It is a seldom used feature of the machine.

You can compress your ASCII string to a single line like this:
Code:
DATA,   "H;"e;"l;"l;"o;",;" ;"W;"o;"r;"l;"d;"!;015;012;0
I know that it is ugly either way.

I don't use SIMH often as I wrote my own Straight 8 emulator starting in the mid 1980's. Interestingly a 386 at 16 mhz runs the emulator about the same speed as real hardware.

I hope that helps and Best Wishes!
 
Doug is correct, it was common practice, on the "Family of 8", to output a null (000[SUB]8) [/SUB]at the beginning of any program that did terminal output to get around this problem or "Prime the Pump" as they say.
 
Thanks Doug. Your posts are always instructive...

Yes the '8' and the ')' is a smiley face with sun glasses on. On the 'old' board we could disable the auto display of these critters. I have not found that option as of yet. When the critters appear I put a space between the '8' and ')'. A pain I know...

We all await the 'new' board...

Dave
 
Dave,

You need so know the board well. How do I add the signature line that I see on some peoples posts?

Thanks,

Mike
 
Hey Mike. This is how I did it (although I have removed my signature now). I originally used it for my Location (until I found out how to do that)!

Edit your Profile and go to the Account tab.

Scroll down until you find "Conversation Details Options".

Tick the box to "Show Signatures" and there is some text to click on to "Edit Post Signature".

Save and logout and log back in again.

I did find the signature took a while to apply though?...

Simple when you know how! Well, at least, that's how my user interface behaves...

Enjoy and good luck.

Dave
 
I have seen code that gets around this issue by sending a null right after the program starts running. Changing your program in this way.
Code:
HELLO, CLA CLL / Clear the AC and the Link bit
TLS / PRIME THE PUMP BY SENDING A NULL
TAD (DATA-1) / Point at AC just "BEFORE" the data (accounting for later pre-increment behavior)

...

OUT1, 0 / Will be replaced by caller's updated PC
TSF / Skip if the previous character is done
JMP .-1 / Wait for flag
TLS / Send the character in the AC
CLA CLL / Clear AC and Link for the next pass
JMP I OUT1 / Return to caller
I am guessing that this is what you are doing in your OUT1 output routine and why it doesn't work on a fresh start of SIMH.
I always disliked this fix because the teletype makes an additional jiggle of the mechanism.

Aha! Thank you to both you and BitWiz for sharing the null-print idiom. I will have to keep that in mind for the future.

Kudos on your usage of the Auto index register. It is a seldom used feature of the machine.

I must admit I searched until I dug up an example that used it, but it's a feature I wanted to learn to take advantage of. I am used to the 6502 zero page which is only "magical" like this if a system's ROMs make use of special locations (such as the C64 KERNAL's use of the first couple bytes, which I guess is not too different from the way 8s tend to deal with interrupts there).

I am working toward a rather ambitious bytecode interpreter, and exploring some ideas I'd seen on other architectures. I had hoped to use the zero page as a sort of "register file" with a sliding window (since there's no handy hardware stack), but those auto-index registers get in the way so I can only use 112 words at the top.

You can compress your ASCII string to a single line like this:
Code:
DATA, "H;"e;"l;"l;"o;",;" ;"W;"o;"r;"l;"d;"!;015;012;0
I know that it is ugly either way.

I am using AK6DN's version of palbart, and I have to wonder if macro8x can help with this sort of thing somewhat. I'm still going through the macro8 manual to see why it couldn't compile things palbart could...

I don't use SIMH often as I wrote my own Straight 8 emulator starting in the mid 1980's. Interestingly a 386 at 16 mhz runs the emulator about the same speed as real hardware.

I hope that helps and Best Wishes!

I found and rescued a 256-line C emulator that I found cute: https://zork.net/git/SpaceHobo/embello-pdp8/src/branch/main/p8.c

Thank you all for your time helping a newbie to PAL!
 
I looked at that emulator mentioned in the previous post. Interesting choices in the instruction decoder. I need to look at the operate instruction handling more closely. And interrupts aren't implemented completely.

By chance I ended up on the PDP-8 Wikipedia page. I note that your Hello, World! is based off of the examples shown. I should know better than look closely because I know I could easily spend hours fixing issues there. The last time I went down that rabbit hole it was trying to correct an example program for the Intel 8080. No 8080 programmer would have written the example that way. I corrected it and some guy put it back they way it was. It took me several rounds with this guy before it stuck. I am afraid to see if my example is still there.

I use palbart to assemble test code to run on my emulator. I even found and fixed a bug in palbart a few years back.
 
I am using AK6DN's version of palbart, and I have to wonder if macro8x can help with this sort of thing somewhat.

I just got to the part of the MACRO8 manual where it describes TEXT literals, so I was right that it can help avoid some of this.
 
I looked at that emulator mentioned in the previous post. Interesting choices in the instruction decoder. I need to look at the operate instruction handling more closely. And interrupts aren't implemented completely.

Yes, it seems that the 256LOC emulator's test case is FOCAL69, so anything not required by that is probably ignored.


I use palbart to assemble test code to run on my emulator. I even found and fixed a bug in palbart a few years back.

Did you push the change upstream? If not, it may be worth seeing if Don North has fixed it in his version, and submitting the fix if he hasn't yet: https://github.com/AK6DN/dec-utilities-for-pdp

I used to take BART to get around when I lived in San Francisco and Oakland, CA, so it's kind of amusing to me that palbart was written around that time to help update their old signal systems.
 
Did you push the change upstream? If not, it may be worth seeing if Don North has fixed it in his version, and submitting the fix if he hasn't yet: https://github.com/AK6DN/dec-utilities-for-pdp

There's also a cross assembler I maintain as part of the 8tools: http://svn.so-much-stuff.com/svn/trunk/pdp8/8tools/. (See the doc/ directory for a little about what the various tools do.)

It's got a number of enhancements and bug fixes. The LINC mode support is still experimental, though.

Vince
 
Back
Top