Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Self Modifying Code Evils?

13 views
Skip to first unread message

Ed Smeda

unread,
Jan 9, 1998, 3:00:00 AM1/9/98
to

I was alerted by a reader that there are problems associated
with self-modifying code.

To minimise code length and save on variable space, I have
resorted to using e.g.

LD (PATCH),A
.
.
.
LD (HL),0
PATCH EQU $-1

While such code can't be ROMed, I don't see any other disadvantage.
Can anyone think of situations where this type of programming should
be avoided? The code is intended for CP/M type OS and its variants.

Ed

D. Peschel

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

In article <6f2_980...@tegan.apana.org.au>,
Ed Smeda <Ed.S...@tegan.apana.org.au> wrote:

>I was alerted by a reader that there are problems associated
>with self-modifying code.

>While such code can't be ROMed, I don't see any other disadvantage.


>Can anyone think of situations where this type of programming should
>be avoided? The code is intended for CP/M type OS and its variants.

Other "stock" reasons for not using self-modifying code are:

- It makes the code non-reentrant (i.e., the code can't be shared
by several running processes).

- The CPU cache(s) and the code may interfere with each other.

Plain CP/M doesn't multitask, though Concurrent CP/M does. The 8080 and Z-80
CPUs don't have caches (as far as I know) though newer versions such as the
Z180 might.

I have no experience with this sort of programming -- I'm just giving a few
standard answers. I do know that on the Macintosh (and probably the PC),
upgrades have caused sneaky code to stop working. Does your approach save
a lot of time? Is it significantly shorter? Are you sure there's not another
way to do the same thing?

-- Derek

JWillard44

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

>To minimise code length and save on variable space, I have
>resorted to using e.g.
>
> LD (PATCH),A
> .
> .
> .
> LD (HL),0
>PATCH EQU $-1
>
>While such code can't be ROMed, I don't see any other disadvantage.
>Can anyone think of situations where this type of programming should
>be avoided? The code is intended for CP/M type OS and its variants.

The biggest problem here is that the code is not re-entrant. Should
something interrupt the execution and use the routine, when it exits the
interrupt, the location "PATCH" would point to the return address inside the
interrupt routine, not the background task which is now running.
That is why a stack is so superior for handling subroutine return
addresses and even data parameters.

Joel in Ogden

"Move not the ancient landmarks" - Solomon

Clarence Wilkerson

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to Ed Smeda

I believe even the BIOS on my H89 has some self modifying code.
If you want to output to a variable io port on a straight 8080,
I don't think you get much choice.
--
Clarence Wilkerson \ HomePage: http://www.math.purdue.edu/~wilker
Prof. of Math. (topology)\ Internet: wil...@math.purdue.edu
Dept. of Mathematics \ Messages: (765) 494-1903, FAX 494-0548
Purdue University, \ Office: (765) 494-1955 (voice/phonemail)
W. Lafayette, IN 47907-1395 \ Rm. 450 Math. Sci. Bldng.

Herbert R Johnson

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

In article <69dal1$c...@mozo.cc.purdue.edu>,
wil...@math.purdue.edu (Clarence Wilkerson) wrote:
*>I believe even the BIOS on my H89 has some self modifying code.
*>If you want to output to a variable io port on a straight 8080,
*>I don't think you get much choice.
*>--
*>Clarence Wilkerson \ HomePage: http://www.math.purdue.edu/~wilker

"You are correct, sir" as they say. I've found one dodge to ROM code and
self-modification is to push the code on the stack and to execute the stack.
I forget the details, it depends on how the stack is incremented or
decremented for your processor. Push a RET or a JUMP address back to yourself,
push the op codes, then "call" or "jump" to the stack pointer. BEware that
a "call" will push your address onto the stack, so a JUMP may be prudent.
YOu get the idea.

Herb Johnson


**** ------------------------------------------------------ ****

Herbert R. Johnson voice/FAX 609-771-1503 day/nite
hjoh...@pluto.njcc.com Ewing, in central New Jersey, USA

amateur astronomer and astro-tour guide
supporter of classic S-100 computers as "Dr. S-100"
rebuilder of Mac Plus computers for your computing pleasure
and senior engineer and asteroid spotter at Astro Imaging Systems

Martyn Lycett

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

D. Peschel wrote in message <69c99q$15li$1...@nntp6.u.washington.edu>...


>In article <6f2_980...@tegan.apana.org.au>,
>Ed Smeda <Ed.S...@tegan.apana.org.au> wrote:
>
>>I was alerted by a reader that there are problems associated
>>with self-modifying code.
>

>>While such code can't be ROMed, I don't see any other disadvantage.
>>Can anyone think of situations where this type of programming should
>>be avoided? The code is intended for CP/M type OS and its variants.
>

>Other "stock" reasons for not using self-modifying code are:
>
> - It makes the code non-reentrant (i.e., the code can't be shared
> by several running processes).
>
> - The CPU cache(s) and the code may interfere with each other.
>
>Plain CP/M doesn't multitask, though Concurrent CP/M does. The 8080
and Z-80
>CPUs don't have caches (as far as I know) though newer versions such
as the
>Z180 might.
>
>I have no experience with this sort of programming -- I'm just giving
a few
>standard answers. I do know that on the Macintosh (and probably the
PC),
>upgrades have caused sneaky code to stop working. Does your approach
save
>a lot of time? Is it significantly shorter? Are you sure there's
not another
>way to do the same thing?
>
>-- Derek

Another good reason not to use it is that it makes it almost
impossible to debug, especially for someone else coming to the code
some time after the initial write. Or even the original programmer
coming back to his own work some years later. If the original
documentation isnt totally comprehensive and extensive, (and who ever
bothers doing that? come on, own up! no-one!) then doing a disassembly
of the code gives a new result each time. Or at least, not a
consistent result each time.

I once read a programming textbook which said: "Self modifying code
isn't clever and it isn't funny. Just don't do it.". I tend to agree.

Having said that, I did do it.......once!

And yes it worked first time, and has done ever since.

And no, I couldn't remember how the hell it worked if I had to
alter/debug it today.

I rest my case.


Martyn Lycett

--
z...@ogvagrearg.pbz (ROT 13)
*********************************************************************
Sorry, but the battle against spam goes on and on.
Just unscramble the above email ROT 13 if you want to get hold of me.
*********************************************************************


Jeff Jonas

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

>>>I was alerted by a reader that there are problems associated
>>>with self-modifying code.

>>>While such code can't be ROMed, I don't see any other disadvantage.
>>>Can anyone think of situations where this type of programming should
>>>be avoided? The code is intended for CP/M type OS and its variants.

>>Other "stock" reasons for not using self-modifying code are:

.... It makes the code non-reentrant
.... cache & pipeline incoherency

>Another good reason not to use it is that it makes it almost
>impossible to debug, especially for someone else coming to the code
>some time after the initial write. Or even the original programmer
>coming back to his own work some years later. If the original
>documentation isnt totally comprehensive and extensive, (and who ever
>bothers doing that? come on, own up! no-one!) then doing a disassembly
>of the code gives a new result each time. Or at least, not a
>consistent result each time.

*groan* I'm working up a web page of such stuff, for I've done
self-modifying code just to test the various CPUs & architectures.
The IBM 360/370 kinda legitimized self modifying code with the
"execute" instruction that takes an instruction, "OR"s the second byte
with a data field and THEN executes the modified instruction.
The 2nd byte was USUALLY the literal length, thus allowing
variable lengths for memory operations.
The LGP/21 allowed the result of an artithmetic operation to go
directly to the instruction register to get executed immediately.
Similarly the CPU on the General Instrument's AN/ALR 66 processor
allowed the instruction register as a target/result of the ALU.
The *only* case I could ALMOST justify using that ability was to
search 2 tables against each other, modifying the literal address
to in effect have 2 index registers at once for dual address instructions
such as compare or move.

>I once read a programming textbook which said: "Self modifying code
>isn't clever and it isn't funny. Just don't do it.". I tend to agree.

Ya, but with the IBM 360's "execute" instruction, it's so conveeeeenient!

>Having said that, I did do it.......once!

I probably did it once for real (360 program: propagate a
byte across a variable length field with one "ex" executing the
move character instruction), the other times just for testing & play.

>And yes it worked first time, and has done ever since.

>And no, I couldn't remember how the hell it worked if I had to
>alter/debug it today.

With the 360/370 systems, debugging consisted of a port-mortem dump,
so all was well :-)
--
Jeffrey Jonas
jeffj@panix(dot)com
Meow? PRR PRR PRR !

KFergason

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

In article <69e2km$h9s$1...@mendelevium.btinternet.com>, "Martyn Lycett"
<z...@ogvagrearg.pbz> writes:

>I once read a programming textbook which said: "Self modifying code isn't

>clever and it isn't funny. Just don't do it.". I tend to agree. Having said


>that, I did do it.......once!

And yes it worked first time, and has done


>ever since. And no, I couldn't remember how the hell it worked if I had
>to alter/debug it today.

>I rest my case.

The original author of this thread said he was doing this on a CP/M machine,
which implies 8080/Z80. I can make no claims there.

However, on the 6502, self modifying code was pretty normal in indexing
the loops. And, it isn't difficult to understand.

I know code similar to below is in many commodore and apple II games.

Kelly
ps. (i haven't coded 6502 in years, so no flak about the code)

lda #60
sta #>index+2
lda #0
sta #<index+1
ldx #4
ldy #0
index sta $6000,y
iny
bne index
inc index+2
dex
bne index
# ok, we are done. we have cleared 4 pages of memory.

Axel Berger

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

*Ed Smeda* wrote on Fri, 98-01-09 07:06 in comp.os.cpm:
ES> LD (PATCH),A
ES> .
ES> .
ES> .
ES> LD (HL),0
ES>PATCH EQU $-1

I may be somewhat thick (in fact I'm sure I am) but I can't see how
this code modifies itself at all. Can you help me?

Danke
Axel

Les Hildenbrandt

unread,
Jan 13, 1998, 3:00:00 AM1/13/98
to

A few years ago I discovered that Spellstar 3.3 for DOS no longer
worked on a 486. It had worked on 8088, 286, 386.
After several days of debuging i found the problem to be a piece of
self modifying code. On the 486 the instruction queue was long enough
that the code was allready in the queue before it was modified.

I think in terms of copy protection and encryption self modifying code
has its use, bot not in normal programming.

Bruce Morgen

unread,
Jan 13, 1998, 3:00:00 AM1/13/98
to

Axel_...@k2.maus.de (Axel Berger) wrote:

Whatever is in A when the first instruction
is executed will be stored wherever HL
points to when the last instruction executes.
For example, if A contains 0FFh when the
first instruction executes, the last
instruction will be patched to "LD (HL),0FFh"
-- clear enough?


Tim Mann

unread,
Jan 13, 1998, 3:00:00 AM1/13/98
to

In article <69e6g9$a...@panix.com>, je...@panix.com (Jeff Jonas) writes:
>>>>I was alerted by a reader that there are problems associated
>>>>with self-modifying code.
>
>>>>While such code can't be ROMed, I don't see any other disadvantage.
>>>>Can anyone think of situations where this type of programming should
>>>>be avoided? The code is intended for CP/M type OS and its variants.

I worked on the LDOS operating system for the TRS-80 Model I and III,
both Z-80 based machines. Self-modifying code was a way of life for
us. We used it to save memory -- with only 64K of address space, as
much as possible of which needed to be set aside for user programs,
every byte was precious. The self-modifying code was not usually hard
to understand in a disassembly, because it all used a few simple,
standard tricks.

The most common was to store a value into the data field of a LD
instruction (or the like) later in the code stream. That saved two
bytes and ran a tiny bit faster.

Another trick, which I can recall using in only one place, was to
store a couple of instructions into the middle of a routine to change
its function. We did that in a floppy disk driver to change between
reading, writing, and verifying (reading and discarding the data); the
routines to do those things differed only in two instructions.

I recall another place where during booting, a particular routine
needed to be called before the system was ready to enable interrupts.
Later, the routine needed to disable and reenable interrupts in a
small critical section. So the EI instruction was initially loaded as
a NOP, and it was changed to an EI later at the end of the bootstrap.

--
Tim Mann <ma...@pa.dec.com>
http://www.research.digital.com/SRC/personal/Tim_Mann/

JWillard44

unread,
Jan 13, 1998, 3:00:00 AM1/13/98
to

Whatever is said about how evil self-modifying code is, there was a time
when it was necessary. Some early mini-computers required it. For instance,
the PDP-8 jump to a subroutine instruction placed the return address in the
location of the call and began execution at the next location.
Sometimes when execution time is critical, or memory space is severely
limited, self-modifying code is necessary. Picture a situation where a
subroutine must be executed the first time a routine is called after being
loaded. Rather than keeping a flag which must be cleared before the first
execution, set afterwards, and checked everytime since, the subroutine call can
be compiled in and over written with a no-op when the routine is executed. The
overhead then becomes only the time to execute a no-op each time the routine is
called, instead of a flag test that required external logic to set up and
maintain.
It is true that there are dangers in self-modifying code. As processors
become faster and memories become bigger, it becomes a trade-off. But, take
too many trade-offs, and your computer, which has more computing power, memory,
and disk space than a service bureau of 15 years ago, takes two minutes to open
a new window and 5 minutes to sign on to AOL.

Roger Ivie

unread,
Jan 13, 1998, 3:00:00 AM1/13/98
to

In article <19980113223...@ladder01.news.aol.com>, jwill...@aol.com (JWillard44) writes:
> Whatever is said about how evil self-modifying code is, there was a time
> when it was necessary. Some early mini-computers required it. For instance,
> the PDP-8 jump to a subroutine instruction placed the return address in the
> location of the call and began execution at the next location.

Gosh, that's funny; when the Z80 makes a subroutine call it _also_ stuffs
a return address in memory and then begins executing somewhere else.

You usually don't try to execute the return address, so it's not usually
self-modifying _CODE_. It is a bit of a pain if you want to call subroutines
in ROM, though...
--
-------------------------+------------------------------------------------
Roger Ivie | Impeach Bob Palmer!
iv...@cc.usu.edu |
http://cc.usu.edu/~ivie/ |

William J. Leary Jr.

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

Roger Ivie wrote in message ...

>In article <19980113223...@ladder01.news.aol.com>,
jwill...@aol.com (JWillard44) writes:
>> Whatever is said about how evil self-modifying code is, there was a
time
>> when it was necessary. Some early mini-computers required it. For
instance,
>> the PDP-8 jump to a subroutine instruction placed the return address in
the
>> location of the call and began execution at the next location.
>
> Gosh, that's funny; when the Z80 makes a subroutine call it _also_ stuffs
> a return address in memory and then begins executing somewhere else.
>
> You usually don't try to execute the return address, so it's not usually
> self-modifying _CODE_. It is a bit of a pain if you want to call
subroutines
> in ROM, though...


When the Z80 calls a subroutine it pushes the return address on the stack.
That's not self modifying code.

I think what the other guy was talking about was the return address being
inserted IN LINE with the subroutine when the call was made.

In that vein, another common use of self-modifying code on early mini's was
to generate an interrupt acknowledge instruction then stuff it into the
correct place to have it executed after it was built. This, of course,
created problems for ROM based code.

One mini I worked on (a General Automation, if memory serves me) went so far
as to have the ability to execute one of the registers. Thus, you built
your interrupt acknowledge instruction in the accumulator, then executed the
"EXECUTE ACCUMULATOR" instruction to execute your IntAck code. The machine
wasn't particular, though. You could put ANY sixteen bit instruction in the
accumulator and execute it.

- Bill


D. Peschel

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

In article <eREIOUOI9GA.91@upnetnews04>,

William J. Leary Jr. <Bill_...@msn.com> wrote:
>>In article <19980113223...@ladder01.news.aol.com>,
>>jwill...@aol.com (JWillard44) writes:

>>> For instance, the PDP-8 jump to a subroutine instruction placed the
>>> return address in the location of the call and began execution at the
>>> next location.

I've reformatted these lines.

>I think what the other guy was talking about was the return address being
>inserted IN LINE with the subroutine when the call was made.

Yes, that's right. The PDP-8 doesn't manage a stack automatically.
If you want one, your subroutines must create it by convention.

>One mini I worked on (a General Automation, if memory serves me) went so far
>as to have the ability to execute one of the registers. Thus, you built
>your interrupt acknowledge instruction in the accumulator, then executed the
>"EXECUTE ACCUMULATOR" instruction to execute your IntAck code. The machine
>wasn't particular, though. You could put ANY sixteen bit instruction in the
>accumulator and execute it.

What happened if you put an EXECUTE ACCUMULATOR instruction in the accumulator
and then encountered an EXECUTE ACCUMULATOR instruction in memory?

I added alt.folklore.computers because the readers might want to know about
this unusual instruction.

-- Derek

William J. Leary Jr.

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

D. Peschel wrote in message <69itau$i14$1...@nntp6.u.washington.edu>...

>What happened if you put an EXECUTE ACCUMULATOR instruction in the
accumulator
>and then encountered an EXECUTE ACCUMULATOR instruction in memory?


This was generally referred to as "hanging the computer."

In other words, yes, it executed the accumulator... and executed the
accumulator... and...

> I added alt.folklore.computers because the readers might want to know
about
> this unusual instruction.


Hey, I wasn't aware there WAS such a group. Thanks.

- Bill


Roger Ivie

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

In article <eREIOUOI9GA.91@upnetnews04>, "William J. Leary Jr." <Bill_...@msn.com> writes:
> Roger Ivie wrote in message ...
>> Gosh, that's funny; when the Z80 makes a subroutine call it _also_ stuffs
>> a return address in memory and then begins executing somewhere else.
>>
>> You usually don't try to execute the return address, so it's not usually
>> self-modifying _CODE_. It is a bit of a pain if you want to call
> subroutines
>> in ROM, though...
>
> When the Z80 calls a subroutine it pushes the return address on the stack.
> That's not self modifying code.
>
> I think what the other guy was talking about was the return address being
> inserted IN LINE with the subroutine when the call was made.

Yes, I know how subroutines work on the PDP-8. You usually don't execute
the return address. If you don't execute it, it's not code. Assembly
programs often have variables inline with and/or right next to code. You
don't think of those variables as being self-modifying code do you?

Don Yuniskis

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

In article <KzH1JX...@cc.usu.edu>, Roger Ivie <iv...@cc.usu.edu> wrote:
>In article <eREIOUOI9GA.91@upnetnews04>, "William J. Leary Jr." <Bill_...@msn.com> writes:
>> Roger Ivie wrote in message ...
>>> Gosh, that's funny; when the Z80 makes a subroutine call it _also_ stuffs
>>> a return address in memory and then begins executing somewhere else.
>>>
>>> You usually don't try to execute the return address, so it's not usually
>>> self-modifying _CODE_. It is a bit of a pain if you want to call
>> subroutines
>>> in ROM, though...
>>
>> When the Z80 calls a subroutine it pushes the return address on the stack.
>> That's not self modifying code.

[snip]

>Yes, I know how subroutines work on the PDP-8. You usually don't execute
>the return address. If you don't execute it, it's not code. Assembly
>programs often have variables inline with and/or right next to code. You
>don't think of those variables as being self-modifying code do you?

Well, that depends... :> I often write self-modifying code
for smaller processors since it usually saves me some space or
runtime. What you call "variables" (hmm... "constant variables"
perhaps? :>) are often prime examples of easy ways to write
what I would characterize as "self modifying code". I guess it
depends on where you draw the boundaries between "text" and "data".

For a somewhat related (yet very different) concept, I often
use the (Z80/8080/8085) code sequence:

INC HL
INC (HL)
JP NZ,CONTINUE_LOOP

DONE:

which implicitly relies on the object referenced at HL to reside in
read only memory. This technique has many similar perils to those
of self-modifying code.

--don

Herbert R Johnson

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

In article <69eog9$aer$1...@europa.frii.com>,
le...@frii.com (Les Hildenbrandt) wrote:
*>A few years ago I discovered that Spellstar 3.3 for DOS no longer
*>worked on a 486. It had worked on 8088, 286, 386.
*>After several days of debuging i found the problem to be a piece of
*>self modifying code. On the 486 the instruction queue was long enough
*>that the code was allready in the queue before it was modified.
*>

Facinating point! I don't know if some of the recent Z80 or other
8-bit processor implementations include instruction queues (caches) but
it is worth noting. Thanks!

HErb Johnson

Joe Nardone

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

In alt.folklore.computers William J. Leary Jr. <Bill_...@msn.com> wrote:
: D. Peschel wrote in message <69itau$i14$1...@nntp6.u.washington.edu>...

: >What happened if you put an EXECUTE ACCUMULATOR instruction in the
: accumulator
: >and then encountered an EXECUTE ACCUMULATOR instruction in memory?

: This was generally referred to as "hanging the computer."
: In other words, yes, it executed the accumulator... and executed the
: accumulator... and...

There's the 6502/10 bug as well, with indirect jumps on 256-byte
boundaries.... if your jump vector (a 2-byte field) started at
??FF, it would not look at (??+1)00, but ??00. OOps.

For example: By luck, your jump vector (for sake of relevance, say
the vector changed during the life of the program, but it doesn't
really matter) got placed at 09FF by the compiler/assembler. If
you executed a JMP (09FF) (as opposed to JMP 09FF, which would do
a direct jump) it would jump to the address contained in 09FF
(low byte) and _0900_ (hi byte), not 0A00.


Joe


--

+-----------------------------------------------------------------------
| If dolphins are so smart, then why do they live in igloos?
+-----------------------------------------------------------------------
| Joe Nardone <nar...@patriot.net> http://www.patriot.net/users/nardone

Robert Billing

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

In article <69itau$i14$1...@nntp6.u.washington.edu>
dpes...@u.washington.edu "D. Peschel" writes:

> What happened if you put an EXECUTE ACCUMULATOR instruction in the accumulator
> and then encountered an EXECUTE ACCUMULATOR instruction in memory?

Well, there was something similar in the DG Nova, and you could hang
the processor by doing it.

--
I am Robert Billing, Christian, inventor, traveller, cook and animal
lover, I live near 0:46W 51:22N. http://www.tnglwood.demon.co.uk/
"Bother," said Pooh, "Eeyore, ready two photon torpedoes and lock
phasers on the Heffalump, Piglet, meet me in transporter room three"

William J. Leary Jr.

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

Roger Ivie wrote in message ...
<Bill_...@msn.com> writes:
>> Roger Ivie wrote in message ...
>>> Gosh, that's funny; when the Z80 makes a subroutine call it _also_
stuffs
>>> a return address in memory and then begins executing somewhere else.
>>>
>>> You usually don't try to execute the return address, so it's not usually
>>> self-modifying _CODE_. It is a bit of a pain if you want to call
>> subroutines
>>> in ROM, though...
>>
>> When the Z80 calls a subroutine it pushes the return address on the
stack.
>> That's not self modifying code.
>>

>> I think what the other guy was talking about was the return address being
>> inserted IN LINE with the subroutine when the call was made.
>

>Yes, I know how subroutines work on the PDP-8. You usually don't execute
>the return address. If you don't execute it, it's not code. Assembly
>programs often have variables inline with and/or right next to code. You
>don't think of those variables as being self-modifying code do you?


No, of course not. My impression (which I apparently didn't express clearly
enough) was that you were talking about modifying "code space" which is what
many folks would consider "self modifying code."

To my mind that's not really self modifying code, it just having data space
interspersed with code space. Self modifying code is a bit more than that.
It requires that you in some way or other create or modify instructions then
insert them by some means into the execution stream.

One classic example from my DG Nova days was the way my boss handled a
multi-way jump. We extracted the target address from a table of addresses
based on a computation then stuffed the address in line after the JMP
opcode, then executed that JMP. To me THIS is self modifying code. The
other is just a memory organization issue.

- Bill


William J. Leary Jr.

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

>le...@frii.com (Les Hildenbrandt) wrote:
>A few years ago I discovered that Spellstar 3.3 for DOS no longer
>worked on a 486. It had worked on 8088, 286, 386.
>After several days of debuging i found the problem to be a piece of
>self modifying code. On the 486 the instruction queue was long enough
>that the code was allready in the queue before it was modified.


I ran into a vaguely similar problem on 68000 years back. We were trying to
debug via a logic analyzer and the damn thing kept trapping when we hadn't
executed the target instruction, which as the first instruction of a
subroutine. Turned out that the prefetch cache (only four bytes... or
words, don't recall exactly which) was prefetching the first word of the
target routine as it fetched the RET of the routine before it. We just
added a couple of NOOPs after the RET of the earlier routine to fix it, but
it was interesting to find.

- Bill


Tom Van Vleck

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

uncl...@tnglwood.demon.co.uk wrote:

> "D. Peschel" writes:
> > What happened if you put an EXECUTE ACCUMULATOR instruction in the
accumulator
> > and then encountered an EXECUTE ACCUMULATOR instruction in memory?
>
> Well, there was something similar in the DG Nova, and you could hang
> the processor by doing it.

The IBM 7094 had a similar problem with XEC *. One famous use of
this hang is described in http://www.best.com/~thvv/7094.html.
The GE-635 and its deescendants cured this problem; the CPU took a
"lockup" fault if an instruction took more than 16 ms.

Self-modifying code was common on the 7094 in the FMS days. I think
there were some incredibly ugly linkages associated with (IOB) and (IOH).

1401 subroutine linkage usually modified the code: subroutines did an SBR
into the return branch instruction, didn't they?

Multics introduced me to the idea of "pure procedure" meaning that
the instruction stream was in a read-only segment; the compilers
stored all writeable data in the stack or the procedure's linkage section.

OS/360 distinguished three kinds of program: reentrant (same as pure),
serially reusable (meaning that the program stored into itself while
running but put everything back when it finished), and i forget the name
of the third kind, but it meant it modified itself, so the supervisor
would have to fetch a fresh copy of the code from disk for each task.

William J. Leary Jr.

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

There's also the classic story of "Mel, a Real Programmer."

I've usually found that people who don't understand how that loop was exited
are the same people who have always used machines where you couldn't write
to code space and/or never programmed in assembler.

- Bill


Julian Thomas

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

In <thvv-15019...@thvv.vip.best.com>, on 01/15/98
at 12:02 AM, th...@best.com (Tom Van Vleck) said:

>OS/360 distinguished three kinds of program: reentrant (same as pure),
>serially reusable (meaning that the program stored into itself while
>running but put everything back when it finished), and i forget the name
>of the third kind, but it meant it modified itself, so the supervisor
>would have to fetch a fresh copy of the code from disk for each
>task.

Not quite. A program could be serially reusable or self-trashing (I don't
remember what it was called either) without modifying a byte of code. To
be reentrant, the program would need to getmain for all its working
storage. Any data areas in the program itself and it drops down to
serially reusable. Any counters in the program that are initialized to 0
when the program is loaded and not reset on exit makes it self-trashing.

--
Julian & Mary Jane Thomas
j...@epix.net http://www.epix.net/~jt
In the beautiful Finger Lakes Wine Country of New York State!
--------------------------------------------------
Why does the hardware keep getting faster, and the software slower?

JWillard44

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

iv...@cc.usu.edu (Roger Ivie) wrote:
>
>> I think what the other guy was talking about was the return address being
>> inserted IN LINE with the subroutine when the call was made.
>
>Yes, I know how subroutines work on the PDP-8. You usually don't execute
>the return address. If you don't execute it, it's not code. Assembly
>programs often have variables inline with and/or right next to code. You
>don't think of those variables as being self-modifying code do you?

If you forget to put the return instruction (PDP-8 used a jump indirect
instruction for this) at the end of the previous routine, then you executed the
address of the last call to the next routine. Then it was self-modified code.

Joel in Ogden

root@localhost

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to


On 1998-01-14 dpes...@u.washington.edu(D.Peschel) said:
-William J. Leary Jr. <Bill_...@msn.com> wrote:
->One mini I worked on (a General Automation, if memory serves me)
->went so far as to have the ability to execute one of the registers.
->Thus, you built your interrupt acknowledge instruction in the
->accumulator, then executed the "EXECUTE ACCUMULATOR" instruction
->to execute your IntAck code. The machine wasn't particular,
->though. You could put ANY sixteen bit instruction in the
->accumulator and execute it.

-What happened if you put an EXECUTE ACCUMULATOR instruction in the
-accumulator and then encountered an EXECUTE ACCUMULATOR instruction
-in memory?

hehe :> the ti9900 had one of these as well - it offered you a choice of
16 registers, though. we always fancied programming on one of those
beasts...

-- Communa (Com...@lisardrock.demon.net)
Don't just blindly reply. You'll talk to your sysop.

Net-Tamer V 1.09.2 - Test Drive

root@localhost

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to


On 1998-01-13 le...@frii.com(LesHildenbrandt) said:
-I think in terms of copy protection and encryption self modifying
-code has its use, bot not in normal programming.

we beg to differ. self-modifying code, for a start, is a great way of
identifying which of the x86 processors you have, for the reason you
just quoted. :> but also, for older processors, it saves a lot of time
and effort in terms of doing things the short way vs. the long way,
especially when your choices of addressing modes are nothing to write
home about and jumps are "free". the 6800 is a case in point. nowadays
we seem to be locked into a half-assed computer architecture that
requires all kinds of nasty internal-to-the-CPU tricks to get it to run
at a reasonable speed, and so not surprisingly self-modifying code is
discouraged.

one more thing. for fans of such tricks, a handy reference is the
document describing the Synthesis OS. god knows where we got it from,
and it's about 200 pages of postscript, but a web search should turn it
up. and it's a truly fascinating document. which leads on to the best
application for self-modifying code; self-executing data.

root@localhost

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to


On 1998-01-14 d...@rtd.com(DonYuniskis) said:
-Well, that depends... :> I often write self-modifying code
-for smaller processors since it usually saves me some space or
-runtime. What you call "variables" (hmm... "constant variables"
-perhaps? :>) are often prime examples of easy ways to write
-what I would characterize as "self modifying code". I guess it
-depends on where you draw the boundaries between "text" and "data".

for many 8 bit forths, the inner interpreter relied on self-modifying
code, since there wasn't a sensible way to do an indirect jump. the
6800 and 6502 spring to mind. (on the other hand, you probably didn't
need to use it anywhere else...)

Carl R. Friend

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

Shawn Sijnstra, in article nr. <34BE8B...@unsw.edu.au>, wrote:

>
> Robert Billing wrote:
> >
> > In article <69itau$i14$1...@nntp6.u.washington.edu>
> > dpes...@u.washington.edu "D. Peschel" writes:
> >
> > > What happened if you put an EXECUTE ACCUMULATOR instruction in
> > > the accumulator and then encountered an EXECUTE ACCUMULATOR

> > > instruction in memory?
> >
> > Well, there was something similar in the DG Nova, and you could
> > hang the processor by doing it.
>
> Was it a processor hang or a HALT equivalent instruction?

The DG processor in question wasn't the NOVA, but rather the
Eclipse. The result would appear like a hang in that the stop
switch wouldn't halt the CPU but the reset switch would.

Note, also, that an XCT of an XCT was interruptable by the I/O
system, so the processor doesn't "hang" (as in an infinite
indirection chain (without protection)), but merely "waits".

--
______________________________________________________________________
| | |
| Carl Richard Friend (UNIX Sysadmin) | West Boylston |
| Minicomputer Collector / Enthusiast | Massachusetts, USA |
| mailto:carl....@stoneweb.com | |
| http://www.ultranet.com/~engelbrt/carl/museum | ICBM: N42:22 W71:47 |
|________________________________________________|_____________________|

Axel Berger

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

*Bruce Morgen* wrote on Tue, 98-01-13 16:29 in comp.os.cpm:
BM>-- clear enough?

Nearly. I do not program assembler but have read a bit on it and was
confused by Z80 vs. 68000 mnemonics - source and destiny are the other
way round. But why is the "0" in the istruction overwritten and not the
meaningless byte at the "patch" location?

Danke
Axel

William J. Leary Jr.

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

> root@localhost wrote:
> > somebody else wrote


> > What happened if you put an EXECUTE ACCUMULATOR instruction in the
> > accumulator and then encountered an EXECUTE ACCUMULATOR instruction
> > in memory?
>

>hehe :> the ti9900 had one of these as well - it offered you a choice of
>16 registers, though. we always fancied programming on one of those
>beasts...


I loved the TI990 and TI9900 CPU architecture. Especially that those
"registers" were really in memory and you could get a new set of registers
at any moment. I always wanted a opportunity to program on one.

- Bill


William J. Leary Jr.

unread,
Jan 15, 1998, 3:00:00 AM1/15/98
to

> Don Yuniskis wrote in message <69mdie$p2s$1...@baygull.rtd.com>...

> > <root@localhost> wrote:
> >
>> for many 8 bit forths, the inner interpreter relied on self-modifying
>> code, since there wasn't a sensible way to do an indirect jump. the
>> 6800 and 6502 spring to mind. (on the other hand, you probably didn't
>> need to use it anywhere else...)
>
> On the contrary, you often need to do indirect jumps (e.g., through
> tables). Assuming you don't have something convenient like JP (HL),
> the classic approach is to push the target address (after fetching
> it from the specific memory location) and RET/RTN to that.


That worked great when the machine didn't have side effects to the return
instruction, like loading a stack frame rather that just copying the top of
the stack into the program counter. We use to use that approach on DG Nova
(or was it an Eclipse?) to do a computed jump via a subroutine. You called
this sub with a pointer to a table and a set of information on how to
compute the entry. After doing the computation, we went and replaced the
return address to the calling routine with the address we'd just extracted
from the table.

I seem to recall that one of us later actually read the instruction set in
detail and realized there was another way to do that jump (something like
jumping through a register or jumping through a memory location) but the
original designer had use this thing hundreds of places and it didn't seem
worth fixing.

- Bill

Shawn Sijnstra

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

Robert Billing wrote:
>
> In article <69itau$i14$1...@nntp6.u.washington.edu>
> dpes...@u.washington.edu "D. Peschel" writes:
>
> > What happened if you put an EXECUTE ACCUMULATOR instruction in the accumulator
> > and then encountered an EXECUTE ACCUMULATOR instruction in memory?
>
> Well, there was something similar in the DG Nova, and you could hang
> the processor by doing it.
>
> --

Was it a processor hang or a HALT equivalent instruction?


Cheers,
Shawn

Don Yuniskis

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

In article <884903276.19939.6...@news.demon.co.uk>,

<root@localhost> wrote:
>
>for many 8 bit forths, the inner interpreter relied on self-modifying
>code, since there wasn't a sensible way to do an indirect jump. the
>6800 and 6502 spring to mind. (on the other hand, you probably didn't
>need to use it anywhere else...)

On the contrary, you often need to do indirect jumps (e.g., through
tables). Assuming you don't have something convenient like JP (HL),
the classic approach is to push the target address (after fetching
it from the specific memory location) and RET/RTN to that.

--don

D. Peschel

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

In article <199801151...@k2.maus.de>,
Axel Berger <Axel_...@k2.maus.de> wrote:

>Nearly. I do not program assembler but have read a bit on it and was
>confused by Z80 vs. 68000 mnemonics - source and destiny are the other
>way round. But why is the "0" in the istruction overwritten and not the
>meaningless byte at the "patch" location?

There is no meaningless byte. PATCH is defined to be the address of the 0.

The code says something like this:

...
ld (HL), 0
PATCH equ $-1
...

The assembler encounters the ld instruction and puts a couple of bytes in
memory (hex 46 00, unless I screwed up). The counter which marks where the
next instruction should go points to the location after the 00. The "equ"
line defines PATCH to refer to an address (specifically, the address currently
in the counter, minus one). So PATCH ends up referring to the address in
memory where the 00 has been put.

-- Derek

Clarence Wilkerson

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to Axel Berger

The convention in some assemblers was that $ was the current
position ( address). So $-1 means one byte before the
"Patch" location.

--
Clarence Wilkerson \ HomePage: http://www.math.purdue.edu/~wilker
Prof. of Math. (topology)\ Internet: wil...@math.purdue.edu
Dept. of Mathematics \ Messages: (765) 494-1903, FAX 494-0548
Purdue University, \ Office: (765) 494-1955 (voice/phonemail)
W. Lafayette, IN 47907-1395 \ Rm. 450 Math. Sci. Bldng.

George R. Gonzalez

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

On the PDP-8, the instruction to switch to another 4K bank of memory had
the bank number built into the instruction. So every time you wanted to
access anything outside your current 4K bank, you had to go modify an
instruction a few steps ahead of yourself. Wasnt a huge problem, as any
good programmer kept as much data as possible in the current bank, or in
a fixed bank.

Sounds impossible nowadays, but we were not too constrained by the 4K
bank size. You just did things in smaller chunks and used the hard disk
a lot. Memory then was, from a off-brand source, about $3000 for 8K, so
getting a lot of memory wasnt an option for most users. The real 4K
banks from DEC were much more expensive.

William Robison

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

George R. Gonzalez wrote:
>
> On the PDP-8, the instruction to switch to another 4K bank of memory had
> the bank number built into the instruction. So every time you wanted to
> access anything outside your current 4K bank, you had to go modify an
> instruction a few steps ahead of yourself.

Old Univac 418 was similar. 4K Page absolute addressing with a
Special Regiater to select 1 or 16 (or 32) pages. Some instructions
were "SR Sensitive" (i.e. would use the SR as part of the upper address.
Only way to load the SR was with a constant in the instruction.
To access large table one had to build an "LSR K" instruction
and place into the executing program...

-Willy

David Director

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

D. Peschel wrote:

[ snip ]

>
> The code says something like this:
>
> ...
> ld (HL), 0
> PATCH equ $-1
> ...
>

[ snip ]

Actually, there was a convention often used to highlight situations
like this. Instead of:

ld (HL), 0
...

you would write:

ld (HL), $-$
...

The $-$ would, of course, translate to zero; but the "$-$" usage
was a visual signal that something was to be plugged in here at
runtime.

-- David

Robert Billing

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

In article <34BE8B...@unsw.edu.au>
S.Sij...@unsw.edu.au "Shawn Sijnstra" writes:

> Was it a processor hang or a HALT equivalent instruction?

Now I've had time to remember this one, the Nova used 16 bit pointers
to data, and had no byte addressing, so for a max 32k x 16 bit size it
only needed 15 bits to address the lot. It used the top bit as an
indirection marker, meaning interpret the bottom bits as pointer to
pointer. However if you created a circular pointer chain early Novas
would hang, endlessly redirecting. Later models had a timeout of some
kind.

It was, in many respects, a nice design, killed by some dreadful
misfeatures. I remember its being a bit of a let down after the
PDP-11/40 I had been using before.

David Director

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

[snip]...

> you built your interrupt acknowledge instruction in the

> accumulator, then executed the "EXECUTE ACCUMULATOR" instruction

> to execute your IntAck code. The machine wasn't particular,

> though. You could put ANY sixteen bit instruction in the
> accumulator and execute it.
>

[snip]

Actually, my favorite instruction was not the "EXECUTE ACCUMULATOR",
but the "EXECUTE PROGRAMMER IMMEDIATE" (EPI) ;-)

-- David

JWillard44

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

d...@rtd.com (Don Yuniskis) wrote:
>On the contrary, you often need to do indirect jumps (e.g., through
>tables). Assuming you don't have something convenient like JP (HL),
>the classic approach is to push the target address (after fetching
>it from the specific memory location) and RET/RTN to that.

Assumes a stack is available. The stack is a relatively recent innovation
in computing. The IBM 360 didn't have it, and that series of processors were
responsible for the acceptance of computers into modern life. The PDP-8, the
original Nova, the IBM system/3,34,36 didn't have it. The General Automation
(SPC-12, 16) didn't have it either.
While the stack makes keeping track of variables and status during
interrupts rather easy and safe, it adds to the interrupt service latency time.
To think that a processor with the processing power of a 80386, let alone a
new Pentium II with MMx is insufficient to enable it to respond to each
character as it comes in over the serial line is mind bogling

William J. Leary Jr.

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

David Director wrote in message <34BFA0...@sungardams.com>...


>Actually, my favorite instruction was not the "EXECUTE ACCUMULATOR",
>but the "EXECUTE PROGRAMMER IMMEDIATE" (EPI) ;-)


Sure, but now we're moving off into the area of instructions the computer
SHOULD have rather than just the ones they DO/did have.

My favorite of the ones we need is Do What I Mean (DWIM). Would save piles
of programmer effort.

- Bill


Carl R. Friend

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

Robert Billing, in article nr. <884959...@tnglwood.demon.co.uk>,
wrote:

>
> In article <34BE8B...@unsw.edu.au>
> S.Sij...@unsw.edu.au "Shawn Sijnstra" writes:
>
> > Was it a processor hang or a HALT equivalent instruction?
>
> Now I've had time to remember this one, the Nova used 16 bit pointers
> to data, and had no byte addressing, so for a max 32k x 16 bit size it
> only needed 15 bits to address the lot.

True, the address space of the Nova was 15 bits wide. There was the
programmers' notion of a byte pointer in which bit 15 (LSB) was used
to address to octet level (following a 1-bit rotate-right). However,
if a word was accessed, as part of an indirection chain, that had bit
zero set the result was another indirect access and defer cycle.
Hitting raw "byte pointers" was a no-no for Nova programmers, and they
knew it.

> It used the top bit as an indirection marker, meaning interpret the
> bottom bits as pointer to pointer.

This is discrete from byte-pointers.

> However if you created a circular pointer chain early Novas would
> hang, endlessly redirecting. Later models had a timeout of some
> kind.

This was usually implemented as part of the memory-management, or
MAP, option. Indirections deeper than 16 levels caused a trap.

> It was, in many respects, a nice design, killed by some dreadful
> misfeatures. I remember its being a bit of a let down after the
> PDP-11/40 I had been using before.

Beauty in in the eye of the beholder. DG took a RISC approach
to CPU design in the 16-bit world and DEC took the CISC tack. In
terms of raw horsepower, the DG iron was usually "hotter" than the
equivalent DEC offering, but that may have been due to its simple
nature.

I used DG and DEC machines for years, still have a bunch of them,
and love and admire both architectures.

Cheers.

Julian Thomas

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

In <Og0bNLrI9GA.302@upnetnews04>, on 01/16/98
at 02:14 PM, "William J. Leary Jr." <Bill_...@msn.com> said:

>Sure, but now we're moving off into the area of instructions the computer
>SHOULD have rather than just the ones they DO/did have.

>My favorite of the ones we need is Do What I Mean (DWIM). Would save
>piles of programmer effort.

Actually, the DE-OR instruction would have wiped out the disk drive
business on day 1!



--
Julian & Mary Jane Thomas
j...@epix.net http://www.epix.net/~jt
In the beautiful Finger Lakes Wine Country of New York State!
--------------------------------------------------

A flying saucer results when a nudist spills his coffee.

Robert Billing

unread,
Jan 16, 1998, 3:00:00 AM1/16/98
to

In article <#4CgtOjI9GA.214@upnetnews04>

Bill_...@msn.com "William J. Leary Jr." writes:

> I loved the TI990 and TI9900 CPU architecture. Especially that those
> "registers" were really in memory and you could get a new set of registers
> at any moment. I always wanted a opportunity to program on one.

I have. Oh deary, deary, me. As CSL said, "Things of extreme evil
which have the appearance of innocence to the uninitiated."

Take the 99105 as a case in point.

MOVB (R2)+, (R3)+

This one instruction generates...

Fetch Opcode
Fetch R2
Save R2 incremented
Fetch R3
Save R3 incremented
Fetch source operand
Fetch destination operand
Store destination operand

...no less than *eight* bus cycles (the last two are the way they are
because it can only address memory as 16 bit words, so to store a byte
it has to do a read modify write). The first time I saw that I thought
I'd broken the logic analyser.

Either it used a register cache (as the 990 did) in which case it was
just any old processor, or it didn't, as the 99105 and 99110 were, and
it did about twice as many external cycles as anything else.

I have managed to force real time operation out of them, but only at
the expense of code which goes about ringing a bell and saying,
"unclean, unclean." Think about what you can do with two register sets
that *partially* overlap...

Linards Ticmanis

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to

On Thu, 15 Jan 1998 root@localhost wrote:
> for many 8 bit forths, the inner interpreter relied on self-modifying
> code, since there wasn't a sensible way to do an indirect jump. the
> 6800 and 6502 spring to mind. (on the other hand, you probably didn't
> need to use it anywhere else...)

Wasn't a JSR chain a sensible and fast method ?


Linards Ticmanis

Les Hildenbrandt

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to

Actualy this was spellstar for the 8086-
I am working on a z380 design now and the z380 does have a instruction
queue

hjoh...@pluto.njcc.com (Herbert R Johnson) wrote:

>In article <69eog9$aer$1...@europa.frii.com>,
>le...@frii.com (Les Hildenbrandt) wrote:
>*>A few years ago I discovered that Spellstar 3.3 for DOS no longer
>*>worked on a 486. It had worked on 8088, 286, 386.
>*>After several days of debuging i found the problem to be a piece of
>*>self modifying code. On the 486 the instruction queue was long enough
>*>that the code was allready in the queue before it was modified.
>*>

>Facinating point! I don't know if some of the recent Z80 or other
>8-bit processor implementations include instruction queues (caches) but
>it is worth noting. Thanks!

>HErb Johnson

> **** ------------------------------------------------------ ****

>Herbert R. Johnson voice/FAX 609-771-1503 day/nite
>hjoh...@pluto.njcc.com Ewing, in central New Jersey, USA

> amateur astronomer and astro-tour guide
> supporter of classic S-100 computers as "Dr. S-100"
> rebuilder of Mac Plus computers for your computing pleasure
> and senior engineer and asteroid spotter at Astro Imaging Systems

root@localhost

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to


On 1998-01-15 Axel_...@k2.maus.de(AxelBerger) said:
-Nearly. I do not program assembler but have read a bit on it and was
-confused by Z80 vs. 68000 mnemonics - source and destiny are the
-other way round. But why is the "0" in the istruction overwritten
-and not the meaningless byte at the "patch" location?

EQU doesn't define a memory byte, it merely sets the value of a label.
thus,

alterme EQU $-1

actually sets the label alterme to point to the byte just before the
next location to be compiled, which is the last byte of LD (HL), 0.

hope this helps. we made the same mistake on first reading the code.

root@localhost

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to


On 1998-01-16 d...@rtd.com(DonYuniskis) said:
->for many 8 bit forths, the inner interpreter relied on
->self-modifying code, since there wasn't a sensible way to do an
->indirect jump. the 6800 and 6502 spring to mind. (on the other
->hand, you probably didn't need to use it anywhere else...)

-On the contrary, you often need to do indirect jumps (e.g., through
-tables). Assuming you don't have something convenient like JP (HL),
-the classic approach is to push the target address (after fetching
-it from the specific memory location) and RET/RTN to that.

sorry, we should clarify - we meant within the forth system on that
particular processor. we didn't mean in general. yes, indirect / table
jumps are remarkably common, and by far the most efficient way to do a
lot of things. and yes, SMC was almost necessary to do them on 8 bit
architectures.

root@localhost

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to


On 1998-01-16 uncl...@tnglwood.demon.co.uk said:
-I have. Oh deary, deary, me. As CSL said, "Things of extreme evil
-which have the appearance of innocence to the uninitiated."

-Take the 99105 as a case in point.

-MOVB (R2)+, (R3)+

-This one instruction generates...
-Fetch Opcode
-Fetch R2
-Save R2 incremented
-Fetch R3
-Save R3 incremented
-Fetch source operand
-Fetch destination operand
-Store destination operand

-...no less than *eight* bus cycles (the last two are the way they
-are because it can only address memory as 16 bit words, so to store
-a byte it has to do a read modify write). The first time I saw that
-I thought I'd broken the logic analyser.

hehe. :> on the other hand, so long as you know the limitations, it's
not a problem. back when, memory could keep up with the processor. and
at least you don't have an instruction fetch in between every single
word. besides, memory doesn't wear out...? it could be a bit of a
problem for cycle-stealing DMA (hey! no cycles to steal! :< ) but what
the hell.

-Either it used a register cache (as the 990 did) in which case it
-was just any old processor, or it didn't, as the 99105 and 99110
-were, and it did about twice as many external cycles as anything
-else.

well, the register cache would speed things up, but you still get to
switch the register set (and then only update them, do the external
memory thing, when you actually first read the registers). it still
looks to us like the treats outweigh the tricks.

-I have managed to force real time operation out of them, but only at
-the expense of code which goes about ringing a bell and saying,
-"unclean, unclean."

*giggle*

-Think about what you can do with two register
-sets that *partially* overlap...

much the same as on a sparcstation, we'd imagine... what's the problem?
ok, so it's not the fastest architecture in the west, but hell, nor was
the 8086. and analyses showed that typical ti code was smaller and
faster on average than typical intel 8086 code.

also, think of the interrupt latency!

William J. Leary Jr.

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to

Julian Thomas wrote in message <34bfc551$1$wg$mr2...@news.epix.net>...


>Actually, the DE-OR instruction would have wiped out the disk drive
>business on day 1!


Ya see something new every day.

I'll bite... what's DE-OR ?

- Bill


john r pierce

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to

jwill...@aol.com (JWillard44) wrote:

> Whatever is said about how evil self-modifying code is, there was a time
>when it was necessary. Some early mini-computers required it. For instance,
>the PDP-8 jump to a subroutine instruction placed the return address in the
>location of the call and began execution at the next location.

The IBM 1130 did this too. Its subroutine call was 'BSI' (branch and store
index), which stored the return address at the first word of the subroutine, and
branched to the 2nd word. the return instruction was a (grr, mnemonic
forgotten, "BR I" ?) Branch Indirect off the entry point. Anyone wanting to do
recursion had to go to great lengths to retrieve this return address and
manually build a stack with it.

I believe the 1130 predated the PDP8 by a few years (it was introducted in 1964,
I believe), but in fact, even the 1130 inherited this behavior from prior IBM
systems (1620? 70xx?)

-jrp

----------------------------------------------------------------------
This posting has a invalid email address to discourage bulk emailers
Due to the ever increasing volumes of spam, I do not mix mail and news
----------------------------------------------------------------------

john r pierce

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to

"William J. Leary Jr." <Bill_...@msn.com> wrote:

>>le...@frii.com (Les Hildenbrandt) wrote:
>>A few years ago I discovered that Spellstar 3.3 for DOS no longer

>>worked on a 486. It had worked on 8088, 286, 386.

>>After several days of debuging i found the problem to be a piece of

>>self modifying code. On the 486 the instruction queue was long enough

>>that the code was allready in the queue before it was modified.
>
>

>I ran into a vaguely similar problem on 68000 years back. We were trying to
>debug via a logic analyzer and the damn thing kept trapping when we hadn't
>executed the target instruction, which as the first instruction of a
>subroutine. Turned out that the prefetch cache (only four bytes... or
>words, don't recall exactly which) was prefetching the first word of the
>target routine as it fetched the RET of the routine before it. We just
>added a couple of NOOPs after the RET of the earlier routine to fix it, but
>it was interesting to find.

Even on the 8086/8088, the convention was to do a JMP between modifying code and
executing it, as this would guarantee flushing of the prefetch queue.

Speaking of self modifying code... An extreme case was used in MS Windows 1.x,
2.x, and 3.x 'BitBlt' routines in the standard VGA driver and most derivatives.
Since BitBlt had 256 possible ROP (raster operation) codes, 4 possible source
types (none, mono memory, color memory, and screen), 3 possible destination
types (mono, color, screen), and 4 types of patterns (none, solid, mono dither,
color brush), not to mention a variety of bit alignment combinations for the bit
packed source and destinations, the display driver would 'compile' an optimized
sequence of instructions onto a block of the stack frame, then execute this.
Quite a few optimizations were applied to this process, such as unwinding the
inner bytes, folding out common subexpressions, recognizing all 0 and all 1
brushes as identity operations, etc. Since the cycle time of early CGA/EGA/VGA
class adapters was SO slow, anything to minimize the number of display memory
accesses helped significantly.

Julian Thomas

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to

In <O6#3uZwI9GA.263@upnetnews03>, on 01/17/98
at 12:12 AM, "William J. Leary Jr." <Bill_...@msn.com> said:

>Ya see something new every day.

>I'll bite... what's DE-OR ?

A or B -> C # standard boolean or.

C deor A,B # inverse operation



--
Julian & Mary Jane Thomas
j...@epix.net http://www.epix.net/~jt
In the beautiful Finger Lakes Wine Country of New York State!
--------------------------------------------------

OS/2: Windows with bullet-proof glass.

Axel Berger

unread,
Jan 17, 1998, 3:00:00 AM1/17/98
to

Thanks to all the nice people who had patience with me and mailed
ecplanations. I've got it now.

It was LD (PATCH) A
and not LD PATCH,A

and EQU $-1
is not the same as EQU 0FFH

a byte just to fill the space but puts the adress of the location
*before* patch at location patch.
Thank you for your patience, I want to learn Z80 as soon as I find the
space to display my collection of old hardware, thus my
(uncomprehending) interest in the posted puzzles.

Danke
Axel

William J. Leary Jr.

unread,
Jan 18, 1998, 3:00:00 AM1/18/98
to

Julian Thomas wrote in message <34c14662$1$wg$mr2...@news.epix.net>...


>A or B -> C # standard boolean or.
>
>C deor A,B # inverse operation


Oh, un-or. un-do logical or.

Cute.

- Bill


sp...@lisardrock.demon.co.uk

unread,
Jan 19, 1998, 3:00:00 AM1/19/98
to


On 1998-01-17 lo...@signature.lines(EdmundH.Ramm) said:
[re. forth inner interpreters: self-mod?]
-Not on the Z80:
-Nor on the Z280:

we know. nor the 6809, for that matter. (and i think you could get away
without on the 1802 too.) but the 6502 has no 16-bit registers, hence
you need to shove the address in a JMP, and the 6800 has only one index
register, which is needed for other things.

but this discussion would be better held in comp.lang.forth... :>

incidentally, what are the smallest/fastest inner interpreter designs
for any given architecture? (we mean the classical indirect-threading
variety here.) and was there ever a decent forth for the PDP8?


-- Communa - all at lisardrock.demon.net
to be sure we read your reply, send to username `communa'

Don Yuniskis

unread,
Jan 20, 1998, 3:00:00 AM1/20/98
to

In article <19980116190...@ladder02.news.aol.com>,

JWillard44 <jwill...@aol.com> wrote:
>d...@rtd.com (Don Yuniskis) wrote:
>>On the contrary, you often need to do indirect jumps (e.g., through
>>tables). Assuming you don't have something convenient like JP (HL),
>>the classic approach is to push the target address (after fetching
>>it from the specific memory location) and RET/RTN to that.
>
> Assumes a stack is available. The stack is a relatively recent innovation
>in computing. The IBM 360 didn't have it, and that series of processors were
>responsible for the acceptance of computers into modern life. The PDP-8, the

They are also decades old. :> As far as I know, any of the CPUs
running CP/M have at least one conventional pushdown stack.

>original Nova, the IBM system/3,34,36 didn't have it. The General Automation
>(SPC-12, 16) didn't have it either.
> While the stack makes keeping track of variables and status during
>interrupts rather easy and safe, it adds to the interrupt service latency time.
> To think that a processor with the processing power of a 80386, let alone a
>new Pentium II with MMx is insufficient to enable it to respond to each
>character as it comes in over the serial line is mind bogling

A *native* x86 can easily do this. Don't confuse an x86 burdened
by the braindamage of a toy operating system (i.e. anything with
the initials MS in its name) with the genuine hardware itself.

--don

William Robison

unread,
Jan 21, 1998, 3:00:00 AM1/21/98
to

In article <19980116190...@ladder02.news.aol.com>,

> > To think that a processor with the processing power of a 80386, let alone a
> >new Pentium II with MMx is insufficient to enable it to respond to each
> >character as it comes in over the serial line is mind bogling

Don Yuniskis wrote:
> A *native* x86 can easily do this. Don't confuse an x86 burdened
> by the braindamage of a toy operating system (i.e. anything with
> the initials MS in its name) with the genuine hardware itself.

Well, the old Z80 (disguised as a 64180), running at 9 Mhz
has no problems keeping up with a 55,000 synchrounous data stream
(more or less equivalent of a 68,000 async connection with gaps
between characters...)

-Willy

Don Yuniskis

unread,
Jan 21, 1998, 3:00:00 AM1/21/98
to

In article <34C61B29...@uiowa.edu>,

I routinely have Z180's maintain four 19.2K UARTs without
problems -- but the original comment pertained to 386's...

--don

Allen J. Baum

unread,
Jan 21, 1998, 3:00:00 AM1/21/98
to

In article <884803...@tnglwood.demon.co.uk>,
uncl...@tnglwood.demon.co.uk wrote:

> In article <69itau$i14$1...@nntp6.u.washington.edu>
> dpes...@u.washington.edu "D. Peschel" writes:
>
> > What happened if you put an EXECUTE ACCUMULATOR instruction in the
accumulator
> > and then encountered an EXECUTE ACCUMULATOR instruction in memory?
>
> Well, there was something similar in the DG Nova, and you could hang
> the processor by doing it.

You could infinitely indirect on other processors as well, but
the HP2100 would trap on more than 16 levels, I think (or was that the Nova?)

--
***********************************************
* Allen J. Baum *
* Digital Semiconductor *
* 181 Lytton Ave. *
* Palo Alto, CA 94306 *
***********************************************

Allen J. Baum

unread,
Jan 21, 1998, 3:00:00 AM1/21/98
to

In article <34BF99C9...@uiowa.edu>, William Robison
<william...@uiowa.edu> wrote:

The HP35 calculator had a branch instruction to change the low bits of the
PC, and a setbank to set the upper. So, a setbank would branch from
address
Xzzzzz to Yzzzzz+1; you had to locate you code segments verrry carefully.

Jerry Avins

unread,
Jan 22, 1998, 3:00:00 AM1/22/98
to

Roger Ivie wrote:

>
> In article <19980113223...@ladder01.news.aol.com>, jwill...@aol.com (JWillard44) writes:
> > Whatever is said about how evil self-modifying code is, there was a time
> > when it was necessary. Some early mini-computers required it. For instance,
> > the PDP-8 jump to a subroutine instruction placed the return address in the
> > location of the call and began execution at the next location.
>
> Gosh, that's funny; when the Z80 makes a subroutine call it _also_ stuffs
> a return address in memory and then begins executing somewhere else.

Yeah, but that memory is stack...
>
> You usually don't try to execute the return address, so it's not usually
> self-modifying _CODE_. It is a bit of a pain if you want to call subroutines
> in ROM, though...

and I never did figure out how to put stack in ROM!
> --
> -------------------------+------------------------------------------------
> Roger Ivie | Impeach Bob Palmer!
> iv...@cc.usu.edu |
> http://cc.usu.edu/~ivie/ |

I think I asked you once, but I forget. Who is Bob Palmer?

Jerry
--
Remove "X" from the address to reply to <jya...@ibm.net>

Engineering is the art
of making things you want
from things you can get.

Jerry Avins

unread,
Jan 22, 1998, 3:00:00 AM1/22/98
to

Shawn Sijnstra wrote:

>
> Robert Billing wrote:
> >
> > In article <69itau$i14$1...@nntp6.u.washington.edu>
> > dpes...@u.washington.edu "D. Peschel" writes:
> >
> > > What happened if you put an EXECUTE ACCUMULATOR instruction in the accumulator
> > > and then encountered an EXECUTE ACCUMULATOR instruction in memory?
> >
> > Well, there was something similar in the DG Nova, and you could hang
> > the processor by doing it.
> >
> > --

>
> Was it a processor hang or a HALT equivalent instruction?
>
> Cheers,
> Shawn

I have a NOVA manual if you want to look.

Jerry Avins

unread,
Jan 22, 1998, 3:00:00 AM1/22/98
to

Allen J. Baum wrote:
>
> In article <34BF99C9...@uiowa.edu>, William Robison
> <william...@uiowa.edu> wrote:
>
> > George R. Gonzalez wrote:
> > >
> > > On the PDP-8, the instruction to switch to another 4K bank of memory had
> > > the bank number built into the instruction. So every time you wanted to
> > > access anything outside your current 4K bank, you had to go modify an
> > > instruction a few steps ahead of yourself.
> >
> > Old Univac 418 was similar. 4K Page absolute addressing with a
> > Special Regiater to select 1 or 16 (or 32) pages. Some instructions
> > were "SR Sensitive" (i.e. would use the SR as part of the upper address.
> > Only way to load the SR was with a constant in the instruction.
> > To access large table one had to build an "LSR K" instruction
> > and place into the executing program...
> >
> > -Willy
>
> The HP35 calculator had a branch instruction to change the low bits of the

Whoa! The HP35 isn't programmable, at least not the one I paid $400 for.
You
are probably thinking of the HP45.

> PC, and a setbank to set the upper. So, a setbank would branch from
> address
> Xzzzzz to Yzzzzz+1; you had to locate you code segments verrry carefully.
>
> --
> ***********************************************
> * Allen J. Baum *
> * Digital Semiconductor *
> * 181 Lytton Ave. *
> * Palo Alto, CA 94306 *
> ***********************************************

Jerry

Jerry Avins

unread,
Jan 22, 1998, 3:00:00 AM1/22/98
to

sp...@lisardrock.demon.co.uk wrote:
>
> On 1998-01-17 lo...@signature.lines(EdmundH.Ramm) said:
> [re. forth inner interpreters: self-mod?]
> -Not on the Z80:
> -Nor on the Z280:
>
> we know. nor the 6809, for that matter. (and i think you could get away
> without on the 1802 too.) ....

You could use any of the 1802 registers as the IP, so it was easy.
(Some were pretty well kept reserved, but's that's another discussion.)

.... but the 6502 has no 16-bit registers,


hence
> you need to shove the address in a JMP, and the 6800 has only one index
> register, which is needed for other things.
>
> but this discussion would be better held in comp.lang.forth... :>
>
> incidentally, what are the smallest/fastest inner interpreter designs
> for any given architecture? (we mean the classical indirect-threading
> variety here.) and was there ever a decent forth for the PDP8?
>
> -- Communa - all at lisardrock.demon.net
> to be sure we read your reply, send to username `communa'
>
> Net-Tamer V 1.09.2 - Test Drive

Jerry

gla...@glass2.cv.lexington.ibm.com

unread,
Jan 22, 1998, 3:00:00 AM1/22/98
to
>Jerry
>--
>Remove "X" from the address to reply to <jya...@ibm.net>
>
> Engineering is the art
> of making things you want
> from things you can get.

The HP45 isn't programmable, either. I still have one.

Dave


JWillard44

unread,
Jan 22, 1998, 3:00:00 AM1/22/98
to

My original comment that it is mind bogling that a 25 MHZ 80386 or (worse)
a Pentium can't handle the characters as they come in over the serial line
without a hardware buffer was aimed at the compromises made by software which
program designers think are insignificant because of the vast advances in
hardware.
That the processor itself has the power to do so, as Don Yuniskis pointed
out, is part of my point. Self-modifying code was only the first of the
techniques to be branded "evil" in the race to cripple the new hardware.
In my years of experience, I formed the opinion that IBM's genius was not
in making new and better hardware, but in inventing software that could bring
it to its knees, requiring the customer to upgrade. This talent has now
proliferated through the colleges and universities and company labs until a
processor 100 times more powerful than the best 360, with more disk space than
ever available to a 360, can't seamlessly print and play solitaire at the same
time. This is absolutely incredible.
I did 80% or more of the programming, in Fortran, for the Data General
Eclipse based system that did the static testing of the DeHaviland Dash -8
aircraft. This processor, about the power of an 8 MHZ 80286, monitored 200
channels of ADC's, painted a color bargraph of their reading on a color Crt,
painted time based graphics of the results on two different monochrome
terminals, made status reports and accepted control input on a text CRT, and
gave printed results on a 1,000 line / min numeric printer and more complex
charts on a dot matrix printer, all in the foreground. In the background at
the same time it could carry out most any other task the system was capable of,
including setting up tests, analyzing results, compile programs, etc. All this
with 256 k words of memory and a 10 Mbyte disk.
Somewhere the industry has gone literally crazy, mentally retarded. The
setting up of the "evils" of programming are partly at fault, so is the
complexity of hardware.


Joel in Ogden

"Move not the ancient landmarks" - Solomon

sp...@lisardrock.demon.co.uk

unread,
Jan 23, 1998, 3:00:00 AM1/23/98
to


On 1998-01-22 Remove.X.to.reply said:
-sp...@lisardrock.demon.co.uk wrote:
-> we know. nor the 6809, for that matter. (and i think you could
->get away without on the 1802 too.) ....

-You could use any of the 1802 registers as the IP, so it was easy.
-(Some were pretty well kept reserved, but's that's another
-discussion.)

oh, yes - we'd forgotten that little fact.

another point of curiosity. the 1805 was an 1802 with added forthy bits
- what were the added forthy bits? and did they really help?

Jerry Avins

unread,
Jan 23, 1998, 3:00:00 AM1/23/98
to

sp...@lisardrock.demon.co.uk wrote:
>
> On 1998-01-22 Remove.X.to.reply said:
> -sp...@lisardrock.demon.co.uk wrote:
> -> we know. nor the 6809, for that matter. (and i think you could
> ->get away without on the 1802 too.) ....
>
> -You could use any of the 1802 registers as the IP, so it was easy.
> -(Some were pretty well kept reserved, but's that's another
> -discussion.)
>
> oh, yes - we'd forgotten that little fact.
>
> another point of curiosity. the 1805 was an 1802 with added forthy bits
> - what were the added forthy bits? and did they really help?

The 1802 commonly used two of its registers as program counters pointing
to CALL snd RETURN subroutines. The 1805 added CALL and RET op codes.
They were two-byte op codes because the only previously unused op code
was used as an escape code to get at them, and at a few others that I
have forgotten. I hadn't yet gotten inside FORTH, so I can't say whether
they were forthy or frothy. BTW, the designer of the 1802 intended it as
a platform interpreters, not for your every-day run-of-the-mill assembly
programmer. That's one of the reasons he didn't mind leaving CALL and
RET out of the limted op code set.


>
> -- Communa - all at lisardrock.demon.net
> to be sure we read your reply, send to username `communa'
>
> Net-Tamer V 1.09.2 - Test Drive

--

XmikeX

unread,
Jan 23, 1998, 3:00:00 AM1/23/98
to

Jerry Avins <jya...@ibm.net> said :


>You could use any of the 1802 registers as the IP, so it was easy.
>(Some were pretty well kept reserved, but's that's another discussion.)

> .... but the 6502 has no 16-bit registers, hence

--------------------------------------^^^^--------^^^^^^-----------------

Technically, the Program Counter (PC) is 16-bit... :)

XmX
--
...the Ark did thusly meander about, rocked by the waves, the gentle
oscillations of 1541 drive-knock on its bow... MG

David Director

unread,
Jan 23, 1998, 3:00:00 AM1/23/98
to

JWillard44 wrote:
>
> My original comment that it is mind bogling that a 25 MHZ 80386 or (worse)
> a Pentium can't handle the characters as they come in over the serial line
> without a hardware buffer was aimed at the compromises made by software which
> program designers think are insignificant because of the vast advances in
> hardware.
>
[ snip ]

I agree completely. In the mid-1970's, I was working for the US Navy,
updating an early-60's CPU to handle all of the P-3C's operations.
The machine had 64K of 30-bit words (if memory serves), about a 2-usec
cycle time, and 320K words of *drum* memory. It handled 7 crew
stations, with 3 large multipurpose graphic displays, 7 alphanumeric
displays, keyboards and trackballs, while simultaneously performing
real-time navigation tasks, monitoring armaments and ordnance, tracking
potential targets, and maintaining communications. Response time to
any operator action was under 500 milliseconds.

Today's software development organizations have forgotten how to
write proper operating systems and applications.

-- David

Don Yuniskis

unread,
Jan 23, 1998, 3:00:00 AM1/23/98
to

In article <34C90D...@sungardams.com>,

David Director <ddir...@sungardams.com> wrote:
>JWillard44 wrote:
>>
>> My original comment that it is mind bogling that a 25 MHZ 80386 or (worse)
>> a Pentium can't handle the characters as they come in over the serial line
>> without a hardware buffer was aimed at the compromises made by software which
>> program designers think are insignificant because of the vast advances in
>> hardware.

[My ISP's news server was dead for several days so my apologies for not
having the original article to quote here...]

>[ snip ]
>
>I agree completely. In the mid-1970's, I was working for the US Navy,
>updating an early-60's CPU to handle all of the P-3C's operations.
>The machine had 64K of 30-bit words (if memory serves), about a 2-usec
>cycle time, and 320K words of *drum* memory. It handled 7 crew
>stations, with 3 large multipurpose graphic displays, 7 alphanumeric
>displays, keyboards and trackballs, while simultaneously performing
>real-time navigation tasks, monitoring armaments and ordnance, tracking
>potential targets, and maintaining communications. Response time to
>any operator action was under 500 milliseconds.

Yes, I was involved in the design of CPLOT-2 -- the second real-time
LORAN-C position plotter on the market (three guesses what the
name of the *first* one was! :>). This VASTLY IMPROVED :> device
had all of 256 *bytes* of RAM and I think 12KB of EPROM. Yet, it
managed to take pairs of LORAN-C time-differences from an external
receiver, convert the hyperbolic coordinates characteristic of
LORAN-C into longitude and latitude -- correcting for the
oblateness of the Earth in the process -- scale them to fit the
options specified for the mercator projection currently under the
plotters pen and drive the stepping motors to indicate the
vessels current position on the map. Along with multiplexing
the display, scanning the keyboard, etc. All on a 6MHz (XTAL)
8085 (i.e. the minimum instruction time was 1.33 microseconds).

>Today's software development organizations have forgotten how to
>write proper operating systems and applications.

The purpose of my answer and my conditional agreement here is there
has been a tradeoff. In the early 70's, CPU's were pitched as
general purpose, flexible solutions to engineering design problems.
You could (or so the hype went) design a board and change the product
without having to touch any of the boards in the field or in
inventory (I guess they assumed ROMs weren't considered part of
inventory! :<)

But, it quickly became apparent that this led to ever increasing
*software* design costs (no such thing as a free lunch!). Along
came HLL's and people slowly accepted them into the market -- more
slowly into the embedded systems market. They gave a quick way to
ratchet up the productivity of a developer. But, then marketeers
started demanding more functionality, etc. (It's *always* the
guys in marketing who are to blame! If not them, then it's
the guy in the "Roach Coach" who sells those rubber sandwiches
at lunch time... it just *has* to be *his* fault!! :>)

With the Pee-Cee came the birth of software bloat. Suddenly
you could have 10MB of RAM in a box. Or 100MB of disk (instead
of 8" frisbees). Or, 100MB of RAM and 10GB of disk!!

I think that if you were to look at the effective productivity
"gains" that PC's have brought to the workplace, you'd find that
while hardware has doubled in speed every 2 years, the software
has *halved* itself in performance over the same time period.
Oh, sure... there *may* be some apps that have added functionality
that is actually *useful* (though the idea of spell checkers in
PCB layout programs seems a bit silly to me!), but I contend that
they don't offset the "missed opportunity" that they cost in
terms of overall stagnant performance "gains".

Now, if you add into the mix the time it takes to keep upgrading that
software, etc., we are probably *losing* ground...

Faster machines (for developers) also insulate the developer from the
cost of his sloppiness/laziness. Take that new application off
of the 300MHz Pentium and run it on a 486 and after a few days, I
suspect the developer will be cringing at how lousy it performs.

Other issues (like dropped characters on UARTs) are rooted, IMHO,
in the OS's lack of attention to those aspects of what makes a
machine a "computer" vs. just something that runs *your* particular
application. It's amazing to see that W95 still crashes just as
reliably as Win3.1! And, while I'm told NT doesn't particularly
"crash" as hard, it does seem to have problems dealing with this
thing called "preemptive multitasking"... why should a friend complain
that an NT application is "hogging the CPU"?

There *are* other places that *have* dealt well with utilizing the
extra CPU available. For example, I run FreeBSD and it doesn't
have those nasty problems dropping characters, etc. (within
reason). Nor does it take 16+ MB of RAM to run (I think it
will run in a 4M footprint).

It just depends on where the developer's motivation comes from...
if your boss is Billy Goates, he's more interested in pushing a new
OS down his customer's throats or yet-another-upgrade of Word, etc.
(Word 2084???) and has no incentive to make something *better*...
(a subjective term, sorry)

[rant mode off]
--don

Andrew Davie

unread,
Jan 24, 1998, 3:00:00 AM1/24/98
to

The HP-65 was the first programmable HP, and probably the unit in question.

sp...@lisardrock.demon.co.uk

unread,
Jan 24, 1998, 3:00:00 AM1/24/98
to


On 1998-01-23 d...@rtd.com(DonYuniskis) said:
-while hardware has doubled in speed every 2 years, the software
-has *halved* itself in performance over the same time period.

the definition of an operating system seems to be a piece of software
whose purpose is to insulate the poor user from any possible performance
gain in hir underlying hardware...

-Faster machines (for developers) also insulate the developer from
-the cost of his sloppiness/laziness. Take that new application off
-of the 300MHz Pentium and run it on a 486 and after a few days, I
-suspect the developer will be cringing at how lousy it performs.

something we've thought for a long time is that developers should do
their work on machines that are the slowest possible machines available
for use. that way they can see just how bad their code is.

(the problem is they can also see just how bad the tools they are using
are too, and probably scream in frustration as a result. been there...)

D. Peschel

unread,
Jan 24, 1998, 3:00:00 AM1/24/98
to

In article <88560109...@angel.comcen.com.au>,
Andrew Davie <ada...@mad.scientist.com> wrote:

>The HP-65 was the first programmable HP, and probably the unit in question.

There seems to be some confusion here. The original poster (Allen J. Baum)
mentioned what I would call a bank scheme: one instruction to set so many
of the low bits in the PC's address, and another instruction to set the
higher bits.

The problem is, this isn't the way that the user-level programming worked
on ANY of HP's handheld calculators. They all provided a simple series of
program steps (which you could call high-level stack-oriented opcodes) as
well as a current step number (which you could call the PC in this high-
level machine). The step number can't be twiddled with binary operations.

My guess is that Allen is talking about the real programming algorithms that
underlie the high-level routines. These have never been accessible to the
user, only the designer of the calculator. (If you think of the programming
model as a very high-level machine, these operations are analogous to
microcode -- in fact, they seem to be very primitive, just like ordinary
microcode.)

I know people have written simulators for HP's early calculators.
Only Allen can explain what he really meant, though. Allen?

I've left out some details. But HP has consistently used this sort of two-
level archictecture, and not documented the lower level until very recently.
(The HP71 was documented, and people have figured out how to hack the HP28
and HP48, which use the same CPU.) Some of HP's desktop calculators may have
been different, but I don't know anything about them.

-- Derek

Don Yuniskis

unread,
Jan 24, 1998, 3:00:00 AM1/24/98
to

In article <885605475.3633.0...@news.demon.co.uk>,

<sp...@lisardrock.demon.co.uk> wrote:
>
>
>On 1998-01-23 d...@rtd.com(DonYuniskis) said:
> -while hardware has doubled in speed every 2 years, the software
> -has *halved* itself in performance over the same time period.
>
>the definition of an operating system seems to be a piece of software
>whose purpose is to insulate the poor user from any possible performance
>gain in hir underlying hardware...

Ha! :>

> -Faster machines (for developers) also insulate the developer from
> -the cost of his sloppiness/laziness. Take that new application off
> -of the 300MHz Pentium and run it on a 486 and after a few days, I
> -suspect the developer will be cringing at how lousy it performs.
>
>something we've thought for a long time is that developers should do
>their work on machines that are the slowest possible machines available
>for use. that way they can see just how bad their code is.
>
>(the problem is they can also see just how bad the tools they are using
>are too, and probably scream in frustration as a result. been there...)

But, there are other classes of errors that manifest themselves on
slower processors that *don't* on faster ones. Usually races.
You could argue that if the guy is always running on a fast box,
then he doesn't care about these anomalies. *But*, if he
runs on a preemptive multitasking box that's heavily loaded, someday
that "gotcha" can show up and you'll never be able to reproduce
it (unless you expect it to be a race)

--don

William J. Leary Jr.

unread,
Jan 24, 1998, 3:00:00 AM1/24/98
to

Jerry Avins wrote in message <34C768...@ibm.netX>...


>and I never did figure out how to put stack in ROM!


Oh! I did , I did!

Working on an 80386SX/16, I had some subroutines in ROM which were there
mostly for the use of other ROM routines running after the RAM had been
tested and a stack set up. Then comes the time I have to call one of them
BEFORE RAM has been tested and a stack working. So, being an evil sort
(almost on topic) I simply pre-built the stack with the correct return
address and values I wanted in the registers after the POPA (pop all
registers, don't recall the exact mnemonic now) and pointed the stack at the
top of this and did a CALL. The CALL pushed it's instruction onto ROM,
which did nothing of course, and the routine did it's PUSHA, which also did
nothing, then when it was all done it did a POPA and RET and came back to
the place I wanted it to be.

Yeah, it was a special case, and it smelled like week old fish, but it got
the job done and saved me inlining a painful bit of hardware initialization
code.

- Bill


Carl R. Friend

unread,
Jan 24, 1998, 3:00:00 AM1/24/98
to

Allen J. Baum wrote:
>
> You could infinitely indirect on other processors as well, but
> the HP2100 would trap on more than 16 levels, I think (or was that
> the Nova?)

The Nova with the MAP option would trap after 16 levels of in-
direction; unmapped ones would indirect forever (or at least until
the reset switch was frobbed - the stop switch had no effect).

--
______________________________________________________________________
| | |
| Carl Richard Friend (UNIX Sysadmin) | West Boylston |
| Minicomputer Collector / Enthusiast | Massachusetts, USA |
| mailto:carl....@stoneweb.com | |
| http://www.ultranet.com/~engelbrt/carl/museum | ICBM: N42:22 W71:47 |
|________________________________________________|_____________________|

JWillard44

unread,
Jan 24, 1998, 3:00:00 AM1/24/98
to

Andrew Davie ada...@mad.scientist.com> wrote:
>
>The HP-65 was the first programmable HP, and probably the unit in question.

Well, o.k. if you add the modifier "hand-held". I remember an HP salseman
bringing a desktop (typewriter sized) calculator to our company for a
demonstration in 1968. It was the functional equivalent of an HP 97, It had
a small CRT that would display the stack and an entry line. It read and wrote
magnetic cards the size and shape of a credit card. It could store data or
programs on the card. It cost about $5,000.
There was not one computer in the entire company. The engineers looked
at this calculator and could see visions of $$$$ being earned as it helped our
designs be up-to-date and take less to accomplish. Management looked at it and
saw $$$$$ that it would cost and turned the idea down. The company folded a
couple of years later.

Re. HP's calcs, : dpes...@u.washington.edu (D. Peschel) wrote:
>My guess is that Allen is talking about the real programming algorithms that
>underlie the high-level routines. These have never been accessible to the
>user, only the designer of the calculator. (If you think of the programming
>model as a very high-level machine, these operations are analogous to
>microcode -- in fact, they seem to be very primitive, just like ordinary
>microcode.)

The underlying micro-code became accessable with the introduction of the
HP-41. Actually, the micro-code of the 65, and 67/97 could be read and
executed to some extent by means of non-allowed instructions which could be
introduced by electronic trauma or internal modifications. But with the 41, HP
introduced instructions and other tools that enabled the generation of
micro-code using software. Members of PPC, the HP user's club founded by
Richard Nelson, were well schooled on these methods and their use was
facilitated by a ROM that was developed by the club.

Joel in Ogden

Axel Berger

unread,
Jan 25, 1998, 3:00:00 AM1/25/98
to

*Don Yuniskis* wrote on Fri, 98-01-23 23:56 in comp.os.cpm:
DY>and you'll never be able to reproduce it (unless you expect it to be a
DY>race)

What is a race?

Danke
Axel

Allen J. Baum

unread,
Jan 26, 1998, 3:00:00 AM1/26/98
to

In article <6abgdl$hio$1...@nntp6.u.washington.edu>,

dpes...@u.washington.edu (D. Peschel) wrote:
>
> There seems to be some confusion here. The original poster (Allen J. Baum)
> mentioned what I would call a bank scheme: one instruction to set so many
> of the low bits in the PC's address, and another instruction to set the
> higher bits.
......
> My guess is that Allen is talking about .....microcode -- in fact, they
> seem to be very primitive, just like ordinary microcode.)

I was talking about HP35 microcode. I'm sorry I didn't make myself clear.
The HP 35/80/45/55/65/67 series all used the same chipset, which was
a 56 bit serial processor with 10 bit instructions, using 256 word serial
ROMs (with serial addressing!). A branch instruction only had an 8 bit
branch offset
(an a 2bit opcode) so had to using a banking structure to address the 3 Roms
required for an HP35.

When the HP45 was designed, it needed 7 ROMs, but the ROM manufacturer had
come up with a quad-ROM (which had the banking logic built-in). This meant
only two parts were required instead of seven- and it meant they had a
whole ROM worth of spare code to fill. At the last minute, the programmer
lifted some code that had been written for the HP-80, but left out when a
bugfix took the available ROM. This stop watch function could only be
activated by a non-existent key (which HP engineers in the know could get
to by re-wiring the keyboard). Someone accidently stumbled across it by
hitting 3 keys at once, which because of the nature of the keyboard
scanning hardware, had the affect of making it look like a 4th key (the
non-existent one) had been pressed, and the secret was out.

Don Yuniskis

unread,
Jan 27, 1998, 3:00:00 AM1/27/98
to

In article <OHGGpqIK9GA.213@upnetnews04>,

William J. Leary Jr. <Bill_...@msn.com> wrote:
>
>Jerry Avins wrote in message <34C768...@ibm.netX>...
>>and I never did figure out how to put stack in ROM!
>
>Working on an 80386SX/16, I had some subroutines in ROM which were there
>mostly for the use of other ROM routines running after the RAM had been
>tested and a stack set up. Then comes the time I have to call one of them
>BEFORE RAM has been tested and a stack working. So, being an evil sort
>(almost on topic) I simply pre-built the stack with the correct return
>address and values I wanted in the registers after the POPA (pop all
>registers, don't recall the exact mnemonic now) and pointed the stack at the
>top of this and did a CALL. The CALL pushed it's instruction onto ROM,
>which did nothing of course, and the routine did it's PUSHA, which also did
>nothing, then when it was all done it did a POPA and RET and came back to
>the place I wanted it to be.
>
>Yeah, it was a special case, and it smelled like week old fish, but it got
>the job done and saved me inlining a painful bit of hardware initialization
>code.

This is a classic POST hack. However, it usually only works in cases
where you can *completely* control interrupt sources, etc. (For a
real challenge, think of how you can extend this to enable you to
test the interrupt system! :>). It usually falls down when you
can't gate NMI sources (even on those processors that disable NMIs
until SP is loaded)

--don

George Hostler

unread,
Jan 27, 1998, 3:00:00 AM1/27/98
to

Robert,

Mentioning the TI-9900 mpu reminded me of a part of my past . . .

I did Fortran and IBM 360J imbedded assembly language on a Perkin Elmer 32xx
while working for McDonnell Douglas in the 80's. Found out that to do a
Fortran library call to change the task priority (or any other call for
matter of fact), it took about 50 - 70 instructions before actually doing
it. Similarly, there was no PUSH or POP, you saved the registers in memory.
By jumping to assembly, I could change the task priority in three
instructions. (Initialized status words for a SUPV 6 call in the beginning
of the program, got the task priority, stored it in the parameter block
location, issued the Supervisor 6 call, bingo! task priority changed).

A former supervisor, Bill, worked on the Cell (or Sell?) computers. They
were 16 bit, had toggle switches, you keyed in the bootstrap loader, had an
analog acquisition front end. When I came on board, they were being
surplused. They used self modifying code, had 8KB of core memory, the techs
added another 8KB of static ram, custom wire wrapped. Since memory was so
precious, they patched instructions on the fly, based upon test
requirements.

The advent of CP/M and 64KB of memory, I don't know why someone would resort
to self modifying code except in extreme resource conservation requirements
or encryption to hinder disassembly. Unless well documented (I downloaded
Fortran IV work to a word processor, blocked it out, documented variables by
creating a data dictionary, added comment lines when I cracked a section, in
essence, reverse engineering), it makes it difficult to modify someone
else's work, let alone one's own. I've gone back to some work I did several
months, 1/2 a year or more, and had to relearn what I did. Even though I
had adequate comments, some documentation (SDF), there was always a learning
curve.

George
Gallup, New Mexico, USA
ghos...@cia-g.com

BTW, you mentioned Christian, I lead the singing at First Indian Baptist
Church.

Robert Billing wrote in message <884988...@tnglwood.demon.co.uk>...
>In article <#4CgtOjI9GA.214@upnetnews04>
> Bill_...@msn.com "William J. Leary Jr." writes:
>
>> I loved the TI990 and TI9900 CPU architecture. Especially that those
>> "registers" were really in memory and you could get a new set of
registers
>> at any moment. I always wanted a opportunity to program on one.
>
> I have. Oh deary, deary, me. As CSL said, "Things of extreme evil
>which have the appearance of innocence to the uninitiated."
>
> Take the 99105 as a case in point.
>
> MOVB (R2)+, (R3)+ <SNIP!>


>I am Robert Billing, Christian, inventor, traveller, cook and animal
>lover, I live near 0:46W 51:22N. http://www.tnglwood.demon.co.uk/
>"Bother," said Pooh, "Eeyore, ready two photon torpedoes and lock
>phasers on the Heffalump, Piglet, meet me in transporter room three"
>
>

sp...@lisardrock.demon.co.uk

unread,
Jan 28, 1998, 3:00:00 AM1/28/98
to


On 1998-01-25 Axel_...@k2.maus.de(AxelBerger) said:
-*Don Yuniskis* wrote on Fri, 98-01-23 23:56 in comp.os.cpm:
-DY>and you'll never be able to reproduce it (unless you expect it
-DY>to be a race)

-What is a race?

race conditions: where two or more processes, procedures, events,
whatever, are competing for the same resource, and whereas the program
depends on them running in a certain order, they may run in a different
one with interesting (and hard-to-spot) results.

Jerry Avins

unread,
Jan 28, 1998, 3:00:00 AM1/28/98
to

It just goes to show that if someone can think of it, even in jest,
someone else can do it!
-- Jerry

john r pierce

unread,
Jan 29, 1998, 3:00:00 AM1/29/98
to

jwill...@aol.com (JWillard44) wrote:

> Whatever is said about how evil self-modifying code is, there was a time
>when it was necessary. Some early mini-computers required it. For instance,
>the PDP-8 jump to a subroutine instruction placed the return address in the
>location of the call and began execution at the next location.


I just remembered ANOTHER case of early self modifying code that was absolutely
mandantory. The IBM 1130 again. (sheesh, will us old 1130-heads EVER shaddup
about it? :)...

Seems the 1130's IPL ("Initial Program Loader") read one punchcard into the
first 80 words of core. Each column of a card has 12 bits. The 1130 had a 16
bit instruction format, which (from rusty memory) was a 5 bit op code, a 'Long'
bit, a 2 bit index register field, and an 8 bit immediate field (also used for
additional op codes in some cases). The (hard wired) IPL would take the 12 bits
from the card reader, put the first 5 in the op code field (bits 0-5, 0 is MSB),
leave the L and IX fields 0, and take the other 7 bits and put them in the
immediate field, duplicating the MSB into bits 8,9. So you had to do
everything in 80 words with NO long or indexed instructions. Well, there's no
way in hades to do some things without either a L or a 1,2,3 :) so you'd end up
using the first several words to shift values around and OR them into other
instructions, i.e. classic self modifying code. Mother is the neccessity of
inventions. Or something.

-jrp
----------------------------------------------------------------------
This posting has a invalid email address to discourage bulk emailers
Due to the ever increasing volumes of spam, I do not mix mail and news
----------------------------------------------------------------------

JWillard44

unread,
Jan 29, 1998, 3:00:00 AM1/29/98
to

>Seems the 1130's IPL ("Initial Program Loader") read one punchcard into the
>first 80 words of core.

I worked in hardware until after my wife completed computer school. She
had an instructor (University computing, Ross Perot's co.) named Charlie Brown.
He had a one card program for the 1130 that was essentially a complete system
diagnostic.

By the way, can you imagine how dumb we are? If Engineer Scottie could
come back in time and know so little about an Apple system that he could
mistake the mouse for a microphone, how could he use the computer to calculate
the design of "transparent aluminum"? Somehow he was so brilliant that he was
able to figure out how to use the Op sys and the program!

Jerry Avins

unread,
Jan 29, 1998, 3:00:00 AM1/29/98
to hjoh...@pluto.njcc.com

Herbert R Johnson wrote:
>
> In article <69dal1$c...@mozo.cc.purdue.edu>,
> wil...@math.purdue.edu (Clarence Wilkerson) wrote:
> *>I believe even the BIOS on my H89 has some self modifying code.
> *>If you want to output to a variable io port on a straight 8080,
> *>I don't think you get much choice.
> *>--
> *>Clarence Wilkerson \ HomePage: http://www.math.purdue.edu/~wilker
>
> "You are correct, sir" as they say. I've found one dodge to ROM code and
> self-modification is to push the code on the stack and to execute the stack.
> I forget the details, it depends on how the stack is incremented or
> decremented for your processor. Push a RET or a JUMP address back to yourself,
> push the op codes, then "call" or "jump" to the stack pointer. BEware that
> a "call" will push your address onto the stack, so a JUMP may be prudent.
> YOu get the idea.
>
> Herb Johnson
>
> **** ------------------------------------------------------ ****
>
> Herbert R. Johnson voice/FAX 609-771-1503 day/nite
> hjoh...@pluto.njcc.com Ewing, in central New Jersey, USA
>
> amateur astronomer and astro-tour guide
> supporter of classic S-100 computers as "Dr. S-100"
> rebuilder of Mac Plus computers for your computing pleasure
> and senior engineer and asteroid spotter at Astro Imaging Systems


Although not exactly self modifying code, another variation on this is
my assembler version of Fortran's "computed goto". Just generate the
address bytes you want, PUSH them, and RETurn. BTW, Herb's procedure
will even work with interrupts enabled.

Jerry Avins
--

Jeff Jonas

unread,
Jan 30, 1998, 3:00:00 AM1/30/98
to

>I just remembered ANOTHER case of early self modifying code that was
absolutely mandantory. The IBM 1130 again.
(sheesh, will us old 1130-heads EVER shaddup about it? :)...

*grin* I too love talking of the IBM 1130 since it was a wonderful
machine to learn all about architecture - so much was visible
from the front panel lights!
(my panel was multi colored as I used Christmas lights
as replacement bulbs!)

>Seems the 1130's IPL ("Initial Program Loader") read one punchcard into the

>first 80 words of core. Each column of a card has 12 bits. The 1130 had a 16
>bit instruction format, which (from rusty memory) was a 5 bit op code, a 'Long'
>bit, a 2 bit index register field, and an 8 bit immediate field (also used for
>additional op codes in some cases).

My reference cards are at home now, but that sounds right.

> The (hard wired) IPL would take the 12 bits
>from the card reader, put the first 5 in the op code field (bits 0-5, 0 is MSB),
>leave the L and IX fields 0, and take the other 7 bits and put them in the
>immediate field, duplicating the MSB into bits 8,9. So you had to do
>everything in 80 words with NO long or indexed instructions. Well, there's no
>way in hades to do some things without either a L or a 1,2,3 :) so you'd end up
>using the first several words to shift values around and OR them into other
>instructions, i.e. classic self modifying code. Mother is the neccessity of
>inventions. Or something.

I'm a bit confused, for I have a plastic punched-card template for
the 1130/1800 showing the 16 bitpatterns used for a pure binary format.
Perhaps that was the card format for a software loader,
not the IPL hardware. But then consider that the IPL from paper tape
actually combined several 8-bit columns to each word, so *some* IPL
hardware was not so dumb. I'm afraid my 1130 theory-of-operation
manuals are deep in storage so I can't look that up now :-(
--
Jeffrey Jonas
jeffj@panix(dot)com
Meow? PRR PRR PRR !

Otter

unread,
Jan 31, 1998, 3:00:00 AM1/31/98
to jwill...@aol.com

On 29 Jan 1998 17:04:55 GMT,
JWillard44 <jwill...@aol.com > wrote:

> By the way, can you imagine how dumb we are? If Engineer Scottie could
>come back in time and know so little about an Apple system that he could
>mistake the mouse for a microphone, how could he use the computer to calculate
>the design of "transparent aluminum"? Somehow he was so brilliant that he was
>able to figure out how to use the Op sys and the program!
>
> Joel in Ogden
>

Remember, these are Hollywood computers. They operate differently
from real-world systems. All you have to do is turn on the power
switch and type one or two lines of code to do stuff like take
complete control of a city's traffic control system, command a weather
satellite to somehow shoot a powerful laser beam to make it rain hard
in Columbia, or develop transparent aluminum...

--Otter


john r pierce

unread,
Feb 1, 1998, 3:00:00 AM2/1/98
to

je...@panix.com (Jeff Jonas) wrote:

>I'm a bit confused, for I have a plastic punched-card template for
>the 1130/1800 showing the 16 bitpatterns used for a pure binary format.
>Perhaps that was the card format for a software loader,
>not the IPL hardware. But then consider that the IPL from paper tape
>actually combined several 8-bit columns to each word, so *some* IPL
>hardware was not so dumb. I'm afraid my 1130 theory-of-operation
>manuals are deep in storage so I can't look that up now :-(

I vaguely recall, yes, the paper tape IPL option would read two 8 bit columns
and make a 16 bit word. I also believe it read an arbitrary number of words up
to some stop code (FFFF or 0000 ?). The machine we had was card IPL only (good
old 1404[?] reader/punch)

Jerry Avins

unread,
Feb 2, 1998, 3:00:00 AM2/2/98
to
...and there are always blinking lights. They take zero time to boot,
and respond to the command "reveal password".

-- J.A.

JWillard44

unread,
Feb 2, 1998, 3:00:00 AM2/2/98
to

I wrote:
>
> HP-41. Actually, the micro-code of the 65, and 67/97
> could be read and executed to some extent by means of non-
> allowed instructions which could be introduced by electronic
> trauma or internal modifications.

dpes...@u.washington.edu (D. Peschel) wrote:
>
> Thanks for your article. Do you have any specific
> information? (I own a HP-97. The card reader may be
> becoming flaky, though.)
>
> I know about using non-normalized numbers to display
> 'E', 'r', 'o', 'c', 'd', and blanks (and to fry the
> printer!) I've heard of the issues of PPC Journal with the
> included magnetic cards, though I don't have them. I've
> read of (and seen a picture of) the Black Box which is
> probably what you meant by "electronic trauma." (It hooks
> up to the power supply and has a variable resistor, I
> think.)
> Is it possible to create new program instructions as
> well, or just tweak the display? (And I assume that the
> printer uses a separate mechanism for printing program step
> codes -- 'LBLa', 'x<y', and so on.)

Actually, I never owned any of the 60 series calculators, and
joined the HP-65 club only after they opened up membership to owners
of other calculators and became PPC. The club had extensive influence
on the design of the HP-41, perhaps the most elegant of all HP
calculators.
As I remember, the 65, 67/97 were limited in accessing their
microcode as there was no way to call micro-code subroutines.
However, the entrance of NNN's did do some unusual things.
I am sure that the back issues of "HP-65 Notes" and "PPC Journal"
are available somewhere, but due to the degradation of the club when
its founder, Richard Nelson, was ousted, I have lost contact with any
members.

Axel Berger

unread,
Feb 2, 1998, 3:00:00 AM2/2/98
to

*Otter* wrote on Sat, 98-01-31 10:33 in comp.os.cpm:
O>Remember, these are Hollywood computers.

Have you read the book Congo by Crichton? In it they first type 50
character sentences with the most crypric abbreviations, (like
IMHO and worse) because transmission is so limited and a couple of
pages later they do remote real time high resolution image processing.
Apart from that, it is a good read though.

Tschö wa
Axel

0 new messages