[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference noted::hackers_v1

Title:-={ H A C K E R S }=-
Notice:Write locked - see NOTED::HACKERS
Moderator:DIEHRD::MORRIS
Created:Thu Feb 20 1986
Last Modified:Mon Aug 03 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:680
Total number of notes:5456

70.0. "R.P.'s write in Mach. Lang." by LATOUR::AMARTIN () Thu Oct 25 1984 20:24

           [Forwarded from the CMU bboard by Laws@SRI-AI.]


     A recent article devoted to the *macho* side of programming
     made the bald and unvarnished statement:
     
                Real Programmers write in Fortran.
     
     Maybe they do now,
     in this decadent era of
     Lite beer, hand calculators and "user-friendly" software
     but back in the Good Old Days,
     when the term "software" sounded funny
     and Real Computers were made out of drums and vacuum tubes,
     Real Programmers wrote in machine code.
     Not Fortran. Not RATFOR. Not, even, assembly language.
     Machine Code.
     Raw, unadorned, inscrutable hexadecimal numbers.
     Directly.
     
     Lest a whole new generation of programmers
     grow up in ignorance of this glorious past,
     I feel duty-bound to describe,
     as best I can through the generation gap,
     how a Real Programmer wrote code.
     I'll call him Mel,
     because that was his name.
     
     I first met Mel when I went to work for Royal McBee Computer Corp.,
     a now-defunct subsidiary of the typewriter company.
     The firm manufactured the LGP-30,
     a small, cheap (by the standards of the day)
     drum-memory computer,
     and had just started to manufacture
     the RPC-4000, a much-improved,
     bigger, better, faster -- drum-memory computer.
     Cores cost too much,
     and weren't here to stay, anyway.
     (That's why you haven't heard of the company, or the computer.)
     
     I had been hired to write a Fortran compiler 
     for this new marvel and Mel was my guide to its wonders.
     Mel didn't approve of compilers.
     
     "If a program can't rewrite its own code,"
     he asked, "what good is it?"
     
     Mel had written,
     in hexadecimal,
     the most popular computer program the company owned.
     It ran on the LGP-30
     and played blackjack with potential customers
     at computer shows.
     Its effect was always dramatic.
     The LGP-30 booth was packed at every show,
     and the IBM salesmen stood around
     talking to each other.
     Whether or not this actually sold computers
     was a question we never discussed.
     
     Mel's job was to re-write
     the blackjack program for the RPC-4000.
     (Port?  What does that mean?)
     The new computer had a one-plus-one
     addressing scheme,
     in which each machine instruction,
     in addition to the operation code
     and the address of the needed operand,
     had a second address that indicated where, on the revolving drum,
     the next instruction was located.
     In modern parlance,
     every single instruction was followed by a GO TO!
     Put *that* in Pascal's pipe and smoke it.
     
     Mel loved the RPC-4000
     because he could optimize his code:
     that is, locate instructions on the drum
     so that just as one finished its job,
     the next would be just arriving at the "read head"
     and available for immediate execution.
     There was a program to do that job,
     an "optimizing assembler",
     but Mel refused to use it.
     
     "You never know where its going to put things",
     he explained, "so you'd have to use separate constants".
     
     It was a long time before I understood that remark.
     Since Mel knew the numerical value
     of every operation code,
     and assigned his own drum addresses,
     every instruction he wrote could also be considered
     a numerical constant.
     He could pick up an earlier "add" instruction, say,
     and multiply by it,
     if it had the right numeric value.
     His code was not easy for someone else to modify.
     
     I compared Mel's hand-optimized programs
     with the same code massaged by the optimizing assembler program,
     and Mel's always ran faster.
     That was because the "top-down" method of program design
     hadn't been invented yet,
     and Mel wouldn't have used it anyway.
     He wrote the innermost parts of his program loops first,
     so they would get first choice
     of the optimum address locations on the drum.
     The optimizing assembler wasn't smart enough to do it that way.
     
     Mel never wrote time-delay loops, either,
     even when the balky Flexowriter
     required a delay between output characters to work right.
     He just located instructions on the drum
     so each successive one was just *past* the read head
     when it was needed;
     the drum had to execute another complete revolution
     to find the next instruction.
     He coined an unforgettable term for this procedure.
     Although "optimum" is an absolute term,
     like "unique", it became common verbal practice
     to make it relative:
     "not quite optimum" or "less optimum"
     or "not very optimum".
     Mel called the maximum time-delay locations
     the "most pessimum".
     
     After he finished the blackjack program
     and got it to run,
     ("Even the initializer is optimized",
     he said proudly)
     he got a Change Request from the sales department.
     The program used an elegant (optimized)
     random number generator
     to shuffle the "cards" and deal from the "deck",
     and some of the salesmen felt it was too fair,
     since sometimes the customers lost.
     They wanted Mel to modify the program
     so, at the setting of a sense switch on the console,
     they could change the odds and let the customer win.
     
     Mel balked.
     He felt this was patently dishonest,
     which it was,
     and that it impinged on his personal integrity as a programmer,
     which it did,
     so he refused to do it.
     The Head Salesman talked to Mel,
     as did the Big Boss and, at the boss's urging,
     a few Fellow Programmers.
     Mel finally gave in and wrote the code,
     but he got the test backwards,
     and, when the sense switch was turned on,
     the program would cheat, winning every time.
     Mel was delighted with this,
     claiming his subconscious was uncontrollably ethical,
     and adamantly refused to fix it.
     
     After Mel had left the company for greener pa$ture$,
     the Big Boss asked me to look at the code
     and see if I could find the test and reverse it.
     Somewhat reluctantly, I agreed to look.
     Tracking Mel's code was a real adventure.
     
     I have often felt that programming is an art form,
     whose real value can only be appreciated
     by another versed in the same arcane art;
     there are lovely gems and brilliant coups
     hidden from human view and admiration, sometimes forever,
     by the very nature of the process.
     You can learn a lot about an individual
     just by reading through his code,
     even in hexadecimal.
     Mel was, I think, an unsung genius.
     
     Perhaps my greatest shock came
     when I found an innocent loop that had no test in it.
     No test. *None*.
     Common sense said it had to be a closed loop,
     where the program would circle, forever, endlessly.
     Program control passed right through it, however,
     and safely out the other side.
     It took me two weeks to figure it out.
     
     The RPC-4000 computer had a really modern facility
     called an index register.
     It allowed the programmer to write a program loop
     that used an indexed instruction inside;
     each time through,
     the number in the index register
     was added to the address of that instruction,
     so it would refer
     to the next datum in a series.
     He had only to increment the index register
     each time through.
     Mel never used it.
     
     Instead, he would pull the instruction into a machine register,
     add one to its address,
     and store it back.
     He would then execute the modified instruction
     right from the register.
     The loop was written so this additional execution time
     was taken into account --
     just as this instruction finished,
     the next one was right under the drum's read head,
     ready to go.
     But the loop had no test in it.
     
     The vital clue came when I noticed
     the index register bit,
     the bit that lay between the address
     and the operation code in the instruction word,
     was turned on--
     yet Mel never used the index register,
     leaving it zero all the time.
     When the light went on it nearly blinded me.
     
     He had located the data he was working on
     near the top of memory --
     the largest locations the instructions could address --
     so, after the last datum was handled,
     incrementing the instruction address
     would make it overflow.
     The carry would add one to the
     operation code, changing it to the next one in the instruction set:
     a jump instruction.
     Sure enough, the next program instruction was
     in address location zero,
     and the program went happily on its way.
     
     I haven't kept in touch with Mel,
     so I don't know if he ever gave in to the flood of
     change that has washed over programming techniques
     since those long-gone days.
     I like to think he didn't.
     In any event,
     I was impressed enough that I quit looking for the
     offending test,
     telling the Big Boss I couldn't find it.
     He didn't seem surprised.

     When I left the company,
     the blackjack program would still cheat
     if you turned on the right sense switch,
     and I think that's how it should be.
     I didn't feel comfortable
     hacking up the code of a Real Programmer."
    

         -- Source: usenet: utastro!nather, May 21, 1983.
T.RTitleUserPersonal
Name
DateLines
70.1ROYCE::KENNEDYThu Oct 25 1984 20:504
The answer to where Mel went is, of course, writing microcode for one of
the big machines (i.e. a Cray, a Nautilus or something)!

Hugh.
70.2TURTLE::GILBERTThu Oct 25 1984 21:073
Mel was indispensable in getting all the wires in a Cray the correct length,
(so signals always arrive at the correct time), but did no micro-coding at CRL;
the Cray has no microcode.
70.3HARE::COWANFri Oct 26 1984 00:504
	Are you serious?

	KC
70.5GROK::HERBERTFri Oct 26 1984 17:463
Anyone on a PDP-11 ever displayed the two bytes at a CLR (R5)?

Kevin
70.6ALIEN::SZETOSat Oct 27 1984 02:318
  Don't tell me some of Richie Lary's code is still in RSTS!  I inherited a
  piece of code, originally written by him, in my first job at DEC.  In it
  was a sequence to print a '<CR><LF>'.  He used R5 to fill the XRB.  One of
  the instructions was 'CLR (R5)' and he used the instruction as the two 
  characters to be written.  Richie's comment in the code (yes, he commented)
  was: "The devil made me do it!"

--Simon
70.7ORPHAN::BRETTSun Oct 28 1984 02:467
.2 was ABSOLUTELY serious, on both the Cyber series and the Cray's, the wire
length is used to control timing, so the engineers putting the machine together
on site sit there with their oscilliscopes and cut 1/4" pieces of wire off
until the signals are taking the correct time to get thru.

/Bevin
70.8HARE::COWANSun Oct 28 1984 12:2511
Oh yea, I remember a story (which, if you are bored, you are perfectly
able to turn off).

I forget who originally told me the story, but there was a Cyber FE
trying to fix a machine.  He has tried all sorts of things, and finally
determined that it was a timing problem.  The solution was to take a piece
of wire and wrap it the long way around the machine.

Software is a piece of cake compared to that.

	KC
70.9CLOSUS::MCVAYThu Nov 01 1984 09:198
 While all you old-timers are reminiscing, I'd like to comment on the
poem: it's the usual "boy, programmers today don't know how to code!
Look at the good old days!"  It sounds like a bunch of old pilots on a
modern shuttle flight talking about how great the DC-3's were--want to
fly around in those from city to city?  I look for a different form of
adventure. 

 However, that poem is one of the most elegant descriptions of what it 
70.10REX::MINOWFri Nov 02 1984 23:2229
If I remember Ritchie's buffer copy code correctly, it ended with
the sequence

	MOV (PC),(R5)+
	CLR (R5)

Note that, to get this right, Ritchie had to make sure the buffer
would be aligned correctly.

When I first joined Dec, I tried modifying the OS8 DECtape driver
to allow reading PDP-11 dectapes (with 512 byte blocks).  Unfortunately
the OS8 DECtape format used 128 byte blocks and the wordcount was
stored as a 2-s complement number (octal 7200).  Since this was
a perfectly valid PDP-8 machine instruction and since the driver
just fit into 128 words, etc. etc.  I never was able to add that
one word of code.

The first operating system for the PDP-11, Dos used to stuff the
next instruction into a device register:

	MOV (PC),@#177564
	RTS PC

The 207 value of RTS PC would set interrupt enable and GO.  When the
DL-11 arrived, one of the loworder bits was used to control break
generation and we had a merry time cutting jumper J5 to get our
machines working again.

Ahh memories.
70.11EAYV05::MCCROHANMon Nov 05 1984 11:2919
How about the following instruction placed in loc 157776
and executed?

MOV -(PC),-(PC)


or the following executed from 000000 on an 11/40 with R0, R6 = 0

000002	CLR (0)+
000004	BR-(2)		Code 776 (I forget my mnemonics)


Anyone know what will happen?

We used these a lot when I was a tech, to check basic memory integrity.


Mike

70.12EAYV04::PETERMMon Nov 05 1984 15:186
The fastest code on an 11/45 was executed in the memory management registers !

Does anyone know how the MM registers in the 11/70 compare with cache ?

                                                                       -PeterM-
70.13EAYV04::PETERMMon Nov 05 1984 15:2712
The 11/05 and 11/10 CPUs allowed code in the general registers -

	1st inst in R0
	2nd inst in R2
	3rd      in R4
	4th      in R6

Use R1, R3, and R5 as scratch registers.

Branch instructions behave peculiarly.

                                                                       -PeterM-
70.14ADVAX::A_VESPERTue Nov 06 1984 11:3421
On the PDP-10 the registers were simply the first 16 words of
memory. (There was even a switch to enable/disable high speed
memory for them on the front panel.) You could load instructions
into them and JUMP or CALL to location 0. 

This was used so often that the assembler had special opcodes to
indicate that code would be relocated to another place before it
was executed: 

	PHASE 0
loop:	...
	JUMPL	loop
	RETURN
	DEPHASE

You had to load it into the registers yourself, then all you had
to do was:

	CALL 0

Andy V
70.15LATOUR::AMARTINThu Nov 08 1984 23:5213
Re .11:

The first one was a real legend in college (MOV (PC)-,(PC)-).  It was
known by the octal for it, rather than the name.  Too bad I forgot it.

Re .14:

Unfortunately, the ACs were slower than cache by the KL, and so programs
that do this (and you can tell with ^T) aren't so optimal any more.

(It's much easier to JRST into the ACs than to JUMP to them; it's difficult
to JUMP anywhere).
				/AHM
70.16ADVAX::A_VESPERFri Nov 09 1984 11:569
re .15:  Yes, I know that JRST is faster, but people who
don't know the PDP-10 instruction set would be confused. 

For those who care, JRST = "Jump and ReSeT flags", and a
plain JUMP is "JUMP never". If you really want to jump, you
must say JUMPA for "JUMP Always" or JUMPL for "JUMP
Lessthan" or ... 

Andy V
70.17ADVAX::A_VESPERFri Nov 09 1984 12:0312
Re .15 continued: 

Also, there is no CALL -- you normally used "PUSHJ P,addr"
to call a routine and a "POPJ P," to return.  There are a
couple of other ways to call routines, but I don't remember
them off-hand. 

I am suprised to hear that the KL10 cache is faster than the
registers. I used a KA10 that ran for a long time on DECtape
before we got a disk drive. 

Andy V
70.18LATOUR::AMARTINFri Nov 09 1984 16:4723
Just ragging on you.

Actually, JRST means "Jump and ReSTore".  In the usual case, "JRST 0,ea",
nothing gets restored, but there are 15 other cases, with several
interpretations depending on the processor type and current mode.

Other subroutine call instructions include:

PUSHJ	PUSH and Jump
JSR	Jump to SubRoutine
JSP	Jump and Save Pc
JSA	Jump and Save Ac
XCT	eXeCuTe
UUO	Unimplemented User Operation

There's also a couple of return instructions

POPJ	POP and Jump
JRSTF	Jump and ReSTore Flags
JRA	Jump and Restore Ac

JSA/JRA are about the most complex and losing.
				/AHM
70.19DAEMON::GENTRYFri Nov 09 1984 23:1513
The MOV -(PC),-(PC) is 14747 (known via some sig newsletters as
the '47 test')

Here's another one for you:

	0/	15740
	15740/	0
	r0/	160000
	0G

on an LSI.

Try it, you'll like it...
70.20EAYV05::MCCROHANWed Nov 21 1984 09:525
I'd love to see that on the address lights of an 11/40 or 11/70!


-Mike-

70.21EAYV05::WESTONMon Nov 26 1984 15:019
Now there was a test of a programmer...

To get the address and data lights running in all sorts of fancy patterns 
on RSTS or RSX (but then with supervisor mode, it was easy...)

Give us good NUL jobs and plenty of lights to play with...

John

70.22JAWS::KAISERTue Nov 27 1984 02:1813
The IBM 1401 computer controlled the 1403 printer directly, as I recall, with
no hardware buffering.  The strike of each hammer in the printline was under
program control.

In 1965 I watched and listened in horror-struck awe as a program ran on the
1401 in UC Berkeley's Computer Center that caused the 1403 to HUM the theme
from "The Bridge Over the River Kwai" and several other melodies.  It was
done by controlling the timing of how the 132 hammers struck the paper, and
the rhythm was the little "click" of the paper advancing a line.

Whoever wrote that was a R.P.

---Pete
70.23HARE::STANTue Nov 27 1984 03:083
I had a null job for RTS-8 (on a PDP-12) that played the
Star War's theme music.  The PDP-12 came with a built-in
speaker that was driven off the pulsing of AC bit 0.
70.24JAWS::KAISERTue Nov 27 1984 11:0615
The same computer room (cf .-2) held an IBM 7040 and an IBM 7094.  One program
for the 7094 produced music by using an AM radio with an antenna that was just
a wire, wrapped around the L light on the console.  Flickering the light on and
off generated the sound.  This wasn't easy, since the L light didn't have to do
with the usual programmable register settings.

The 7094 also had a bank of lights 15 wide by 7 deep that showed the contents
of the index registers.  I wrote a program to make these be a moving message
display.

And finally, in the same installation (and later in many other installations) I
heard a program make "music" on the 1401 by playing through an AM radio simply
placed atop the CPU.  With FCC compliance, those days are gone.

---Pete
70.25REX::MINOWTue Nov 27 1984 13:2924
The 1401 example wasn't quite as stated in a previous response.
You controlled the 1403 printer by loading a line in the print
buffer and executing the "print" instruction.  Time and bad
living have purged the exact mnemonic from my working storage.

The printer contained a chain of type and logic to hit the hammer
when the proper character was in the proper position.  By spacing
the characters properly, you can get different tones:

	E    E    E    E ...
	E         E        E

The second line should give a lower-pitched noise.  "Music" consisted
of a deck of cards, appropriately punched, and a card-to-printer
listing program.

In addition to music, there was at least one card deck which was
punched in such a way as to cause the chain to resonate, and eventually
break.

Loudspeakers attached to computer logic dates back well into the '50s.
We used them as diagnostic tools, as well as to play music.

Martin.
70.26LATOUR::RDFTue Nov 27 1984 14:0715
Before I worked for DEC, I had some friends in WS (West Springfield)
where the tape drives get their burn-in.  Some of the diagnostics people there
had set up the burn-in programs for the TU-78 so that it would play "Mary
had a little lamb".  The tape spinning forward a few blocks, then back a
couple, and forward some more,..etc, provided the sound.   

Rumor has it you can walk up to any production TU78, type the right 
combination of numbers on the little keypad down below the reels and
have this occur.

Rick

PS.  If you're interested some time, ask them about the tank they made out
     of tape drive motors and takeup reels.  

70.27ULTRA::KARGERSat Dec 01 1984 18:094
The Burroughs 6700 had a large rectangular bank of lights that displayed
the Burroughs logo (a large capital B) as the idle pattern.  I used the
B6700 at the US Air Force Academy, and of course, some unknown real programmer
had changed the idle pattern to display AF.
70.28FKPK::KONINGMon Dec 03 1984 21:2227
Figures....


My favorite type of system console is the one on the CDC 6000 series.
It's a pair of 18-inch or so round scopes, with two display modes:
dot graphics (one dot per microsecond) or vector-stroke characters
(one per microsecond or so, three sizes).  The display control is
connected directly to the I/O channel, and driven by a dedicated
peripheral processor.  By default you got the system status (sort of
like WHAT or VT5DPY or whatever -- except that it's in real time
since the screen is updated 50 times per second directly from the
system tables).  But you could run all sorts of games on it to
while away the time at late night shifts.  One good example was
the kaleidoscope -- great in combination with certain controlled
substances.

Another handy one is the PC watcher: it uses the "read PC" instruction,
breaks down the 18-bit result into 9-bit X and 9-bit Y, and plots
a dot there.  Great way to find the "hot spots".

Finally, there was "lunar lander".  Not the easy one like on the GT40,
but one like a true flight simulator -- with a view from the pilot's
station out the windows and on the controls.  I never got past the
point of seeing stars and craters spinning past the window lik
crazy... 

	Paul
70.29FKPK::KONINGMon Dec 03 1984 21:2411
...and speaking of hacking machine code:

The 6000 series machines have a bootstrap which consists of a panel
of 12 rows of 12 switches, i.e. a 12-word program to be executed by
a PPU.  (why 12 words?  For symmetry, of course!)

It's always fun to try to cram anything in 12 words, but the best
challenge was to use the first 5 words or so to transfer the next 7
to another PPU, which would then execute the next 5 to read the
secondary boot off the disk and use the last 2 words as parameter
to be passed to the secondary boot...
70.30EAYV04::PETERMMon Jan 07 1985 11:156
Way back in the dim days when PDP11/70s were something new, a student on a
hardware course in READING, ENGLAND happenned on a program which would blow
the fuse on the TU10 tape drive.  A little bit of forgetting to check the
ready bit and woops went the fuse driving the reel motor power supply.

PeterM
70.32LATOUR::AMARTINWed Jan 09 1985 00:574
The field image copy of DDT for the -20 depends upon the fact that the
instruction SETA (opcode 424) is both a no-op and a legal indirect word.
				/AHM
P. S.  What does the number of no-ops in an architecture have to do with RISC?
70.33TRON::WARWICKWed Jan 09 1985 10:4411
RE: -1

  I think what he meant was:

RISC = Reduced Instruction Set Computer.

PDP-10 has millions of NO-OPs. Therefore, a machine with only one NO-OP
is a RISC. Right ?

trev

70.34EAYV04::PETERMWed Jan 09 1985 10:5712
The PDP-11 has "0", zero, zilch NOP instructions.  How's that for RISC.

The 240 instruction commonly referred to as NOP is actually a
"Clear no Cond codes" instruction.  Similarly the 260 instruction is actually
"Set no Cond codes".  Also any of the branch instructions (seventeen) with an
offset of zero should NOP.

PAL-11-A (remember those days) barfed on the NOP mnemonic.

Come to think of it, PAL-11-A didn't understand PDP-11 registers ! ! !

PeterM
70.35EDSVAX::CRESSEYWed Jan 09 1985 12:4616
Re .33

    Right.

    Reducing the number of useful instructions only impacts dull, serious
    programmers.  Hackers only become concerned when the number of NOP's
    is reduced.

Re .34

    I believe you misunderstand.  ANY instruction that does nothing but
    waste time is a NOP.  Clear nothing is a NOP.  Set Nothing is a NOP.
    Branch Never is a NOP.  I don't know how many NOP's there are in the
    PDP-11 instruction set, but there certainly are some.  It makes no
    difference whether an op-code is reserved for NOP.  In fact, reserving
    an OPCODE for NOP is bad engineering of the OPCODE space.
70.36LATOUR::AMARTINWed Jan 09 1985 12:5915
Ah, but the word Reduced refers to the power and complexity of instructions,
not the number of different instructions.

Re .-1:

There are at least two uses for a NOP instruction.  One is to waste time, and
one is to waste space.  I have never used a NOP to waste time in a program,
but I have often used a NOP to fill up space after things like a subroutine
call with skip returns.  It is a matter of interest as to which NOP is the
fastest in such circumstances.

(Actually I suppose putting NOPs in the non-skip slot after a routine call
would be more like alignment than wasting space.  Putting them in code to
leave space for patching would be a space wasting application).
				/AHM
70.37ROYCE::KENNEDYWed Jan 09 1985 14:094
Re:	240 (the standard PDP11 NOP)

It is also a space character with the high-bit (sometimes) 
parity set. Anyone used it as such??
70.38EAYV04::PETERMWed Jan 09 1985 15:2714
My point was that the NOP instruction does not exist in the PDP-11
architecture - WHAT ! who said architecture ?

The NOP assembler mnemonic was added as an afterthought and was implemented
as a clear no cond-codes.

Maybe it was fashionable to implement NOPs in computers in those days.

Suggestion

	Real computers have the NOP instruction implemented in
	microcode or in logic !

PeterM
70.39TURTLE::GILBERTWed Jan 09 1985 19:5114
Ah, yes.  This discussion brings back such memories...

I've used NOPs (on PDP-11s) as a time-waste.

A PDP-11/20 of bygone days had a floating point unit which was accessed by
some 'memory' registers.  Since the floating-point operations were pretty
fast (relative to the 11), and checking for completion of the floating-point
operation rather tedious (and sometimes caused a few unused micro-seconds of
CPU time), and the timings of both the PDP-11/20 instructions and the floating-
point unit were clearly stated, it was 'better' to just generate a few 'nop'
instructions to wait the requisite amount of time.

This was done by a macro (of course), which sometimes generated a few nops
(of various flavors), sometimes a little loop, ..., all meticulously timed.
70.40FKPK::KONINGWed Jan 09 1985 21:2320
Re .37: I've see a non-standard NOP used to SAVE space...

Some background:

	- The RT11 exec is position-independent code
	- The RT11 .PRINT system service (EMT) takes the address of
	  the string to print in R0
	- If the string is terminated by a null (.ASCIZ), the .PRINT
	  adds a CR LF to it

So therefore, when the CLI code wanted to do a CRLF in position independent
code, the sequence of instructions came out as:

	MOV	PC,R0
	MOV	R0,R0		;NOP whose low byte is zero!
	.PRINT

I trust further explanations are superfluous...

	Paul
70.41RANI::LEICHTERJSun Jan 20 1985 22:2045
re:  NOP's and RISC's

Interestingly, every RISC design I've seen includes an explicit NOP - it has to!
You see, one of the design goals of RISC architectures is that EVERY instruction
take one cycle time.  This causes a problem for conditional branches:  You need
to do two things in sequence - test the condition - even if it's a single bit -
and then either change or not change the PC.  Just the load of the PC will
take as long as, say, loading a register - so you'd need to lengthen the cycle
time - slowing down the whole machine - just to accomodate the conditional
branches.  Further, a big advantage of the fixed size/fixed cycle time instruc-
tions is that they can easily be pipelined.  However, when a branch is taken
(conditional or not) the next instruction in the pipe becomes invalid, which
costs you a cycle.

The solution, adopted from long micro-programming practice, is the so-called
"delayed branch".  This is a branch that doesn't "take" until one cycle
AFTER it is issued.  Thus, if DBR were a delayed branch:

	1:	MOV	#0,A
	2:	DBR	FOO
	3:	MOV	#0,B
	4:
	...
	FOO:	xxx

The instructions are executed in the order (1), (2), (3), (FOO).

In most cases - typically 90% or more in compiler-generated code - the in-
struction just before the DBR can safely be moved after the DBR.  Then the
code gets executed at the maximum rate possible.  There are always the
remaining cases - things like successive branches, for example - that can't
be interchanged.  In that case, you need a NOP to put after the DBR.

(Another alternative, of course, is to have both BR's and DBR's.  Most RISC's
don't do this since they usually have room in the instruction word to include
a register or two, so they tend to have a bunch of branches - BR if 0, if >0,
etc. - rather than variations on one branch; so they'd need to duplicate a
variety of branches, rather than introducing one NOP, which will only very
rarely be used anyway.  (It will also save space, but not time - the delay
for a non-delayed branch will still have to be there.))

							-- Jerry

BTW, for missing instructions:  The VAX appears to be the first significant
architecture without an explicit WAIT (for interrupt) instruction.	-- J
70.42FKPK::KONINGMon Jan 21 1985 22:0311
Re .41: what you describe as "RISC" sounds more like a typical 2901-based
microcontroller.  For example the UDA50 microengine works that way.
But I've never seen a general-purpose CPU of the RISC flavor that
has deferred branch.  Nor is it necessary for RISC machines to have
only one-cycle instructions, or fixed-length cycles.

As for the missing WAIT: I rather suspect it's the other way around, with
the PDP11 being one of the few that DOES have one.  For example, the PDP8,
IBM 360, and Cyber 6000 all get along without it.

	Paul
70.43REX::MINOWWed Jan 23 1985 00:007
Old PDP-11 Dos-11 hackers will fondly recall that the 11/20
had two wait-for-interrupt instructions.  The guts of that
marvelous o.s. used
	BR	.
to wait for an interrupt.

Anyone remember why?
70.44VAXUUM::DYERMon Apr 22 1985 19:153
	[RE .43]:  Well, Martin; are you going to keep us in suspense any
longer?
#6	<_Jym_>\
70.45REX::MINOWMon Apr 22 1985 20:2411
Well, Lou Cohen actually wrote that code.  He has now repented
of his evil past and is working on improving software quality.

If I remember the history correctly, on the 11/20, if there
was an interrupt pending when you executed the WAIT, the cpu
waited anyway (until the NEXT interrupt request).  BR .
just spun around until something happened.  Rumor has
it that the same bug was in the 11/34, too.

Martin.

70.46MARCIA::GSCOTTFri May 24 1985 23:4617
In my old TOPS-10 days we had a contest to see who could write the smallest
program that did a printed a directory on your terminal.  I can't remember
who won, but it it was the guy who used an

	INBUF 5,

which is an ASCIZ CR, LF.  (INBUF makes buffers from free memory for I/O).

Another guy used a 

	POPJ P,'UFD'

preceeded by a SKIPA instruction with the AC field non-zero (because
SKIPA 1,ADDR loads AC with contents of ADDR and skips always, and the
location before the POPJ was used for your PPN to look up your UFD).

GAS