return to main 1401 Restoration Page

Software E-Mails
a burst starting 12/02/2014
- primarily 1401 coding, subroutines


Dear Friends,
   Luca Severini < lucaseverini@mac.com >
   [ an experienced programmer now getting a Computer Science degree ]
   [If you wish you may add I'm a retrocomputing enthusiast and collector of 
    Personal and Home Computers from the late Seventies up to early Nineties.]
   got interested in an antique archaic computer called an IBM 1401,
   announced in 1958 - 

   He started programming the IBM 1401 using a 
        cross-platform development system called "ROPE"
     click here for an introduction

   The ?news group? '1401_software@computerhistory.org' 
      discusses IBM 1401 software issues 

   There was a discussion of comparing values (including alpha)
       in a decimal machine with decimal adder ....  Link-001

   Luca Severini then asked an ?innocent? question of the group  
      about how to store the instruction address register into memory.
       Link-003
   Probably he was intending to later ask about 
        "calling" subroutines
   which needs the capability. 
       "Who knows what lurks in the hearts of men?"
 
   An explosion of e-mails followed, and the thread blossomed into:
     - subroutines
     - subroutines with parameters in index registers
     - recursion (subroutines calling themselves)   Link-004
     -   (recursion can be very useful in compiliers)
     - compiliers   Link-005
     -    etc. etc. "and so on"
     - macros  Link-045 with Alan Kay 

    I have put the e-mails (and some attachments)
        into a time sequence ordered list below
        (for better or worse(r), the oldest at the top)
           Being truly slothful, I have not provided an
              index, table of contents, ...
     If you wish to make one, you may refer to the 
         included  tags   "Link-nnn" 
         an example being  Link-012
         the clickable link being Link-012

Oldest nearest the top (here)
------------------------------------------------------
Link-001

Subject:	
    Re: [1401_software] Help
	  	
From:	
Van Snyder < van.snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 1:35 am
To:	Paul Laughton < paul.laughton@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Paul Laughton wrote:
> Oh my. And here I thought I was comparing a computed 81 to a computed
> 4. Those zone bits appear to be a PIA when doing mathematical operations.

The 1401 does arithmetic in decimal. The low-order four bits (8421) are
the digit, provided it's in 0..9. If the B-zone alone is set in the
low-order digit, the number is negative. With no zone, AB zone, or A
zone, it's positive. If the field is more than one digit and you get
overflows, the first overflow sets the A zone in the high-order digit,
the second sets the B zone, the third sets the AB zone, the fourth
clears the zone bits, etc....

Here's a fun program to reverse engineer, that does 128-digit arithmetic:

,008015,022029L074367,036040,3333371001z3282,200329a328a349332z332b333200.
,338345,349356,360367,368368,047054/299M050328,061068L071332/333327 0

Bet you can't get that into two lines of C code!

>
> Paul
>
> On Mon, Dec 1, 2014 at 9:40 PM, Van Snyder < van.snyder@jpl.nasa.gov
> < mailto:van.snyder@jpl.nasa.gov>> wrote:
>
> Comparisons are not in binary order as if BA8421 were a binary
> number. They're done according to the collating sequence chart on
> page 170 of A24-1403. 0 compares after A.
>
> Paul Laughton wrote:
>
> Can someone explain what is going on here?
>
> When I run this program which compares < HA>:< 0D>, it finds the
> < 0D> is greater than < HA>. Why?
>
> Run the program. When it halts, look at the console. It shows B>A
>
> Note: that that segment reproduces the context of the program
> where I am having the problem.
> Thank you,
> Paul
>
> =====
> ".s" file attached. In case you can't read, here a font
> challenged version.
>
> ORG 87
> X1 DCW 001 *
> ORG 333
> *
> START NOP
> C EIGHT+1+X1,FOUR+1+X1
> STOP H STOP
> FOUR DCW 0
> DCW @0D @
> EIGHT DCW 0
> DCW @AHI @
> ONE DCW 1
> ZERO DCW @000@
> END START
>
>
>
>
> ------------------------------------------------------------------------
----------------------------------------------------------------------
Link-002

Subject:	
    Re: [1401_software] Help
	  	
From:	
Paul Laughton < paul.laughton@gmail.com>		 
Date:	Tue, Dec 02, 2014 11:48 am
To:	Van Snyder < Van.Snyder@jpl.nasa.gov>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
I have started to learn 1401 programming by creating sw 
multiply and divide subroutines. This task has put into a head 
on collision with 1401's funny math. All your comments are being very helpful.

Thank you,
Paul

On Tue, Dec 2, 2014 at 11:34 AM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:

    On Tue, 2014-12-02 at 16:50 +0000, Lawrence Kesteloot wrote:
    > The "C" compare operation is not for numbers. Even if you were
    > comparing decimal numbers, it wouldn't know about the sign bits.
    >
    > It's surprisingly hard to compare numbers on the 1401. For example,
    > say you want to compute "X < Y". You can subtract then use BM (branch
    > minus), but that won't always do the right thing when X = Y, since the
    > sign of the 0 result will come from B (and hence may be +0 or -0). So
    > you must first check for X = Y. You could first do that with the "C"
    > operation, but then you must make sure both numbers are properly
    > normalized (either have leading zeros/blanks or not, and have a
    > consistent sign). You can do that with a subtraction first:
    >
    >
    >      S    @0@, X
    >      S    @0@, Y
    >      C    X, Y
    >      BE   EQUAL
    >
    >
    > Even then I'm not sure if it'll properly handle the case of X and Y
    > initially being 0 but with opposite signs. In fact, reading the sign
    > chart on page 30 of A24-1403, it looks like if X = +0 and Y = -0, the
    > above code won't work (the signs will stay that way and the compare
    > will fail). Van?

    I think this is correct.  For signed numbers with equal magnitudes, I
    think that negative numbers compare greater than positive numbers,
    according to the collating sequence.  For example +123 is 12C, while
    -123 is 12T.  Treated as characters, 12T collates after 12C.

    For fields that should be numeric and unsigned, we would always do a
    "double punch and blank check:"

      za   field+1, test+1
      c    field, test
      bu   oops

    > And in any case you must only use C on fields of equal length, or
    > you'll get surprising results when the B field is longer.

    If the B field is longer, you always get unequal compare.  If I remember
    correctly, if the machine has high-low-equal you also always get "high".

    The description of high-low-equal in A24-3071-2 is very sparse.  It only
    describes the new D-modifiers for the 5-character branch instruction.
    It doesn't describe how the compare instruction works differently if the
    machine has the feature.

    >
    >
    > Lawrence
    >
    >
    > On Mon Dec 01 2014 at 11:22:11 PM Paul Laughton
    > < paul.laughton@gmail.com> wrote:
    >         Oh my. And here I thought I was comparing a computed 81 to a
    >         computed 4. Those zone bits appear to be a PIA when doing
    >         mathematical operations.
    >
    >
    >         Paul
    >
    >         On Mon, Dec 1, 2014 at 9:40 PM, Van Snyder
    >         < van.snyder@jpl.nasa.gov> wrote:
    >                 Comparisons are not in binary order as if BA8421 were
    >                 a binary number.  They're done according to the
    >                 collating sequence chart on page 170 of A24-1403. 0
    >                 compares after A.
    >
    >                 Paul Laughton wrote:
    >                         Can someone explain what is going on here?
    >
    >                         When I run this program which compares
    >                         < HA>:< 0D>, it finds the < 0D> is greater than
    >                         < HA>. Why?
    >
    >                         Run the program. When it halts, look at the
    >                         console. It shows B>A
    >
    >                         Note: that that segment reproduces the context
    >                         of the program where I am having the problem.
    >                         Thank you,
    >                         Paul
    >
    >                         =====
    >                         ".s" file attached. In case you can't read,
    >                         here a font challenged version.
    >
    >                                        ORG  87
    >                              X1        DCW  001                      *
    >                                        ORG  333
    >                              *
    >                              START     NOP
    >                                        C    EIGHT+1+X1,FOUR+1+X1
    >                              STOP      H    STOP
    >                              FOUR      DCW  0
    >                                        DCW  @0D   @
    >                              EIGHT     DCW  0
    >                                        DCW  @AHI  @
    >                              ONE       DCW  1
    >                              ZERO      DCW  @000@
    >                                        END  START
    >
    >
    >
----------------------------------------------------------------------
Link-003


Subject:	
    [1401_software] Re: Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 2:07 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 13:54 -0800, Luca Severini wrote:
> Hi,
>
> Is there some way to get and store the current program counter 
value (the I-Address register) like SBAR and SBR instructions?
> It seems no to me but perhaps someone know a way...

You can store the I-address register after any branch instruction using
SBR (assuming you have the indexing and store address special feature).
As far as I know, you cannot store the I address register after any
other instruction. Of course, you can store an address that Autocoder
knows using two-address SBR:

sbr Where, Addr

This is also handy for incrementing index registers:

sbr x1, 10+x1

For a real eye opener on using SAR and SBR to process variable-length
fields, look at Gary Mokotoff's Fortran II compiler. If it's not at
bitsavers, I can send it.

Van

> Thank you!
>
> Luca

 

----------------------------------------------------------------------
Link-004

From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 3:32 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 15:08 -0800, Luca Severini wrote:
> And I do need recursion... ;-)

Then you'll need to make a stack of activation records, and a stack
pointer, and put the return address in the activation record in the
stack, and finally move the return address into the subroutine exit
branch.

recurs sbr *&14 Return address
sbr sx3, 0&x3 Save X3
sbr x3, 0-0 Return address to X3
sbr sx2, 0&x2 Save X2
mcw stkptr, x2 Stack pointer to X2
sbr retn&x2, 7&x3 Assume two arguments
mcw 2&x3, arg1&x2 Arg 1 to stack
mcw 5&x3, arg2&x2 Arg 2 to stack
...
sbr stkptr, 80&x2 Push the stack
b recurs
dsa narg1 New arg 1
dsa narg2 New arg 2
sbr stkptr, 0&x2 Pop the stack
or, if X2 is no longer the current activation record's stack pointer:
mcw stkptr, x2 Get the stack pointer
sbr stkptr, 15920&x2 Pop the stack
Maybe get stuff out of the current activation record into local
variables here, or maybe just use it from the activation record
...
mcw retn&x2, recurx&3
mcw sx3&x2, x3
mcw sx2&x2, x2
recurx b 0-0

stack da 10x80 Ten activation records of 80 chars
retn 1,3 See pages 16-19 of C24-3319
arg1 4,6
arg2 7,9
sx2 10,12
sx3 13,15
stuff1 16,42
stuff2 32,80
stkptr dsa stack

You could do the stack push at entry and the stack pop at exit, if
there's more than one recursive call. Start STKPTR at STACK-80, and
early in RECURS do
mcw stkptr, x2
sbr x2, 80&x2
sbr stkptr, 0&x2
then, at the end
mcw stkptr, x2
sbr stkptr, 15920&x2
...
stkptr dsa stack-80

> Luca
>
>
>
> On Dec 2, 2014, at 2:58 PM, Lawrence Kesteloot < lk@teamten.com> wrote:
>
> > Right, you return by storing the B register into the operand of a
> > branch at the end of your subroutine. The convention is to use the
> > name of the subroutine followed by "X", like "SQRTX", for the last
> > instruction. Works great as long as you don't need recursion. And
> > you don't need the Indexing feature to use this, but you do need the
> > Store Address Register feature (which we also have).
> >
> >
> > Lawrence
> >
> >
> >
> > On Tue Dec 02 2014 at 2:38:03 PM Michael Albaugh
> > < m.e.albaugh@gmail.com> wrote:
> >
> > On Dec 2, 2014, at 1:54 PM, Luca Severini
> > < lucaseverini@mac.com> wrote:
> >
> > > Hi,
> > >
> > > Is there some way to get and store the current program
> > counter value (the I-Address register) like SBAR and SBR
> > instructions?
> > > It seems no to me but perhaps someone know a way...
> >
> > About the only way I can think of is to branch to a location
> > that does an SBR
> > and then branches back:
> >
> > GIAR SBR VIAR+3
> > VIAR B 0
> >
> > B GIAR will result in the address after the branch being
> > stored
> > at VIAR+3, with execution picking up after the branch to
> > GIAR.
> > Of course, this only works if your 1401 has the Indexing
> > feature,
> > as ours do.
> >
> > -Mike
>
>

----------------------------------------------------------------------
Link-005

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Tue, Dec 02, 2014 3:33 pm
To:	Paul Laughton < paul.laughton@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Kind of a shotgun reply here, to (at least) three messages)

On Dec 2, 2014, at 3:19 PM, Paul Laughton < paul.laughton@gmail.com> wrote:

> Indeed, how does one write a C compiler without recursive descent?

He isn't writing a "hosted" compiler, but a "cross compiler",
so the compiler doesn't run on the 1401. Also, one can always
simulate recursion (most computers actually do :-) and one
_can_ write a parser for C that is not recursive descent.
Various "bottom up" methods work, for a sufficiently lax
definition of "work" that does not include "gives usable
error messages". Yes, I know, been through that fight ages
ago, many times. It is theoretically possible to write such
a parser whose error-handling doesn't suck, in the same
sense that it is possible to write a fully compliant ADA
compiler on a Turing machine. I'm not holding my breath.


> On Tue, Dec 2, 2014 at 3:08 PM, Luca Severini < lucaseverini@mac.com> wrote:
> And I do need recursion... ;-)

As I mentioned, you "stack" the address by moving it from its
initial home, and then back to return. As with many machines
(e.g. MIPS, Power, S360) that do not automatically stack the
return address, you can optimize by only stacking it in non-leaf
routines. You treat it like any caller-save register.

This raises the question: Are you actually emitting 1401 code,
or more like threaded code (ala Forth or the PDP-11 Fortran
compiler), or maybe a byte-coded VM as the original Small C
did (again, IIRC)

> Luca
>
>
> On Dec 2, 2014, at 2:58 PM, Lawrence Kesteloot < lk@teamten.com> wrote:
>
>> Right, you return by storing the B register into the operand 
of a branch at the end of your subroutine. The convention is to 
use the name of the subroutine followed by "X", like "SQRTX",
 for the last instruction. Works great as long as you don't need 
recursion. And you don't need the Indexing feature to use 
this, but you do need the Store Address Register feature (which we also have).
>>

It was my impression from the manual that SBR/SAR were part of the Indexing
feature, just as MA is part of the "more than 4K" feature.
But anyway, unless you are writing position-independent code, you
can get by without SBR by moving the (known) address of the next
instruction into the "return holder", then branching. Many ways
to do this sort of thing.

-Mike
----------------------------------------------------------------------
Link-006

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 3:37 pm
To:	Paul Laughton < paul.laughton@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 15:19 -0800, Paul Laughton wrote:
> Indeed, how does one write a C compiler without recursive descent?

One could use LR for parsing, but that needs a stack too, just not for
recursion.

Now that would be an interesting project: An LR parser generator, either
using Pager's algorithm or De Remer's LALR, written in Autocoder.

You'd want to use an aggressive compression scheme on the LR table,
something like the "comb" method that De Remer and Pennello produced
from the Metaware LALR generator.

>
> On Tue, Dec 2, 2014 at 3:08 PM, Luca Severini < lucaseverini@mac.com>
> wrote:
> And I do need recursion... ;-)
>
>
> Luca
>
>
>
> On Dec 2, 2014, at 2:58 PM, Lawrence Kesteloot
> < lk@teamten.com> wrote:
>
> > Right, you return by storing the B register into the operand
> > of a branch at the end of your subroutine. The convention is
> > to use the name of the subroutine followed by "X", like
> > "SQRTX", for the last instruction. Works great as long as
> > you don't need recursion. And you don't need the Indexing
> > feature to use this, but you do need the Store Address
> > Register feature (which we also have).
> >
> >
> > Lawrence
> >
> >
> >
> > On Tue Dec 02 2014 at 2:38:03 PM Michael Albaugh
> > < m.e.albaugh@gmail.com> wrote:
> >
> > On Dec 2, 2014, at 1:54 PM, Luca Severini
> > < lucaseverini@mac.com> wrote:
> >
> > > Hi,
> > >
> > > Is there some way to get and store the current
> > program counter value (the I-Address register) like
> > SBAR and SBR instructions?
> > > It seems no to me but perhaps someone know a
> > way...
> >
> > About the only way I can think of is to branch to a
> > location that does an SBR
> > and then branches back:
> >
> > GIAR SBR VIAR+3
> > VIAR B 0
> >
> > B GIAR will result in the address after the branch
> > being stored
> > at VIAR+3, with execution picking up after the
> > branch to GIAR.
> > Of course, this only works if your 1401 has the
> > Indexing feature,
> > as ours do.
> >
> > -Mike
>
> 

----------------------------------------------------------------------
Link-007

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Tue, Dec 02, 2014 3:39 pm
To:	Michael Albaugh < m.e.albaugh@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Right. Is a cross compiler.
I know I could simulate recursion but I'd like to do a compiler 
(a Small-C compiler btw)
which work without tricks as much as possible.
I have quite good experience with MC68xxx and Z80 Assembly 
but 1401 is... different. ;-)
However, thanks to the help I'm getting here, it seems possible.

Luca

On Dec 2, 2014, at 3:33 PM, Michael Albaugh < m.e.albaugh@gmail.com> wrote:

> Kind of a shotgun reply here, to (at least) three messages)
>
> On Dec 2, 2014, at 3:19 PM, Paul Laughton < paul.laughton@gmail.com> wrote:
>
>> Indeed, how does one write a C compiler without recursive descent?
>
> He isn't writing a "hosted" compiler, but a "cross compiler",
> so the compiler doesn't run on the 1401. Also, one can always
> simulate recursion (most computers actually do :-) and one
> _can_ write a parser for C that is not recursive descent.
> Various "bottom up" methods work, for a sufficiently lax
> definition of "work" that does not include "gives usable
> error messages". Yes, I know, been through that fight ages
> ago, many times. It is theoretically possible to write such
> a parser whose error-handling doesn't suck, in the same
> sense that it is possible to write a fully compliant ADA
> compiler on a Turing machine. I'm not holding my breath.
> 

----------------------------------------------------------------------
Link-008

Subject:	
    [1401_software] Re: Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 3:51 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 15:32 -0800, Luca Severini wrote:
> Hi Van
>
> Does it make sense to say that I would like to use one of the 
index registers as a stack pointer?
>
> If it makes sense, how would you write a code snippet which 
jumps to a subroutine with two arguments a returns
> a value like 123 ?

Recursion and stack handling in a recent message. Here's a
non-recursive routine that has an input argument, which it ignores, and
an output argument, which it changes to 123. The 6 characters after the
branch to SUBR are addresses of arguments. You could in principle put
the argument values there instead, and use offsets different from 3 and
6.

subr sbr *&14 *&13 below was a mistake
sbr sx3&6, 0&x3 Save X3
sbr x3, 0-0 Argument addresses
sbr subrx, 6&x3 Return address
sbr sx2&6, 0&x2 Save X2
mcw 5&x3, x2 Address of second argument
mcw @123@, 0&x2
or, if you don't want to save, restore, and use X2 to access ARG2:
mcw 5&x3, *&7
mcw @123@, 0-0
sx2 sbr x2, 0-0 Restore X2
sx3 sbr x3, 0-0 Restore X3
subrx b 0-0 Return

> Thank you!
>
> Luca
>
>
> On Dec 2, 2014, at 3:07 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:
>
> > On Tue, 2014-12-02 at 14:13 -0800, Luca Severini wrote:
> >> Hi Van,
> >>
> >> Yes. I found it. I must use SBR after the branch. But thanks 
for your complete explanation.
> >> Now I'm looking for a way to return back from the subroutine...
> >
> > b subr
> > ...
> > subr sbr exit&3
> > ...
> > exit b 0-0 I use "0-0" to mean "filled at run time".
> >
> > If you have arguments that you want to get at using X3, and you want to
> > preserve X3:
> >
> > sub2 sbr *&13 Return address
> > sbr sx3+6, 0&x3 Save X3
> > sbr x3, 0-0 Branch+1 to X3
> > sbr exit2&3, 6&x3 assume SUB2 has two address arguments
> > ...
> > sx3 sbr x3,0-0 Restore X3
> > exit2 b 0-0
> > ...
> > b sub2
> > dsa arg1
> > dsa arg2
> >
> >> Luca
----------------------------------------------------------------------
Link-009

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Jay Jaeger < cube1@charter.net>		 
Date:	Tue, Dec 02, 2014 3:52 pm
To:	1401_software@computerhistory.org
Van has addressed this, but I thought I'd chime in, too.

One can write a C compiler using any number of techniques OTHER than
recursive descent. For example, one might generate a parser for a cross
compiler using YACC, which is LALR (look-ahead LR). I would expect Luca
has probably already done so.

Luca's C *runtime* will presumably need to *simulate* a stack somehow,
since C expects to use "activation record" stack frames - and Van
provide some hints about that. Basically, the stack can be done by
setting aside a fixed storage area for it and writing some "push" and
"pop" subroutines.

And, presumably his subroutine entry logic will stash the return address
in a fixed location somewhere, and then call the push subroutine to put
that return address on the stack, thus making the C code more or less
re-entrant. (On a machine with interrupts, he'd have to disable those
long enough to allow the push subroutine to snag that address from the
fixed location before it got overwritten by another C
subroutine/function call.)

It is kind of fun watching Luca work through some of this. When I was
taking my grad-school compiler class, we wrote an ALGOL-68 compiler that
generated "tuples", and I wrote the code generation that took the tuples
and generated PDP-11 RT-11 compatible relocatable object files (we
didn't even go through an assembler).

It is interesting how (at least one) modern day CS students have to
expand their minds to get around the idea that not every machine has a
hardware stack / stack related instructions. ;)

On the other hand, the very very FIRST CS course I took in 1969/1970
used ALGOL on a Burroughs B5500, and our last assignment was, believe it
or not, a recursive descent compiler to generate code for a
stack-machine (kind of a micro-B5000) that we had written an assembler /
interpreter for in the next to last project. The pair of projects took
an entire box of cards. (The instructor provided the recursive descent
framework (i.e., acted as the compiler generator). We had to write the
scanner (lexical analyzer) and fill in the bodies of the recursive
descent subroutines.

Then the next fall I got a job working with an IBM 1410. ;)

JRJ

On 12/2/2014 5:19 PM, Paul Laughton wrote:
> Indeed, how does one write a C compiler without recursive descent?
>
----------------------------------------------------------------------
#010

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 3:55 pm
To:	Michael Albaugh < m.e.albaugh@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 15:33 -0800, Michael Albaugh wrote:
> Various "bottom up" methods work, for a sufficiently lax
> definition of "work" that does not include "gives usable
> error messages". Yes, I know, been through that fight ages
> ago, many times. It is theoretically possible to write such
> a parser whose error-handling doesn't suck, in the same
> sense that it is possible to write a fully compliant ADA
> compiler on a Turing machine. I'm not holding my breath.

The Metaware LR parser generator had a very good error recovery method
that produced excellent error messages.

I think it was the subject of Tom Pennello's MS thesis at UC Santa Cruz.

Too bad Frank De Remer and Tom Pennello never got around to publishing
"Compiler Construction By Tool and By Hand."
----------------------------------------------------------------------
Link-011

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 3:59 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 15:51 -0800, Luca Severini wrote:
> sbr *+14 copy the B-Address (which is the return address itself) 
register in the 0-0 two instructions below.
> Then the address copied there will be copied into X3.
> Correct?

That's correct. You have to hold your mouth just right for 1401
programming to make sense. Don't hurt yourself.

> > I can't test your code now but I will asap.
> > The location *+14 to what of the following instructions, correspond?
> >
> > Luca
> >
> >
> > On Dec 2, 2014, at 3:32 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:
> >
> >> On Tue, 2014-12-02 at 15:08 -0800, Luca Severini wrote:
> >>> And I do need recursion... ;-)
> >>
> >> Then you'll need to make a stack of activation records, and a stack
> >> pointer, and put the return address in the activation record in the
> >> stack, and finally move the return address into the subroutine exit
> >> branch.
> >> 
----------------------------------------------------------------------
 
Link-012
 
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Tue, Dec 02, 2014 4:02 pm
To:	Jay Jaeger < cube1@charter.net>
Cc:	1401_software@computerhistory.org
Hi Jay,

I'm a CS student at SJSU indeed but I worked many years in Italy 
(I'm from Rome) as a software developer.
My first real computer at work was a Macintosh in 1986.
I developed software on it using Assembly and C/C++ (in that 
temporal order).
I also had a Sinclair Spectrum with a Z80 and 48KB which I 
programmed just for fun in Basic and/or Assembly.

Yes, the 1401 is very different and more difficult but I 
like the challenge to write a C compiler on a computer
which was developed 10 years before C and obviously lacks 
some featured later CPUs have to ease the development of
complex (iterative, reentrant, etc.) software.

Luca


On Dec 2, 2014, at 3:52 PM, Jay Jaeger < cube1@charter.net> wrote:

> Van has addressed this, but I thought I'd chime in, too.
>
> One can write a C compiler using any number of techniques OTHER than
> recursive descent. For example, one might generate a parser for a cross
> compiler using YACC, which is LALR (look-ahead LR). I would expect Luca
> has probably already done so.
>
> Luca's C *runtime* will presumably need to *simulate* a stack somehow,
> since C expects to use "activation record" stack frames - and Van
> provide some hints about that. Basically, the stack can be done by
----------------------------------------------------------------------
Link-013

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Tue, Dec 02, 2014 4:05 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>

On Dec 2, 2014, at 3:39 PM, Luca Severini < lucaseverini@mac.com> wrote:

> Right. Is a cross compiler.
> I know I could simulate recursion but I'd like to do a compiler 
(a Small-C compiler btw)
> which work without tricks as much as possible.
> I have quite good experience with MC68xxx and Z80 Assembly but 
1401 is... different. ;-)

Actually, not so different from its contemporaries. The first machine
I'm aware of having a hardware stack was the KDF9, and a quick
web-search says it came out in 1964. The 68xxx and Z80 are much
later as well.

> However, thanks to the help I'm getting here, it seems possible.

I can pretty strongly recommend a threaded approach as I mentioned
the PDP-11 used. That is, you "compile" to a set of "instructions"
for a virtual machine, where each instruction is the address of
a routine in your "run time". If you use a uniform 6-character
"cell" on your stack, it could be either an integer suitably
large for "unsigned int" behavior, or an address (in 1401 format)
or possibly even a pair of addresses (for strings, as "all bits zero"
is a blank on the 1401, and although C doesn't require that '\0'
actually be "all bits zero", pain follows taking that liberty.

The DEC paper is apparently available on Gordon Bell's site, at
http://research.microsoft.com/en-us/um/people/gbell/Computer_Engineering/00000387.htm

-Mike
----------------------------------------------------------------------
Link-014

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 4:09 pm
To:	Jay Jaeger < cube1@charter.net>
Cc:	1401_software@computerhistory.org
On Tue, 2014-12-02 at 17:52 -0600, Jay Jaeger wrote:
> When I was taking my grad-school compiler class, we wrote an ALGOL-68
> compiler that generated "tuples", and I wrote the code generation that
> took the tuples and generated PDP-11 RT-11 compatible relocatable
> object files (we didn't even go through an assembler).

The 1401 Fortran-II compiler had a very interesting way of working. It
didn't need any tapes (unless the compiler was on tape). It kept the
program in core, and loaded pieces of the compiler (63 of them),
gradually turning the Fortran program into machine code, sitting there
in core and ready to run. This was described in IBM Systems Journal 4,
1 (1965). It fits in 8k. I think Al Kossow has it at bitsavers.org,
but if it's not there I'm happy to send it (or the IBM Sys.J. paper) to
anybody who wants it.

It's a real eye-opener about using SAR and SBR to process
variable-length fields.

----------------------------------------------------------------------
Link-015

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Tue, Dec 02, 2014 4:12 pm
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401 Software Team < 1401_software@computerhistory.org>

On Dec 2, 2014, at 3:55 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:

> On Tue, 2014-12-02 at 15:33 -0800, Michael Albaugh wrote:
>> Various "bottom up" methods work, for a sufficiently lax
>> definition of "work" that does not include "gives usable
>> error messages". Yes, I know, been through that fight ages
>> ago, many times. It is theoretically possible to write such
>> a parser whose error-handling doesn't suck, in the same
>> sense that it is possible to write a fully compliant ADA
>> compiler on a Turing machine. I'm not holding my breath.
>
> The Metaware LR parser generator had a very good error recovery method
> that produced excellent error messages.
>
> I think it was the subject of Tom Pennello's MS thesis at UC Santa Cruz.

Do you know if it is available on the net, somewhere. I keep hearing
about good bottom-up parsers, but they never seem to "go mainstream".

> Too bad Frank De Remer and Tom Pennello never got around to publishing
> "Compiler Construction By Tool and By Hand."

I would _so_ buy that. I did buy J.A.N. Lee's Anatomy of a Compiler,
and it explained a lot of stuff I had just taken on faith, long enough
to pass the exam.

The first compiler I ever wrote was a class assignment, integer-subset
Algol 60 -> CDC6400. If Luca thinks the 1401 is weird, he should take
a look at that machine.

-Mike
----------------------------------------------------------------------
Link-016

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 4:15 pm
To:	Michael Albaugh < m.e.albaugh@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 16:05 -0800, Michael Albaugh wrote:
> I can pretty strongly recommend a threaded approach as I mentioned
> the PDP-11 used. That is, you "compile" to a set of "instructions"
> for a virtual machine, where each instruction is the address of
> a routine in your "run time". If you use a uniform 6-character
> "cell" on your stack, it could be either an integer suitably
> large for "unsigned int" behavior, or an address (in 1401 format)
> or possibly even a pair of addresses (for strings, as "all bits zero"
> is a blank on the 1401, and although C doesn't require that '\0'
> actually be "all bits zero", pain follows taking that liberty.

The floating-point arithmetic, subscripting, and I/O in the 1401
Fortran-II compiler used something like what later came to be called
"P-Code," the name used for it in the UCSD Pascal compiler.

I remember seeing 68000 Forth codes for which the compiler produced a
list of routines' addresses lined up, then the stack pointer was pointed
at the last one, then a return instruction was executed. The bottom of
the stack was the address of the control routine.

----------------------------------------------------------------------
Link-017

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Tue, Dec 02, 2014 4:16 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>

On Dec 2, 2014, at 4:10 PM, Luca Severini < lucaseverini@mac.com> wrote:

> I'm using in part that approach.
> For example for the bitwise operations.
> I created some routines and, or, xor, shl (shift left), shr (shift right).

_technically_ you will not need separate right-shifts for signed and
unsigned. In practice, your users will tar and feather you for using
a non-sign-extending right-shift for signed ints. One compiler for the
x86 did that (it is/was legal, as right-shifting a negative value is/was
undefined behavior). You should have heard the swearing!.

> Same for some comparison like >= and < =
> Probably I need to do something also for strings like C intend them...

Like I said, you are going to run into the issue of '\0' being either
a blank (space) or flame-bait.

-Mike
----------------------------------------------------------------------
Link-018

Subject:	
 Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Tue, Dec 02, 2014 4:16 pm
To:	"Van.Snyder@jpl.nasa.gov" < Van.Snyder@jpl.nasa.gov>, 
Paul Laughton < paul.laughton@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Just to send this around again ... a real gem, and done on 
the 8K UCLA 1401 ca 1963-4 (attached).

Cheers,

Alan

    From: Van Snyder < Van.Snyder@jpl.nasa.gov>
    To: Paul Laughton < paul.laughton@gmail.com>
    Cc: 1401 Software Team < 1401_software@computerhistory.org>
    Sent: Tuesday, December 2, 2014 3:37 PM
    Subject: Re: [1401_software] Storing I-Address register

    On Tue, 2014-12-02 at 15:19 -0800, Paul Laughton wrote:
    > Indeed, how does one write a C compiler without recursive descent?

    One could use LR for parsing, but that needs a stack too, just not for
    recursion.

    Now that would be an interesting project: An LR parser generator, either
    using Pager's algorithm or De Remer's LALR, written in Autocoder.

    You'd want to use an aggressive compression scheme on the LR table,
    something like the "comb" method that De Remer and Pennello produced
    from the Metaware LALR generator.

Attachment pd1-3-schorre-AlanKay.pdf 

----------------------------------------------------------------------
Link-019

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Tue, Dec 02, 2014 4:25 pm
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401 Software Team < 1401_software@computerhistory.org>

On Dec 2, 2014, at 4:15 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:

> The floating-point arithmetic, subscripting, and I/O in the 1401
> Fortran-II compiler used something like what later came to be called
> "P-Code," the name used for it in the UCSD Pascal compiler.

Well before Pascal, too :-) Many systems used such "virtual machines",
sometimes in the form of otherwise unused op-codes which would trap
to a routine to emulate them. "Thread code" uses addresses of the routines
rather than "signifiers" of what to call, but that is essentially a space/time
tradeoff.

> I remember seeing 68000 Forth codes for which the compiler produced a
> list of routines' addresses lined up, then the stack pointer was pointed
> at the last one, then a return instruction was executed. The bottom of
> the stack was the address of the control routine.

Does not sound like any Forth I've met, but I haven't met then all,
and there are certainly some odd ones out there. Usually there is
a Forth "Instruction pointer" (or Working Pointer) which is used to
fetch the next "word" to execute, and that points to a data-structure
that contains a pointer to the actual code to execute. There's also
that thing about two stacks (essentially one for parameters/results
and one for control-flow. Only the latter is usually the "native"
stack-pointer (on machines that have one).

-Mike

----------------------------------------------------------------------
Link-020

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Tue, Dec 02, 2014 4:32 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>

On Dec 2, 2014, at 4:18 PM, Luca Severini < lucaseverini@mac.com> wrote:

>
> On Dec 2, 2014, at 4:16 PM, Michael Albaugh < m.e.albaugh@gmail.com> wrote:
>> Like I said, you are going to run into the issue of '\0' being either
>> a blank (space) or flame-bait.
>
> I was thinking to use the unused bitzone as '\0'...
> What do you think?

Later you clarify that you mean the 'A' bit, but in what sense
is it "unused". It is part of the letters J-R, and several
special characters. Or did you mean a character with _only_
the 'A' bit set? If so, you will still run into people who
will do something like
int foo = *char_ptr;
and complain loudly if foo is (or is not) all-bits zero.
If they expected 8-bit-binary data, they will object to
you converting the A-bit into a zero, and if they expected
to be pointing at a char array that is a string, they will
object to !foo being false if you don't convert it.

And then we get into that whole (CHAR_BITS < 8) mess.

-Mike
----------------------------------------------------------------------
Link-021


Subject:	
 Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Tue, Dec 02, 2014 4:45 pm
To:	Michael Albaugh < m.e.albaugh@gmail.com>, 
Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Hi Folks

Actually, the B5000 likely hit the bricks first (in late 62). 
And it had much much more than just a stack, but many of the best 
HW/SW ideas of all time directly executed by HW.

One of my favorite papers of all time is by its designer 
Bob Barton ca. 1961 -- and it ranks high for being really short 
with super high gem density (attached).

Cheers

Alan

Attached p393-barton-AlanKay.pdf

    From: Michael Albaugh < m.e.albaugh@gmail.com>
    To: Luca Severini < lucaseverini@mac.com>
    Cc: 1401 Software Team < 1401_software@computerhistory.org>
    Sent: Tuesday, December 2, 2014 4:05 PM
    Subject: Re: [1401_software] Storing I-Address register


    On Dec 2, 2014, at 3:39 PM, Luca Severini < lucaseverini@mac.com> wrote:

    > Right. Is a cross compiler.
    > I know I could simulate recursion but I'd like to do a
 compiler (a Small-C compiler btw)
    > which work without tricks as much as possible.
    > I have quite good experience with MC68xxx and Z80 Assembly 
but 1401 is... different. ;-)

    Actually, not so different from its contemporaries. The first machine
    I'm aware of having a hardware stack was the KDF9, and a quick
    web-search says it came out in 1964. The 68xxx and Z80 are much
    later as well.

    > However, thanks to the help I'm getting here, it seems possible.

    I can pretty strongly recommend a threaded approach as I mentioned
    the PDP-11 used. That is, you "compile" to a set of "instructions"
    for a virtual machine, where each instruction is the address of
    a routine in your "run time". If you use a uniform 6-character
    "cell" on your stack, it could be either an integer suitably
    large for "unsigned int" behavior, or an address (in 1401 format)
    or possibly even a pair of addresses (for strings, as "all bits zero"
    is a blank on the 1401, and although C doesn't require that '\0'
    actually be "all bits zero", pain follows taking that liberty.

    The DEC paper is apparently available on Gordon Bell's site, at

http://research.microsoft.com/en-us/um/people/gbell/Computer_Engineering/00000387.htm




    -Mike

    _________


p393-barton-AlanKay.pdf


----------------------------------------------------------------------
Link-022

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 4:46 pm
To:	Michael Albaugh < m.e.albaugh@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 16:16 -0800, Michael Albaugh wrote:
> Like I said, you are going to run into the issue of '\0' being either
> a blank (space) or flame-bait.

I'm curious what Luca is proposing to use for end-of-string (NULL). \0
is blank on the 1401. How about GMWM, which doesn't print?

Van

----------------------------------------------------------------------
Link-023

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 4:47 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 16:22 -0800, Luca Severini wrote:
> I mean, the A-bit is kinda of unused so could be used to mark the end
> of string like '\0' does.

Except that, without a special RPQ, you can't read it from the 1402....
----------------------------------------------------------------------
Link-024

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Tue, Dec 02, 2014 4:53 pm
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401 Software Team < 1401_software@computerhistory.org>

On Dec 2, 2014, at 4:46 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:

> On Tue, 2014-12-02 at 16:16 -0800, Michael Albaugh wrote:
>> Like I said, you are going to run into the issue of '\0' being either
>> a blank (space) or flame-bait.
>
> I'm curious what Luca is proposing to use for end-of-string (NULL). \0
> is blank on the 1401. How about GMWM, which doesn't print?

It does on a 1443 with the right type-bar. :-) but seriously, there
is (I believe) some wiggle-room about what character is actually stored
when you use '\0', that character does have to compare equal in an
explicit comparison (if (*cprt == '\0'), but pretty much everybody
assumes that if (!*cptr) will also work. So the terminator pretty
much has to really be all-bits-zero (1401 blank). I think Luca was
thinking of using Substitute-blank (A-bit) for the _blanks_, and
all-bits-zero for '\0'. Less pain. But it does mean that the translation
needs to be made on input (convert blank to subts-blank), and possibly
output (what does 14503 print?)

Of course, "splitting" a "word" into multiple "chars" for output is
going to be fraught.

-Mike
----------------------------------------------------------------------
Link-025

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 4:58 pm
To:	Alan Kay < alan.nemo@yahoo.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Wed, 2014-12-03 at 00:45 +0000, Alan Kay wrote:
> Hi Folks
>
>
> Actually, the B5000 likely hit the bricks first (in late 62). And it
> had much much more than just a stack, but many of the best HW/SW ideas
> of all time directly executed by HW.
>
>
>
> One of my favorite papers of all time is by its designer Bob Barton
> ca. 1961 -- and it ranks high for being really short with super high
> gem density (attached).

Burroughs had excellent ideas. Univac had excellent construction (and
some good ideas, too, expecially Exec-8 in its time). Neither one could
figure out how to market their products. Unlike DEC, Univac had a
difficult time figuring out how to ingest user-provided software. In
the late 1960's or early 1970's, JPL was looking for a large computing
center, I don't remember whether to replace about eight 7094's or three
1108's. IBM, Univac, Honeywell, CDC responded. We waited and
waited ... and waited for Burroughs, expecting them to bid the 8500.
When we contacted them, they said "Hmmm, we must have lost that."

In some ways, Univac and Burroughs deserved each other.

----------------------------------------------------------------------
Link-026

Subject:	
    Re: [1401_software] Help
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Tue, Dec 02, 2014 5:01 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>, 
Van Snyder < Van.Snyder@jpl.nasa.gov>
I apparently forgot to hit "send" on this, or my mailer is
messed up. Please forgive the (possible) repeated message
and ignore as needed.


On Dec 2, 2014, at 12:50 PM, Luca Severini < lucaseverini@mac.com> wrote:

> Same here...
> I'm working to a Small-C cross -compiler for the 1401.

I'm curious how you plan to handle the way C has a built-in
requirement for binary (unlike Fortran). I can imagine using
6-digit numbers for everything and doing the modulo 2^^16
for unsigned ints, but it's not going to be pretty. Also
shifts will be nasty. Are you assuming the BBE (part of
advanced Programming, IIRC) is available?

As for the "getting the PC" question, You seem to have gotten
several answers. The question of "return" is that the 1401
was like many (most?) other machines of its time, the return
address is stored in a place dedicated to that subroutine,
in the 1401's case, the address field of the Branch that is
the last instruction of the subroutine. If you plan to allow
recursion, you will probably be better off using one index
register to create a stack. Since you will have no interrupts,
you can pre-pop it to a temp th

SBR

> I't the final project of my Compiler Design class at SJSU.
> The compiler itself is built with Java/JavaCC and (will) 
produce an Autocoder output
> Any comment and suggestion is very welcome.
>
> Luca
> 
----------------------------------------------------------------------
Link-027

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Tue, Dec 02, 2014 5:24 pm
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Sorry, what char is GMWM ?
If doesn't print I think it makes sense to use it as string terminator.

Luca


On Dec 2, 2014, at 4:46 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:

> On Tue, 2014-12-02 at 16:16 -0800, Michael Albaugh wrote:
>> Like I said, you are going to run into the issue of '\0' being either
>> a blank (space) or flame-bait.
>
> I'm curious what Luca is proposing to use for end-of-string (NULL). \0
> is blank on the 1401. How about GMWM, which doesn't print?
>
> Van
> 
----------------------------------------------------------------------
Link-028

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 5:25 pm
To:	Michael Albaugh < m.e.albaugh@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 16:53 -0800, Michael Albaugh wrote:
> On Dec 2, 2014, at 4:46 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:
>
> > On Tue, 2014-12-02 at 16:16 -0800, Michael Albaugh wrote:
> >> Like I said, you are going to run into the issue of '\0' being either
> >> a blank (space) or flame-bait.
> >
> > I'm curious what Luca is proposing to use for end-of-string (NULL). \0
> > is blank on the 1401. How about GMWM, which doesn't print?
>
> It does on a 1443 with the right type-bar. :-) but seriously, there
> is (I believe) some wiggle-room about what character is actually stored
> when you use '\0', that character does have to compare equal in an
> explicit comparison (if (*cprt == '\0'), but pretty much everybody
> assumes that if (!*cptr) will also work. So the terminator pretty
> much has to really be all-bits-zero (1401 blank). I think Luca was
> thinking of using Substitute-blank (A-bit) for the _blanks_, and
> all-bits-zero for '\0'. Less pain. But it does mean that the translation
> needs to be made on input (convert blank to subts-blank), and possibly
> output (what does 14503 print?)

According to page 170 of the Brownie Book, it prints a record mark, or
maybe a cent sign if you have the right chain. It might be a good idea
to ask a real 1401/1403 at CHM.

IBM also provided 64-character printer chains, with a bunch of graphic
characters. These were used to print ALD charts. Also 16-character
"numeric" chains, which made the printer very fast.

Page 17 of the C99 standard (at least WG14/N1124, the 6 May 2005
committee draft) says "A byte with all bits set to 0, called the
null-character, shall exist in the basic execution character set; it is
used to terminate a character string." Later on that page, both upper-
and lower-case letters are required, and a bunch of characters the 1403
couldn't print, even with a 64-character chain. The basic execution
character set is 91 printable characters, plus HT, VT, FF, alert,
backspace, carriage return, and new line. Presumably also NULL. Page
18 did list 9 ugly trigraphs that could be used in case some characters
don't actually exist. That gets you down to 82 (plus the non-printing
ones \abfnrtv). Eliminate lower-case letters and you're down to 56.

Then there is the NULL pointer, for which 000 would work, since on a
1401 you can't actually access location zero in a meaningful way (except
using the MCM instruction).

> Of course, "splitting" a "word" into multiple "chars" for output is
> going to be fraught.
>
> -Mike
>

----------------------------------------------------------------------
Link-029

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Tue, Dec 02, 2014 5:26 pm
To:	Alan Kay < alan.nemo@yahoo.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>, 
"Van.Snyder@jpl.nasa.gov" < Van.Snyder@jpl.nasa.gov>
Great! Thanks Alan!

Luca


On Dec 2, 2014, at 4:16 PM, Alan Kay < alan.nemo@yahoo.com> wrote:

> Just to send this around again ... a real gem, and done on the 
8K UCLA 1401 ca 1963-4 (attached).
>
> Cheers,
>
> Alan
----------------------------------------------------------------------
Link-030

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 5:27 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 17:24 -0800, Luca Severini wrote:
> Sorry, what char is GMWM ?
> If doesn't print I think it makes sense to use it as string terminator.

GMWM is the group mark with a word mark, CBA8421M, the complement of the
"all zero bits" string terminator mandated by the C standard. It also
terminates record moves using the MCM (P) instruction, and I/O on
devices with %xx addresses.

>
> Luca
>
>
> On Dec 2, 2014, at 4:46 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:
>
> > On Tue, 2014-12-02 at 16:16 -0800, Michael Albaugh wrote:
> >> Like I said, you are going to run into the issue of '\0' being either
> >> a blank (space) or flame-bait.
> >
> > I'm curious what Luca is proposing to use for end-of-string (NULL). \0
> > is blank on the 1401. How about GMWM, which doesn't print?
> >
> > Van
> > 
----------------------------------------------------------------------
Link-031

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Tue, Dec 02, 2014 5:31 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 17:27 -0800, Van Snyder wrote:
> On Tue, 2014-12-02 at 17:24 -0800, Luca Severini wrote:
> > Sorry, what char is GMWM ?
> > If doesn't print I think it makes sense to use it as string terminator.

OOPS BA8421M (odd parity).

> GMWM is the group mark with a word mark, CBA8421M, the complement of the
> "all zero bits" string terminator mandated by the C standard. It also
> terminates record moves using the MCM (P) instruction, and I/O on
> devices with %xx addresses.
>
> >
> > Luca
> > 

----------------------------------------------------------------------
Link-032

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Tue, Dec 02, 2014 5:32 pm
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Then it looks just good.
And for the translation Michael mentioned before I can imagine 
it could happen inside the read and write/print functions of a 
not-yet-existing stdio library.

Luca

On Dec 2, 2014, at 5:27 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:

> On Tue, 2014-12-02 at 17:24 -0800, Luca Severini wrote:
>> Sorry, what char is GMWM ?
>> If doesn't print I think it makes sense to use it as string terminator.
>
> GMWM is the group mark with a word mark, CBA8421M, the complement of the
> "all zero bits" string terminator mandated by the C standard. It also
> terminates record moves using the MCM (P) instruction, and I/O on
> devices with %xx addresses.
> 
----------------------------------------------------------------------
Link-033

Subject:	
 Re: Fortran-II 8K compiler (was Re: [1401_software] Storing I-Address register
	  	
From:	
Robert B Garner < robgarn@us.ibm.com>		 
Date:	Tue, Dec 02, 2014 5:35 pm
To:	Luca Severini < lucaseverini@mac.com>, Van.Snyder@jpl.nasa.gov
Cc:	1401_software@computerhistory.org, Robert B Garner 
< robgarn@us.ibm.com>, "Ed Thelen" < ed@ed-thelen.org>
Luca, Van,

Our 1401 web site has an OCR'd version of IBM JR&D paper (thanks Ed!)
describing the 8K FORTRAN II compiler, along with recent notes by Gary Mokotoff:
http://ibm-1401.info/1401-IBM-Systems-Journal-FORTRAN.html

Here's the scan of the paper itself:

    ACKNOWLEDGEMENT
       The author wishes to express appreciation to his colleagues,
       G. Mokotoff, S. Smillie, and D. Macklin for their generous
       assistance.  Parts of this paper prepared by the author for 
       inclusion in Reference 1. 


Gary Mokotoff and Dave Macklin should still be on this 
1401 software distribution list!

We do have the 1401 binary of this Fortran compiler (it luckily 
was preserved with the Conneticuit system),
which I would like to run on our 1401s some day (likely from the 
729 tape emulator box).

- Robert

p.s.  I've been enjoying the email exchange as our 1401 software 
alias has come alive.  
Ron Mak likely didn't realize that his SJSU compiler-for-1401 
class project would be this 
challenging and generate so much disucssion.  ;-)

I would someday like to see the Dhyrstone.c benchmark run on the 1401.  
Although it was atrocious for gauging the performance of post 80's computers 
(compilers "cheated" via code elimination and it didn't stress cahces), 
it had been OK for embedded micros or pre-80's computers.  
I disliked Dhyrstone so much that it motivated me (and 3 others) to 
co-founder the SPEC Benchmarking cooperative in the late 80s.
----------------------------------------------------------------------
Link-034

Subject:	
   Re: Fortran-II 8K compiler (was Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Tue, Dec 02, 2014 5:55 pm
To:	Robert B Garner < robgarn@us.ibm.com>, 
Luca Severini < lucaseverini@mac.com>, "Van.Snyder@jpl.nasa.gov" < Van.Snyder@jpl.nasa.gov>
Cc:	"1401_software@computerhistory.org" 
< 1401_software@computerhistory.org>
Yes, this is a similar technique to a perhaps earlier Algol compiler 
by Woodger on a really tiny British drum memory machine (and 
even more passes). Their is a nice article about it by Woodger 
in the Journal Of Automatic Programming (maybe '61?)

I remember trying this FORTRAN once, just to see what it did do, 
and how it did it (it was not fast ...) on the 8K 1401 we had 
at Randolph AFB. I did use the RPG system however, and it 
covered parts of the needs of Air Training Command pretty well.

Cheers,

Alan
----------------------------------------------------------------------
Link-035

Subject:	
   Re: Fortran-II 8K compiler (was Re: [1401_software] Storing I-Address register
	  	
From:	
Lawrence Kesteloot < lk@teamten.com>		 
Date:	Tue, Dec 02, 2014 5:58 pm
To:	Robert B Garner < robgarn@us.ibm.com>, Luca Severini 
< lucaseverini@mac.com>, Van.Snyder@jpl.nasa.gov
Cc:	1401_software@computerhistory.org
63 phases?! They store the programs backwards! They sort the 
lines of the program by statement type. This is blowing my mind.

Today it's hard to imagine code that doesn't fit in RAM. It's 
possible that every executable binary on my Mac could fit in 
its 8 GB of RAM simultaneously.

Lawrence
----------------------------------------------------------------------
Link-036

Subject:	
 	IBM Systems Journal 4 RE: [1401_software] Stori ng I-Address register
From:	
< ed@ed-thelen.org>		 
Date:	Tue, Dec 02, 2014 8:10 pm
To:	"1401 Software Team" < 1401_software@computerhistory.org>
IBM Systems Journal 4
  (OCRed)
is available at

http://ibm-1401.info/1401-IBM-Systems-Journal-FORTRAN.html

-Ed Thelen
----------------------------------------------------------------------
Link-037

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Jay Jaeger < cube1@charter.net>		 
Date:	Tue, Dec 02, 2014 8:26 pm
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401_software@computerhistory.org
Yup. I actually played with a copy under 1401 mode on our 1410. The
source code went into the middle of the deck.

If you mean an image of the card deck or tape, I don't see it on
bitsavers. If you have cards, I can read them (I seem to recall it
taking nearly an entire tray).

On 12/2/2014 6:09 PM, Van Snyder wrote:
> On Tue, 2014-12-02 at 17:52 -0600, Jay Jaeger wrote:
>> When I was taking my grad-school compiler class, we wrote an ALGOL-68
>> compiler that generated "tuples", and I wrote the code generation that
>> took the tuples and generated PDP-11 RT-11 compatible relocatable
>> object files (we didn't even go through an assembler).
>
> The 1401 Fortran-II compiler had a very interesting way of working. It
> didn't need any tapes (unless the compiler was on tape). It kept the
> program in core, and loaded pieces of the compiler (63 of them),
> gradually turning the Fortran program into machine code, sitting there
> in core and ready to run. This was described in IBM Systems Journal 4,
> 1 (1965). It fits in 8k. I think Al Kossow has it at bitsavers.org,
> but if it's not there I'm happy to send it (or the IBM Sys.J. paper) to
> anybody who wants it.
>
> It's a real eye-opener about using SAR and SBR to process
> variable-length fields.
> 
----------------------------------------------------------------------
Link-038

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Jay Jaeger < cube1@charter.net>		 
Date:	Tue, Dec 02, 2014 8:30 pm
To:	1401_software@computerhistory.org
An alternative you could consider is actually using the ASCII collating
sequence for strings, and writing your own compare routines, and using
binary for for end of string.

Similarly, you could consider having 12 bit short numbers, binary
encoded in two characters, and 18 or 24 bit longs. Of course, you would
not be able to use the 1401 to actually add or compare or anything like
that.

The result would be pretty close to threaded code, as others have
described - everything would turn into subroutine calls.

On 12/2/2014 6:18 PM, Luca Severini wrote:
>
> On Dec 2, 2014, at 4:16 PM, Michael Albaugh < m.e.albaugh@gmail.com> wrote:
>
>>
>> On Dec 2, 2014, at 4:10 PM, Luca Severini < lucaseverini@mac.com> wrote:
>>
>>> I'm using in part that approach.
>>> For example for the bitwise operations.
>>> I created some routines and, or, xor, shl (shift left), shr (shift right).
>>
>> _technically_ you will not need separate right-shifts for signed and
>> unsigned. In practice, your users will tar and feather you for using
>> a non-sign-extending right-shift for signed ints. One compiler for the
>> x86 did that (it is/was legal, as right-shifting a negative value is/was
>> undefined behavior). You should have heard the swearing!.
>>
----------------------------------------------------------------------
Link-039

 Subject:	
  Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Wed, Dec 03, 2014 2:26 am
To:	Luca Severini < lucaseverini@mac.com>, 
Jay Jaeger < cube1@charter.net>
Cc:	"1401_software@computerhistory.org" 
< 1401_software@computerhistory.org>
Just a suggestion: before trying C, I'd suggest you look at 
its ancestor BCPL by Martin Richards. It is set up to bootstrap from 
one computer to another, and was made to have an Algolic 
language that could be used to write systems. The bootstrap is 
done via a simple byte-code interpreter (that you write), it 
has its own compiler written in itself, and you can modify 
the code generators -- etc.

Cheers,

Alan

    From: Luca Severini < lucaseverini@mac.com>
    To: Jay Jaeger < cube1@charter.net>
    Cc: 1401_software@computerhistory.org
    Sent: Tuesday, December 2, 2014 8:34 PM
    Subject: Re: [1401_software] Storing I-Address register

    I'd like to keep the decimal characteristic of the 1401 
and make my life easier
    not having any real programming experience on 1401.

    For the data types I imagined something like this:

        BOOL      DCW  0                  * 0-1 0-1
        CHAR      DCW  000                * 0-255 00-FF
        SHORT    DCW  00000              * 0-65535 0000-FFFF
        INT      DCW  00000              * 0-65535 0000-FFFF
        LONG      DCW  0000000000        * 0-4294967295 00000000-FFFFFFFF (later)

    Luca

    On Dec 2, 2014, at 8:30 PM, Jay Jaeger < cube1@charter.net> wrote:

    > An alternative you could consider is actually using the ASCII collating
    > sequence for strings, and writing your own compare routines, and using
    > binary for for end of string.
    >
    > Similarly, you could consider having 12 bit short numbers, binary
    > encoded in two characters, and 18 or 24 bit longs.  Of course, you would
    > not be able to use the 1401 to actually add or compare or anything like
    > that.
    >
    > The result would be pretty close to threaded code, as others have
    > described - everything would turn into subroutine calls.
    >
    > On 12/2/2014 6:18 PM, Luca Severini wrote:
    >>
    >> On Dec 2, 2014, at 4:16 PM, Michael Albaugh < m.e.albaugh@gmail.com> wrote:
    >>
    >>>
    >>> On Dec 2, 2014, at 4:10 PM, Luca Severini < lucaseverini@mac.com> wrote:
    >>>
    >>>> I'm using in part that approach.
    >>>> For example for the bitwise operations.
    >>>> I created some routines and, or, xor, shl (shift left), shr (shift right).
    >>>
    >>> _technically_ you will not need separate right-shifts for signed and
    >>> unsigned. In practice, your users will tar and feather you for using
    >>> a non-sign-extending right-shift for signed ints. One compiler for the
    >>> x86 did that (it is/was legal, as right-shifting a negative value is/was
    >>> undefined behavior). You should have heard the swearing!.
    >>>
    >>>> Same for some comparison like >= and <=
    >>>> Probably I need to do something also for strings like C intend them...
    >>>
    >>> Like I said, you are going to run into the issue of '\0' being either
    >>> a blank (space) or flame-bait.
    >>
    >> I was thinking to use the unused bitzone as '\0'...
    >> What do you think?
    >>
    >>>
    >>> -Mike
    >>> 

----------------------------------------------------------------------
Link-040

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Wed, Dec 03, 2014 2:32 am
To:	Alan Kay < alan.nemo@yahoo.com>
Cc:	"1401_software@computerhistory.org" 
< 1401_software@computerhistory.org>
Hi Alan,

It's the final project for my Compiler Design class and 
must be C or, more precisely, Small-C.
However I will give a look to it. Everything suggestion 
that can help is welcome. Thanks!

Luca


On Dec 3, 2014, at 2:26 AM, Alan Kay < alan.nemo@yahoo.com> wrote:

> Just a suggestion: before trying C, I'd suggest you look 
at its ancestor BCPL by Martin Richards. It is set up to bootstrap 
from one computer to another, and was made to have 
an Algolic language that could be used to write systems. The 
bootstrap is done via a simple byte-code interpreter (that 
you write), it has its own compiler written in itself, and 
you can modify the code generators -- etc.
>
> Cheers,
>
> Alan
>
>     From: Luca Severini < lucaseverini@mac.com>
>     To: Jay Jaeger < cube1@charter.net>
>     Cc: 1401_software@computerhistory.org
>     Sent: Tuesday, December 2, 2014 8:34 PM
>     Subject: Re: [1401_software] Storing I-Address register
>
>     I'd like to keep the decimal characteristic of the 1401 
and make my life easier
>     not having any real programming experience on 1401.
>
>     For the data types I imagined something like this:
>
>         BOOL      DCW  0                  * 0-1 0-1
>         CHAR      DCW  000                * 0-255 00-FF
>         SHORT    DCW  00000              * 0-65535 0000-FFFF
>         INT      DCW  00000              * 0-65535 0000-FFFF
>         LONG      DCW  0000000000        * 0-4294967295 00000000-FFFFFFFF (later)
>
>     Luca
>
>     On Dec 2, 2014, at 8:30 PM, Jay Jaeger < cube1@charter.net> wrote:
>
>     > An alternative you could consider is actually using the ASCII collating
>     > sequence for strings, and writing your own compare routines, and using
>     > binary for for end of string.
>     >
>     > Similarly, you could consider having 12 bit short numbers, binary
>     > encoded in two characters, and 18 or 24 bit longs.  Of course, you would
>     > not be able to use the 1401 to actually add or compare or anything like
>     > that.
>     >
>     > The result would be pretty close to threaded code, as others have
>     > described - everything would turn into subroutine calls.
>     >
>     > On 12/2/2014 6:18 PM, Luca Severini wrote:
>     >>
>     >> On Dec 2, 2014, at 4:16 PM, Michael Albaugh < m.e.albaugh@gmail.com> wrote:
>     >>
>     >>>
>     >>> On Dec 2, 2014, at 4:10 PM, Luca Severini < lucaseverini@mac.com> wrote:
>     >>>
>     >>>> I'm using in part that approach.
>     >>>> For example for the bitwise operations.
>     >>>> I created some routines and, or, xor, shl (shift left), shr (shift right).
>     >>>
>     >>> _technically_ you will not need separate right-shifts for signed and
>     >>> unsigned. In practice, your users will tar and feather you for using
>     >>> a non-sign-extending right-shift for signed ints. One compiler for the
>     >>> x86 did that (it is/was legal, as right-shifting a negative value is/was
>     >>> undefined behavior). You should have heard the swearing!.
>     >>>
>     >>>> Same for some comparison like >= and <=
>     >>>> Probably I need to do something also for strings like C intend them...
>     >>>
>     >>> Like I said, you are going to run into the issue of '\0' being either
>     >>> a blank (space) or flame-bait.
>     >>
>     >> I was thinking to use the unused bitzone as '\0'...
>     >> What do you think?
>     >>
>     >>>
>     >>> -Mike
>     >>>
>     >> 

----------------------------------------------------------------------
Link-041

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Wed, Dec 03, 2014 2:53 am
To:	Luca Severini < lucaseverini@mac.com>
Cc:	"1401_software@computerhistory.org" 
< 1401_software@computerhistory.org>
Hi Luca

As your prof about doing BCPL instead ... it's a nice compromise 
language, and could be a very good fit to the 1401 
(and especially for your class project).

Cheers

Alan

    From: Luca Severini < lucaseverini@mac.com>
    To: Alan Kay < alan.nemo@yahoo.com>
    Cc: Jay Jaeger < cube1@charter.net>; 
"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
    Sent: Wednesday, December 3, 2014 2:32 AM
    Subject: Re: [1401_software] Storing I-Address register

    Hi Alan,

    It's the final project for my Compiler Design class 
and must be C or, more precisely, Small-C.
    However I will give a look to it. Everything suggestion 
that can help is welcome. Thanks!

    Luca
----------------------------------------------------------------------
Link-042

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Wed, Dec 03, 2014 3:19 am
To:	Alan Kay < alan.nemo@yahoo.com>
Cc:	"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
Hi Alan,

My prof is Ron Mak who originally wrote the ROPE developer 
environment (Autocoder assembly) for the 1401.
The idea was mine. Instead to create an useless compiler 
nobody will never use I asked to wrote the small-c compiler for the 1401.
Sure is not an easy task but is very interesting and I'm having fun.
Moreover I got a chance to get comments and suggestions 
from expert people like you, Van Snyder, Stan Paddock, Jaeger , Albaugh,and
some more I don't write down just to stay brief...
In any case now is too late to switch on something else. 
Perhaps next semester but only after this compiler is completed.
Thanks for your suggestion anyway.

Luca


On Dec 3, 2014, at 2:53 AM, Alan Kay < alan.nemo@yahoo.com> wrote:

> Hi Luca
>
> As your prof about doing BCPL instead ... it's a nice 
compromise language, and could be a very good fit to the 
1401 (and especially for your class project).
>
> Cheers
>
> Alan

----------------------------------------------------------------------
Link-043

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Wed, Dec 03, 2014 3:38 am
To:	Luca Severini < lucaseverini@mac.com>
Cc:	"1401_software@computerhistory.org" 
< 1401_software@computerhistory.org>
Oh, I know Ron, he's a good guy. A good way to "establish a 
beachhead" for a higher level language on the 1401 is to 
first write an interpreter for a byte coded virtual machine. This 
can be used as a target for a variety of projects -- compilers, 
and meta-compilers (like Meta II) -- and lots of things can 
be accomplished before worrying about the tricky problems 
of generating efficient native code for the 1401.

It's a good approach for a compiler *on* the 1401 itself or 
a cross-compiler to the 1401 (and take a look at the VALGOL 
example in the Meta II paper, to see how much can be accomplished 
how quickly via this route). The wikipedia article on Meta II 
has a link to an online implementation you can try things on ...

This follows a long useful tradition going back to at least 
the beginning of the sixties, and the wrestling with not 
just FORTRAN and COBOL on small machines, but especially Algol 58, 
and Algol 60. (Another basic point is that many of the 
apparent speed losses one incurs from interpretation can be 
made up many times over if you don't have to overlay --
 Engelbart *speeded up* their system on the SDS-940 when they 
moved from a compiler to an interpreter because so much 
more would fit into a working set, and swapping to the drum was 
minimized ....)

And, of course, the B5000 very early did one of the first 
(maybe the first) byte-code VMs except it was a RM (it *was* 
the machine's instruction set).

A classic book is by Randall & Russell that chronicles an early 
successful implementation of Algol-60 (on the KDF9 actually) 
via a parallel implementation of interpreter and compiler. As 
I mentioned, this was the route that BCPL took, that Meta II 
took, the classic Euler implementation by Wirth and Weber, etc.

Cheers

Alan

    From: Luca Severini < lucaseverini@mac.com>
    To: Alan Kay < alan.nemo@yahoo.com>
    Cc: Jay Jaeger < cube1@charter.net>; 
"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
    Sent: Wednesday, December 3, 2014 3:19 AM
    Subject: Re: [1401_software] Storing I-Address register

    Hi Alan,

    My prof is Ron Mak who originally wrote the ROPE developer 
environment (Autocoder assembly) for the 1401.
    The idea was mine. Instead to create an useless compiler 
nobody will never use I asked to wrote the small-c compiler for the 1401.
    Sure is not an easy task but is very interesting and I'm having fun.
    Moreover I got a chance to get comments and suggestions 
from expert people like you, Van Snyder, Stan Paddock, Jaeger , Albaugh,and
    some more I don't write down just to stay brief...
    In any case now is too late to switch on something else. 
Perhaps next semester but only after this compiler is completed.
    Thanks for your suggestion anyway.

    Luca

----------------------------------------------------------------------
Link-044

 Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Wed, Dec 03, 2014 3:51 am
To:	Alan Kay < alan.nemo@yahoo.com>
Cc:	"1401_software@computerhistory.org" 
< 1401_software@computerhistory.org>
I found the article "BCPL: a tool for compiler writing and 
system programming" on the ACM digital library. 
Do you know any other book that could be useful for this or
 similar projects on the 1401?
Thank you!

Luca


On Dec 3, 2014, at 3:38 AM, Alan Kay < alan.nemo@yahoo.com> wrote:

> Oh, I know Ron, he's a good guy. A good way to "establish a 
beachhead" for a higher level language on the 1401 is to 
first write an interpreter for a byte coded virtual machine. This 
can be used as a target for a variety of projects -- compilers, 
and meta-compilers (like Meta II) -- and lots of things can 
be accomplished before worrying about the tricky problems of 
generating efficient native code for the 1401.
>
----------------------------------------------------------------------
Link-045

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Wed, Dec 03, 2014 4:29 am
To:	Luca Severini < lucaseverini@mac.com>
Cc:	"1401_software@computerhistory.org" 
< 1401_software@computerhistory.org>
Hi Luca

As I mentioned, BCPL has an interesting history because of its 
ease of portability and its approach to allowing high-level 
systems programming to be done in it. It was a mainstay at 
Lincoln Labs during the mid to late 60s, was used by 
Strachey and Stoy to write the OS 6 tiny operating system (would be interesting 
on a 1401), and was used by the Computer Science Lab at 
Parc for many of their projects (e.g. the first version of 
Microsoft Word was done at Parc in BCPL). A language derived 
from BCPL which was used for small machines at CMU in the 60s was 
called Bliss (Bill Wulf and Chuck Geschke).

I would urge anyone working on a 1401 to bootstrap Meta II and 
its VM, and then use it to make something like VALGOL or BCPL.

The OS 6 papers are worth reading (they are online).

The 1401 was my first machine (I had spent a little time wiring 
plugboards before this), and I didn't have any perspective 
to see how idiosyncratic it was (even in an era where there was 
a much wider variety of computer architectures one had to 
learn). It just was what it was, and one had to make things work on it.

At that time, I didn't appreciate "meta-thinking" -- on the 
contrary, almost everything about writing 1401 programs 
at Randolph AFB in the early 60s was about optimizations, some 
of them really fragile and dangerous, to deal with the 
rather large problems that were to be solved on an 8K machine (that 
was thought of as "small and slow" even by the standards 
of 1961). The larger B220 was also slow, especially its tape 
drives, and again it had an architecture that by today's
 standards was "unusual".

I should mention that the "meta" that *did* exist -- which was 
quite interesting and powerful -- was the Autocoder 
macro system, and we spent quite a bit of effort writing "tailored 
macros" that would optimize functions upon expansion 
in the assembly process. This was good, and did help level of expression, 
but it missed the deeper meta-game.

However, a few years later in grad school (with a few more 
kinds of computers in between), I started seeing what 
could be accomplished by "meta" and especially having a relatively simple 
and powerful tool -- like a Meta II, or the "Tree Meta"
 that the Engelbart folks used -- to deal with form. I could see 
that many parts of past struggles with "hardware that had 
little to do with software or programming" (which was most 
hardware of the day) would have been much easier to deal 
with if I had BCPL or Meta II, etc. in my utility belt. The heuristic 
of quickly writing an intermediate system to escape 
gratuitous complexities came late to me.

Cheers

Alan

    From: Luca Severini < lucaseverini@mac.com>
    To: Alan Kay < alan.nemo@yahoo.com>
    Cc: Jay Jaeger < cube1@charter.net>; "1401_software@computerhistory.org" 
< 1401_software@computerhistory.org>
    Sent: Wednesday, December 3, 2014 3:51 AM
    Subject: Re: [1401_software] Storing I-Address register

    I found the article "BCPL: a tool for compiler writing and system 
programming" on the ACM digital library. 
    Do you know any other book that could be useful for this or similar 
projects on the 1401?
    Thank you!

    Luca




    On Dec 3, 2014, at 3:38 AM, Alan Kay < alan.nemo@yahoo.com> wrote:

>     Oh, I know Ron, he's a good guy. A good way to "establish 
a beachhead" for a higher level language on the 1401 is 
to first write an interpreter for a byte coded virtual machine. 
This can be used as a target for a variety of projects 
-- compilers, and meta-compilers (like Meta II) -- and lots of 
things can be accomplished before worrying about the tricky 
problems of generating efficient native code for the 1401.
>

----------------------------------------------------------------------
Link-046

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Paul Laughton < paul.laughton@gmail.com>		 
Date:	Wed, Dec 03, 2014 10:51 am
To:	Luca Severini < lucaseverini@mac.com>
Cc:	"1401_software@computerhistory.org" < 1401_software@computerhistory.org>

I am currently writing a Tiny Basic interpreter for the 1401. I will be 
compiling the source into a byte code in a way similar to 
what I did when I wrote Atari Basic a few decades ago. One 
difference between this Basic and Atari Basic is that I will 
not need to implement a List command. The interpretation of the 
Atari Basic byte code back to a listing similar to what the 
user had entered was in an interesting task.

I am thinking that one day people, especially little people, 
will be 
able to write and run simple Basic programs on the 1401.
I am a big fan of Basic. I started by working on the Basic for 
IBM's Call/360 back in the late 60s. Most recently I have 
written a very popular Basic that runs on Android devices.

Paul

On Wed, Dec 3, 2014 at 3:51 AM, Luca Severini < lucaseverini@mac.com> wrote:

    I found the article "BCPL: a tool for compiler writing and system
 programming" on the ACM digital library. 
    Do you know any other book that could be useful for this or 
similar projects on the 1401?
    Thank you!

    Luca

----------------------------------------------------------------------
Link-047

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Wed, Dec 03, 2014 11:03 am
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Tue, 2014-12-02 at 20:20 -0800, Luca Severini wrote:
> Hi van
>
> The sbr instruction "sbr retn&x2, 7&x3" in your example doesn't seem 
to work or I don't understand how it does.
> What should be the memory location of field retn when X2 is 844? 
(I would expect 844 or 845).
> Thank you!

If the address the assembler determines for the symbol RETN is 1000, and
X2 has the value 844, then the runtime value of retn&x2 ought to be
1844. The symbols X1, X2 and X3 are special to Autocoder when they
appear after "&". Otherwise, they are just ordinary labels. So in

x7 equ 94
retn equ 1000
sbr retn&x2, 7&x3

retn&x2 is not 1094, it's 1000 plus the runtime value of X2. The value
that's stored there is 7 plus the runtime value of X3, which in the case
of the recursion outline is the return address (which ought to be 6&x3,
sorry) to account for two argument addresses.

The two-address SBR instruction fills the A- and B-address registers
during instruction decoding. Then, when it executes it stores the
B-address register at the core location specified by the A-address
register. A one-address SBR instruction doesn't change the B-address
register during instruction decoding. In principle, a one-character SBR
instruction ought to work. For example

mcw a,b
sbr

ought to store the address of the character before the B field just
before the A field (assuming A and B have equal length).

There's a description of 1401 dataflow in G24-1377, which is on the
bitsavers.org web site. It doesn't have any advanced features, such as
SBR or multiply, but it is helpful.

As Mike has pointed out, your function invocation strategy might work
better if you put the arguments on the stack instead of after the branch
to the function. Thereby, your return address would always be 0&x3. I
might be tempted to put the stack at the top of core and have it grow
downward. The startup might look like

cs 0
sbr stkptr

Something else you might wish to consider, if you compiler generates
Autocoder instead of machine code, is using the relocatable features and
the linker in the Fortran version of Autocoder. Your code wouldn't
assmeble and link in "real" autocoder (because it didn't provide for
relocatable output or have a linker).

Van

> Luca
>
>
> On Dec 2, 2014, at 3:32 PM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:
>
> > On Tue, 2014-12-02 at 15:08 -0800, Luca Severini wrote:
> >> And I do need recursion... ;-)
> >
> > Then you'll need to make a stack of activation records, and a stack
> > pointer, and put the return address in the activation record in the
> > stack, and finally move the return address into the subroutine exit
> > branch.
> > 

----------------------------------------------------------------------
Link-048

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Wed, Dec 03, 2014 11:07 am
To:	Paul Laughton < paul.laughton@gmail.com>
Cc:	"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
Hi Paul,

Thanks for the suggestion.
I remember you. We meet at the Museum few weeks ago.
I'm really curious to see your Basic for the 1401.
You already gave me the link to your Android Basic.
Is the source of the 1401 Tiny Basic available to give a look to it?

I completely agree that there are people interested in writing simple 
	(or not so simple because or architecture constraint) 
programs for the 1401 as much as there is still people writing software 
	for the Atari VCS, the Mattel Intellivision, the 
Sinclair Spectrum, the Commodore
64, the Commodore Amiga, the Atari ST to name few.
To have accessible and well-known programming languages 
like C and Basic is the key...

Luca


On Dec 3, 2014, at 10:51 AM, Paul Laughton < paul.laughton@gmail.com> wrote:

>
> I am currently writing a Tiny Basic interpreter for the 1401. 
I will be compiling the source into a byte code in a way similar 
to what I did when I wrote Atari Basic a few decades ago. One 
difference between this Basic and Atari Basic is that I will 
not need to implement a List command. The interpretation of the 
Atari Basic byte code back to a listing similar to what the 
user had entered was in an interesting task.
>
----------------------------------------------------------------------
Link-049

 Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Wed, Dec 03, 2014 11:16 am
To:	Alan Kay < alan.nemo@yahoo.com>
Cc:	"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
On Wed, 2014-12-03 at 12:29 +0000, Alan Kay wrote:
> The larger B220 was also slow, especially its tape drives, and again
> it had an architecture that by today's standards was "unusual".

I sent a B220 manual to Al Kossow. It was bound, not loose leaf. I
don't know whether he scanned it and put it on bitsavers.


______________________

----------------------------------------------------------------------
Link-050

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Wed, Dec 03, 2014 11:17 am
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Hi Van,

Your help is really making the difference.
I really hope you will forgive for pestering you with my questions...

One more btw... ;-)
Let's say I have X2 pointing to a memory location but I need to change to 
another location which is 10 locations before (below).
If I subtract a value from an index register the register gets the, how is called?, 
complemented form which causes problems when I want to use for example SBR 
to copy its value in a location.
Using MZ solves the problem but, perhaps, there is a better 
and more elegant) way to do that.
Do you have any suggestion?
Thanks yet again!

Luca

s @10@, x2 subtract 10 from X2
mz X2-1, x2 normalize X2
sbr varadr, 0+x2 save it to varadr



On Dec 3, 2014, at 11:03 AM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:

> On Tue, 2014-12-02 at 20:20 -0800, Luca Severini wrote:
>> Hi van
>>
>> The sbr instruction "sbr retn&x2, 7&x3" in your example doesn't seem to 
work or I don't understand how it does.
>> What should be the memory location of field retn when X2 is 844? 
(I would expect 844 or 845).
>> Thank you!
>
> If the address the assembler determines for the symbol RETN is 1000, and
> X2 has the value 844, then the runtime value of retn&x2 ought to be
> 1844. The symbols X1, X2 and X3 are special to Autocoder when they
> appear after "&". Otherwise, they are just ordinary labels. So in
>
> x7 equ 94
> retn equ 1000
> sbr retn&x2, 7&x3
>
> retn&x2 is not 1094, it's 1000 plus the runtime value of X2. The value
> that's stored there is 7 plus the runtime value of X3, which in the case
> of the recursion outline is the return address (which ought to be 6&x3,
> sorry) to account for two argument addresses.
> 

----------------------------------------------------------------------
Link-051

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Paul Laughton < paul.laughton@gmail.com>		 
Date:	Wed, Dec 03, 2014 11:24 am
To:	Luca Severini < lucaseverini@mac.com>
Cc:	"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
Luca,

My 1401 Basic is just getting started. I have learned a lot about the 1401 from
 writing a SW multiply and divide. It will be a couple of weeks before 
I see any real progress.

Paul

On Wed, Dec 3, 2014 at 11:07 AM, Luca Severini < lucaseverini@mac.com> wrote:

    Hi Paul,

    Thanks for the suggestion.
    I remember you. We meet at the Museum few weeks ago.
    I'm really curious to see your Basic for the 1401.
    You already gave me the link to your Android Basic.
    Is the source of the 1401 Tiny Basic available to give a look to it?

    I completely agree that there are people interested in writing simple 
   (or not so simple because or architecture constraint) programs
    for the 1401 as much as there is still people writing software for the 
	Atari VCS, the Mattel Intellivision, the Sinclair Spectrum, the Commodore
    64, the Commodore Amiga, the Atari ST to name few.
    To have accessible and well-known programming languages like C and Basic is the key...

    Luca


    On Dec 3, 2014, at 10:51 AM, Paul Laughton < paul.laughton@gmail.com> wrote:

>
>     I am currently writing a Tiny Basic interpreter for the 1401. I will be 	
	compiling the source into a byte code in a way similar to what I did when
	 I wrote Atari Basic a few decades ago. One difference between this Basic 
	and Atari Basic is that I will not need to implement a List command. 
	The interpretation of the Atari Basic byte code back to a listing 
similar to 	what the user had entered was in an interesting task.
>
>     I am thinking that one day people, especially little people, will be able
	 to write and run simple Basic programs on the 1401.I am a big fan of 	
	Basic. I started by working on the Basic for IBM's Call/360 back in the 
	late 60s. Most recently I have written a very popular Basic that runs
	 on Android devices.
>
>     Paul
>
>     On Wed, Dec 3, 2014 at 3:51 AM, Luca Severini < lucaseverini@mac.com> wrote:
>
>         I found the article "BCPL: a tool for compiler writing and system 
	programming" on the ACM digital library. 
>         Do you know any other book that could be useful for this or similar 
	projects on the 1401?
>         Thank you!
>
>         Luca
>
----------------------------------------------------------------------
Link-052

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Wed, Dec 03, 2014 11:29 am
To:	Paul Laughton < paul.laughton@gmail.com>
Cc:	"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
Then we are in the same situation... 
Good luck to both of us! ;-)

Luca


On Dec 3, 2014, at 11:24 AM, Paul Laughton < paul.laughton@gmail.com> wrote:

> Luca,
>
> My 1401 Basic is just getting started. I have learned a lot about the 1401 from 
writing a SW multiply and divide. It will be a couple of weeks before I see 
any real progress.
>
> Paul
>
> On Wed, Dec 3, 2014 at 11:07 AM, Luca Severini < lucaseverini@mac.com> wrote:
>
>     Hi Paul,
>
>     Thanks for the suggestion.
>     I remember you. We meet at the Museum few weeks ago.
>     I'm really curious to see your Basic for the 1401.
>     You already gave me the link to your Android Basic.
>     Is the source of the 1401 Tiny Basic available to give a look to it?
>
----------------------------------------------------------------------
Link-053

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Wed, Dec 03, 2014 11:32 am
To:	"Van.Snyder@jpl.nasa.gov" < Van.Snyder@jpl.nasa.gov>
Cc:	"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
As you undoubtedly know, its predecessor the drum based 205 
was an early machine 
programmed by Don Knuth, and his MIX machine and its code 
in the early versions 
of his books was very "220-like". He was also one of the 
programmers of BALGOL on the 220, and Barton was one of the designers of the compiler (I think it was the
 very first pass-and-a-half compiler).

Cheers,

Alan

    From: Van Snyder < Van.Snyder@jpl.nasa.gov>
    To: Alan Kay < alan.nemo@yahoo.com>
    Cc: Luca Severini < lucaseverini@mac.com>; "1401_software@computerhistory.org" 
	< 1401_software@computerhistory.org>
    Sent: Wednesday, December 3, 2014 11:16 AM
    Subject: Re: [1401_software] Storing I-Address register

    On Wed, 2014-12-03 at 12:29 +0000, Alan Kay wrote:



    > The larger B220 was also slow, especially its tape drives, and again
    > it had an architecture that by today's standards was "unusual".


    I sent a B220 manual to Al Kossow.  It was bound, not loose leaf.  I
    don't know whether he scanned it and put it on bitsavers.

----------------------------------------------------------------------
 Link-054

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Alan Kay < alan.nemo@yahoo.com>		 
Date:	Wed, Dec 03, 2014 11:32 am
To:	"Van.Snyder@jpl.nasa.gov" < Van.Snyder@jpl.nasa.gov>
Cc:	"1401_software@computerhistory.org" < 1401_software@computerhistory.org>
As you undoubtedly know, its predecessor the drum based 205 was an early machine 
programmed by Don Knuth, and his MIX machine and its code in the early versions 
of his books was very "220-like". He was also one of the 
programmers of BALGOL on the 220, and Barton was one of the designers of the compiler (I think it was the 
very first pass-and-a-half compiler).

Cheers,

Alan

    From: Van Snyder < Van.Snyder@jpl.nasa.gov>
    To: Alan Kay < alan.nemo@yahoo.com>
    Cc: Luca Severini < lucaseverini@mac.com>; "1401_software@computerhistory.org" 
         < 1401_software@computerhistory.org>
    Sent: Wednesday, December 3, 2014 11:16 AM
    Subject: Re: [1401_software] Storing I-Address register

    On Wed, 2014-12-03 at 12:29 +0000, Alan Kay wrote:



    > The larger B220 was also slow, especially its tape drives, and again
    > it had an architecture that by today's standards was "unusual".


    I sent a B220 manual to Al Kossow.  It was bound, not loose leaf.  I
    don't know whether he scanned it and put it on bitsavers.







----------------------------------------------------------------------
Link-055

Subject:	
 Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Wed, Dec 03, 2014 12:04 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Wed, 2014-12-03 at 11:17 -0800, Luca Severini wrote:
> Hi Van,
>
> Your help is really making the difference.
> I really hope you will forgive for pestering you with my questions...
>
> One more btw... ;-)
> Let's say I have X2 pointing to a memory location but I need 
to change to another location
> which is 10 locations before (below).
> If I subtract a value from an index register the register 
gets the, how is called?, complemented form
> which causes problems when I want to use for example SBR 
to copy its value in a location.
> Using MZ solves the problem but, perhaps, there is a 
better (and more elegant) way to do that.
> Do you have any suggestion?

Subtracting (or adding) a runtime-variable offset from an index register
(or any address) is difficult. The address needs to be converted to
decimal, then do the arithmetic, then convert back to an address.
Routines to do that are attached (and are instructive). For
assembly-time fixed offsets, things are pretty simple. For example, to
add ten to X2 do

sbr x2, 10&x2

To subtract ten, ... well, you can't do that directly, ... but you can
add 15990, which the hardware wraps around at 16000:

sbr x2, 15990&x2

By the way, Autocoder does NOT replace -10 with 15990. It just uses 10.
So you shouldn't expect this to work:

sbr x2, 0-10&x2

If the address to be modified is not in an index register, use the MA
instruction (see page 78 of the Brownie Book):

ma @010@,addr Add ten to Addr
ma @I9?@,addr Subtract ten from Addr (actually add 15990)

It was common to see this being done to addresses within instructions,
not just in three-character data fields.

For machines with less than 4k, MA wasn't provided (except as an
extra-cost RPQ), but Autocoder has an MA macro.

If you want to get the address just before a word mark for a field whose
low-order character is addressed by x2, for example to process
variable-length fields, this is what Gary Mokotoff did in the Fortran-II
compiler

c 0&x2
sar x2

which is why the program was initially stored BACKWARD in core. Why
compare? It doesn't change core, and it doesn't chain the B address,
i.e., the A- and B- address registers are filled with the same values
during I-1, I-2 and I-3 cycles. See G24-1377-0 pages 8-10. One could
use

mcw 0&x2, 0&x2

but that's three characters longer.

Two more useful programs are attached. These are core dump routines
whose output is a bit easier to read than the hardware core dump.
g-dump is from Germany.

> Thanks yet again!

I'm having fun too.

> Luca
>
> s @10@, x2 subtract 10 from X2
> mz X2-1, x2 normalize X2
> sbr varadr, 0+x2 save it to varadr
>
>
>
> On Dec 3, 2014, at 11:03 AM, Van Snyder < Van.Snyder@jpl.nasa.gov> wrote:
>
> > On Tue, 2014-12-02 at 20:20 -0800, Luca Severini wrote:
> >> Hi van
> >>
> >> The sbr instruction "sbr retn&x2, 7&x3" in your example doesn't seem to work or I don't understand how it does.
> >> What should be the memory location of field retn when X2 is 844? (I would expect 844 or 845).
> >> Thank you!
     ----------- attachment #1 3to5.s ------------------------

              job  Convert three-character address to five digits
               ctl  6611
     from      equ  205
     start     lca  @999@,from         First address to convert
     outer     mcw  from,to
               b    c3to5              Convert it
               mcw  to,215
               mcw  from,to
               b    c3to5s             Convert it
               mcw  to,225
               mcw  from,to
               b    c3to5f             Convert it
               mcw  to,235
               mcw  from,to
               b    c3to5x             Convert it
               mcw  to,245
               w
               ma   a1k,from           Bump it by 1k
               c    from,@999@         Q. Wrapped around
               bu   outer              No
     done      h    done
     a1k       dsa  1000
               ltorg*
     *
     * Fast routine to convert the three-character address at
     * ,,to,, to a five-digit address, in place.
     *
     c3to5     sbr  exit&3
               s    to-3               Clear thousands digits
               mz   to,to-4            Low zone to accumulate
     loop1     bwz  loop1x,to-4,2      Q. low zone remaining
               a    @?4@,to-3          Yes, add 4k per low zone
               b    loop1
     loop1x    mz   to-2,to-4          High zone to accumulate
     loop2     bwz  loop2x,to-4,2      Q. high zone remaining
               a    @?1@,to-3          Yes, add 1k per high zone
               b    loop2
     loop2x    za   to&1               Clear zones
     exit      b    0-0
     to        dcw  #5
               dc   #1
               ltorg*
     *
     * Smallest routine to convert the three-character address at
     * ,,to,, to a five-digit address, in place.
     *
     c3to5s    sbr  exits&3
               mcw  k00,to-3           Zero high digits, leave no zone
     loop1s    za   to&1,test&1        Copy digits only
               c    to,test            Q. Address all digits
     exits     be   0-0                Yes, zones all gone
               ma   am1000,to          MA -1000 from address
               a    k1,to-3            Bump thousands
               b    loop1s
     test      dcw  #3
               dc   #1
     k00       dcw  00
     am1000    dsa  16000-1000         -1000
     k1        dcw  1
     *
     * Faster routine to covert the three-character address at
     * ,,to,, to a five-digit address, in place.
     *
     c3to5f    sbr  exitf&3
               mcw  k00,to-3
               bwz  lowf,to-2,2
               bwz  high2,to-2,k
               bwz  high1,to-2,s
               a    *-6,to-3
     high2     a    *-6,to-3
     high1     a    *-6,to-3
     lowf      bwz  donef,to,2
               bwz  low2,to,k
               bwz  low1,to,s
               a    &4,to-3
     low2      a    &4,to-3
     low1      a    &4,to-3
     donef     za   to&1             Clear zones
     exitf     b    0-0
               ltorg*
     *
     * Fastest routine to covert the three-character address at ,,to,,
     * to a five-digit address, in place, but it uses all three index
     * registers.
     *
     c3to5x    sbr  exitx&3
               lca  @0020000400006@,99
               mz   to-2,*&3         Set index register for thousands
               mcw  thou,to-3
               mz   to,*&3           Index register for 4-thousands
               a    thou4,to-3
               za   to&1             Clear zones
     exitx     b    0-0
     thou      dcw  00
               dcw  01
               dcw  02
               dcw  03
     thou4     dcw  00
               dcw  04
               dcw  08
               dcw  12
               end  start
         -------------- attachment #2 5to3.s ------------------------------
               job  Convert five-digit number to an address
               ctl  6611
     five      equ  205
     three     equ  210
               org  336
     zones     dcw  @2skb@
     adr       dcw  #5
     number    dcw  #5
     start     sw   three-2
               lca  &15999,number
     outer     mcw  number,adr    Number to convert
               b    conv          Convert it to an address
               mcw  adr,three
               mcs  number,five
               w
               s    &1000,number  Subtract 1000
               bm   fast,number   q. done
               b    outer         no
     fast      lca  &15999,number
     outer2    mcw  number,adr    Number to convert
               b    conv2         Convert it to an address
               mcw  adr,three
               mcs  number,five
               w
               s    &1000,number  Subtract 1000
               bm   done,number   q. done
               b    outer2        no
     done      h    done
               ltorg*
     *
     * Smallest routine to convert the five-digit number in adr to
     * a three character address, in place.  Needs the digit part
     * of the last character of the address of zones to be nine.
     *
     conv      sbr  convx&3
               bav  *&1           turn off overflow
     loop      a    @96@,adr-3
               bav  loop
               mz   adr-4,adr
               mn   adr-3,*&4
               mz   zones-0,adr-2
     convx     b    0-0
               ltorg*
     *
     * Fastest routine to convert the five-digit number in adr to
     * a three character address, in place.  Uses X1.  Would be
     * slower and 14 characters longer if it saved and restored x1.
     *
     x1        equ  089
     conv2     sbr  conv2x&3
               mcw  adr-3,x1
               mcw  @0@
               mz   hzone-15&x1,adr-2
               mz   lzone-15&x1,adr
     conv2x    b    0-0
     hzone     dcw  @9zri9zri9zri9zri@
     lzone     dcw  @9999zzzzrrrriiii@
               end  start
         -------------- attachment #3   core dump routine -------------
               JOB  Card 1 of core dump routine
     * SET WORD MARKS FOR THE SECOND CARD
               ORG  1
               SW   A1,A2
     A1        SW   A3,A4
     A2        NOP  0,0,0
     A3        SW   A5,A6
     A4        NOP  0,0,0
     A5        SW   A7
     A6        SW   A8,A9
     A7        SW   A10
     A8        SW   A11
     A9           N0
     A10       SW   A12
     A11       SW   A13
     A12       R    BLOOP            READ THE NEXT CARD
     A13       DCW  #1
               JOB  Card 2 of core dump routine
     * Replace group marks in 81-399 by ).
               ORG  1
     BLOOP     MCW  BADDR,BTESTG&6   SET TEST ADDRESS
               MCW  BADDR,BREPLG&6   SET REPLACEMENT ADDR
     BTESTG    BCE  BREPLG,5777&X1,}  GROUP MARK? (B REPLACED) 
     BBUMP     A    BINCR,BADDR      UPDATE TEST ADDRESS
               BCE  BDONE,BADDR-2,4  DONE WITH SCAN?
               B    BLOOP            AROUND AGAIN
     BREPLG    MCW  BLOZ,5777&X1     REPLACE GROUP MARK (B REPLACED)
               B    BBUMP            UPDATE TEST ADDRESS
     BADDR     DCW  @081@
               DC   @ @
     BDONE     CC   K                SKIP TWO LINES
               CS   *-3              NEED NEW WORD MARKS
               SW   CSTART           READY FOR A NEW CARD
     BINCR     R    CSTART           READ A NEW CARD
     BLOZ      DCW  @)@              LOZENGE ON THE  A  CHAIN
               JOB  Card 3 of core dump routine
     * Set word marks for the next card, print the print
     * area, then print the word marks.
               ORG  1
     CSTART    SW   C1,C2
     C1        SW   C3
     C2        SW   C4
     C3        SW   C5,C6
     C4        SW   C7,C8
     C5        SW   C9
     C6        SW   C10,C11
     C7        SW   DLOAD,C14
     C8        SW
     C9        SW   C15,C16
     C10       SW   C17,C12
     C11       CW   C4
     C12       SW   DLOAD2
     C13       W
     C14          2)
     C15          N0
     C16       R    DSTART
     C17       NOP
               JOB  Card 4 of core dump routine
     * Clear 300-332 to make sure 330 isn't a zero.  Fill
     * in the dots and numbers 210-330, print them.
               ORG  1
               DCW  @.......@
     DNUM      DCW  @210@
               DC   #1
     DSTART    CS   332              ENSURE 330 IS NOT @0@
                  N00
               NOP
     DLOAD     LCA  DNUM,210         LOAD NUM TO PRINT
     DLOAD2    LCA                   LOAD DOTS
               CW   C8
               A    DREAD&1,DNUM     ADD 10 T0 NUM
               BCE  DDONE,330,0      DONE?
               A    DREAD&1,DLOAD&6  ADD 10 TO LOAD PLACE
               LCA  2,332            LAST TWO DOTS TO PRINT
               B    DLOAD            AROUND AGAIN
     DDONE     CW   DLOAD2
               W
                  N0
               CC   J                SKIP ONE LINE
     DREAD     R    ESTART           READ THE NEXT CARD
               DCW  #1
               JOB  Card 5 of core dump routine
     * Clear 300-332. Remember whether 101 had a word mark.
     * Set one so we can load from 101 upward.  Load 101-200
     * and its word marks to 201-300.  Clear (or don't
     * clear) the word mark in 201.  Print.  Print word marks.
               ORG  1
     EHAVWM    MCW  ENOP,ECW         CHANGE CW TO NOP
               B    ELOOP
     ESTART    SW   E1
               NOP
     E1        CS   332
               NOP
               BW   EHAVWM,101       WM IN 101?
               SW   101              NO, SET ONE
     ELOOP     LCA  101,201          LOAD TO PRINT AREA
               BCE  ECW,ELOOP&4,3    STORING AT 300 YET?
               A    EREAD,ELOOP&3    UPDATE FROM ADDRESS
               A    EREAD,ELOOP&6    UPDATE TO ADDRESS
               B    ELOOP            NO
     ECW       CW   201              OR MAYBE NOT
               W
                  2)                 PRINT THE WORD MARKS
                  N0
     EREAD     R    FSTART           READ THE NEXT CARD
     ENOP      NOP
               JOB  Card 6 of core dump routine
     * Clear 300 to make sure it isn't zero.  Fill in the
     * dots and numbers 110-200.  Print them.
               ORG  1
               DCW  @.......@
     FNUM      DCW  @110@
               DC   #1
     FSTART    CS   300              ENSURE 300 ISN'T 0
               NOP
               SW   FLOAD2
               NOP
     FLOAD     LCA  FNUM,210         LOAD NUM TO PRINT
     FLOAD2    LCA                   LOAD THE DOTS
               NOP  0
               A    FREAD&1,FNUM     ADD 10 T0 NUM
               BCE  FDONE,300,0      DONE?
               A    FREAD&1,FLOAD&6  ADD 10 TO LOAD PLACE
               NOP  0,0
               B    FLOAD            AROUND AGAIN
     FDONE     CW   FLOAD2
               W
                  N0
               CC   J                SKIP ONE LINE
     FREAD     R    GSTART           READ THE NEXT CARD
               NOP
               JOB  Card 7 of core dump routine
     * Clear 300.  Remember whether 81 had a word mark.  Set
     * one.  Load 81-99 and its word marks to 281-299.
     * Clear (or don't clear) the word mark in 281.  Print.
     * Print word marks.
               ORG  1
     GHAVWM    MCW  GNOP,GCW         CHANGE CW TO NOP
               B    GLOOP
               DCW  #4
               DCW  #1
     GSTART    CS   300
               CS
               BW   GHAVWM,81        WM IN 81?
               SW   81               NO, SET ONE
     GLOOP     LCA  81,201           LOAD TO PRINT AREA
               BCE  GCW,GLOOP&4,3    STORING AT 300 YET?
               A    GREAD,GLOOP&3    UPDATE FROM ADDRESS
               A    GREAD,GLOOP&6    UPDATE TO ADDRESS
               B    GLOOP            NO
     GCW       CW   281              OR MAYBE NOT
               W
                  2)                 PRINT THE WORD MARKS
                  N0
     GREAD     R    HSTART           READ THE NEXT CARD
     GNOP      NOP
               JOB  Card 8 of core dump routine
     * Load index register identification to 281-300.
               ORG  1
     HDOTS     DCW  @......*@
     HINDX1    DCW  @1*..@
               DCW  @*2*.@
     H1        DCW  @.@
     HINDX     DCW  @*3*.@
               DC   #1
     H2        DCW  #1
     H3        DC   #7
     HSTART    SW   H4
               CW   HDOTS&1,HINDX&1
               CW   H2,H1&1
     H4        CW
               LCA  HINDX,300        MOVE XR ID TO 300
               SW   H1,H2&1
               R    ISTART           READ THE NEXT CARD
               DCW  #4
               DCW  #1
               DCW  #2
               DCW  #2
               DCW  #4
               DCW  #1
               JOB  Card 9 of core dump routine
     * Load sense switch identifiers to 201-234.
               ORG  1
     ISSTXT    DCW  @SENSE SWS   ON@
               DC   #1
               DCW  #7
               DCW  #7
     IOFF      DCW  @OFF@
               DC   #1
               DCW  #7
               DCW  #7
               DCW  #1
     ISTART    LCA  ISSTXT,214       LOAD SS ON TEXT TO 214
               LCA  IOFF,234         LOAD SS OFF
               CW   C15
               CW   C12
               NOP
               SW   JSTART
               R    JSTART           READ THE NEXT CARD
               DCW  #1
               JOB  Card 10 of core dump routine
     * Put list of on and off sense switches in 236... (on)
     * or 216... (off).
               ORG  1
     JTWO      DCW  2
               DC   #9
     JSTART    BSS  JON,B            SWITCH ON?
     JOFF      M    JB,236           NO, MOVE SS ID TO OFF
               A    JTWO,JOFF&6      INCR OFF ID SPOT
               B    JBOTH
     JON       M    JB,216           YES, MOVE SS ID TO ON
               A    JTWO,JON&6
               NOP
     JBOTH     A    JREAD,JSTART&4   INCR SWITCH TEST
               A    JREAD,JB         INCR SS ID
               BCE  JREAD,JB,H       DONE?
               NOP
               B    JSTART           AROUND AGAIN
     JREAD     R    KSTART           READ THE NEXT CARD
     JB        DCW  @B@              SS ID TO PRINT
               JOB  Card 11 of core dump routine
     * Save comparison indicators in 100..125.
               ORG  1
     KUNEQ     DCW  @   UNEQUAL@
     KEQUAL    DCW  @EQUAL@
     KHIGH     DCW  @ HIGH@
               DC   #2
     KLOW      DCW  @LOW@
               DC   #4
               DCW  #4
     KSTART    LCA  KUNEQ,110        SAVE  UNEQUAL
               LCA  KEQUAL,115       SAVE  EQUAL
               NOP
               LCA  KHIGH,120        SAVE  HIGH
               LCA  KLOW,125         SAVE  LOW
               NOP  0,0,0
               NOP
               NOP  0
               R    LSTART
               DCW  #1
               JOB  Card 12 of core dump routine
     * Move appropriate comparison indicators to 247..265.
               ORG  1
     LINC      DCW  5003             INC FOR TWO ADDRS
               DC   #6
     LSTART    BU   LINDON           INDICATOR ON?
               NOP  0,0
               NOP  0,0
               B    LINDOF           NO
               DCW  #7
     LINDON    MCW  110,256          MOVE INDICATOR TO PR
               NOP
     LINDOF    A    LREAD,LSTART&4   INCR INDICATOR TEST
               A    LINC,LINDON&6    INCR BOTH ADDRS
               BCE  LREAD,LSTART&4,V  DONE?
               NOP
               B    LSTART           AROUND AGAIN
     LREAD     R    MSTART           READ THE NEXT CARD
               DCW  #1
               JOB  Card 13 of core dump routine
     * Construct overflow off (or on) indicator.
     * Move it to 268..277.
               ORG  1
     MOVFF     DCW  @OVFLO OFF@
               DC   #1
     MSTART    BAV  MOVFL            OVERFLOW?
     MOVON     DCW  @N @             NOP, AND  N  FOR MSG
               DC   @00000@          REST OF THE NOP INSTR
               NOP  0,0
               B    MOVFON
               DCW  #7
     MOVFL     MCW  MOVON,MOVFF      CHANGE  OFF  TO  ON
               NOP
     MOVFON    MCW  MOVFF,277        MOVE MSG TO PRINT AREA
               NOP  0,0
               NOP  0,0,0
               NOP
               NOP  0
               R    NSTART
               DCW  #1
               JOB  Card 14 of core dump routine
     * Move clear routines for 200-299 and 0-80 to
     * 101-116.  Print indicators. Clear 200-299 and 0-80.
     * Set word mark in 1, read a card and branch to 1.
               ORG  1
               DCW  @/299/080,0@     CLEAR STORAGE ROUTINE
               DCW  @01100@          SEE SOURCE CODE BELOW
     NCLEAR    DCW  @1@
               DC   #6
               DCW  #7
               DCW  #4
     NSTART    SW   N1,N2
               CW   JSTART,NCLEAR
               CW
               LCA  NCLEAR,NCLEND-1
               SW   NCLEND,NCL3
               SW   NCL2
     N1        SW   NCL1
               W
               CC   L                SKIP THREE LINES
     N2        CC   K                SKIP TWO LINES
               B    NCLBEG
               DCW  #1
     * Routine to clear 200-299 and 0-80, then set a word
     * mark at 1, read a card and branch to 1.  The text of
     * this routine is punched in cc 1-16 of card N.
               ORG  101
     NCLBEG    CS   299
     NCL1      CS   80
     NCL2      SW   1
     NCL3      R    OSTART
     NCLEND    DCW  #1
               JOB  Move data and word marks to print area
     * Routine to move data and word marks to print area.
     * Convert group marks to ).
     * Read a card when done.
               ORG  78
     DWSTRT    BU   WSTART
     DW1       B    SWITCH
     X1        DCW  @X00@
     DFF       DCW  @FF@
     X2        DCW  333
     DW3       DCW  01
     X3        DC   033
     DWPRNT    W
     DW5       CS   332
               CS
     DWLOOP    SW   212&X3           ASSUME DATA HAS WM
     DW7       MCW  0&X2,212&X3      MOVE THE DATA
     DW8       BW   GOTWM,0&X2       DID IT HAVE WM?
     LOZ       CW   212&X3           NO, CLEAR ASSUMED WM
     GOTWM     BCE  GOTGM,0&X3,}     GROUP MARK?
     DW9       B    NOGM             NO
     GOTGM     MCW  LOZ,212&X3       REPL GROUP MARK WITH )
     NOGM      A    DWREAD,X3        BUMP X3
               A                     BUMP X2 -- MA FOR BIG CORE
     DW12      BCE  DWLOOP,X3-2,0    AROUND AGAIN
               CW   DWSTRT           CHANGED LATER TO W 060
     SWITCH    NOP  080              CHANGED TO N OR /
     DW14      SW   PSTART
     DWREAD    R    PSTART           READ THE NEXT CARD
     DWDOTS    DCW  @........@
     DWLOW     DCW  49               LOW ORDER TWO DIGITS
     DWBEGN    DCW  00333            BEGIN OF LINE
     DWAREA    DC   @-AREA @
               JOB  Card 15 of core dump routine
     * Set word marks, move some code to 164-200.
               ORG  1
     OSTART    SW   O1,O2
     O1        SW   O3,O4
     O2        SW   O5,O6
     O3        NOP
     O4        SW   O7
     O5        SW   O8
     O6        LCA  O9,DWAREA
     O7        R    PSTART
     O8        DCW  @)@              CW JUST BEFORE SWITCH
     O9        DC   @078N080,0011001........4900333-AREA @
               JOB  Card 16 of core dump routine
     * Move some code to 125-163, set some word marks.
               ORG  1
     PSTART    LCA  P1,DW12&7
               SW   DWBEGN-4,DWLOW-1
               SW   DW12,DW12
               SW
               SW   DWDOTS-7
               SW   DWREAD
               SW   DW14,SWITCH
               R    QSTART
               DCW  @)2A2B1410!0}B148M1252A2A176099A@
     P1        DC   @B1060970@
               JOB  Card 17 of core dump routine
     * Move some code to 87-124, set some word marks.
               ORG  1
     QSTART    LCA  Q1,DW8&7
               SW   NOGM,GOTGM
               SW   DW5,DWLOOP
               SW
               SW   DW9
               SW   GOTWM
               SW   DW8,DW7
               R    RSTART
               DCW  @X00FF333010332/332/,2A2M0!02A2@
     Q1        DC   @V1290!01@
               JOB  Card 18 of core dump routine
     * Set some word marks, move some code to 78-86
     * (actually part of an instruction)
               ORG  1
     RSTART    SW   R1,SDONE
               SW   S1,SLOW-6
               LCA  R5,DW1&3
               NOP
               CW   O8
               CW   O5
               SW   X2&1,X2-2
               SW   X1&1,DW1
     R1        R    SSTART
               DCW  #11
     R5        DCW  @   1/B168@
               JOB  Card 19 of core dump routine
     * Move "00333-AREA " with zero suppression to
     * 201-211.  Update "xxxxx-AREA " to 00400.  Put
     * .....39 - ........99 in print area.  Go to print it
     * and to set up to print 333-399 area.
               ORG  1
     SSTART    MCS  DWAREA,211
               MCW  SADDR,DWBEGN     REPLACE 333 WITH 400
     SLOOP     LCA  DWLOW,261        FIRST DOTS OFFSET 49
               LCA                   MOVE THE DOTS
               BCE  SDONE,DWLOW-1,9  DONE FILLING DOTS?
               A    DWREAD,DWLOW-1   BUMP DOTS ADDR BY 10
               A    DWREAD,SLOOP&5   BUMP DOTS POINT BY 10
               B    SLOOP            AROUND AGAIN
     SDONE     LCA  SLOW,251         PUT ......39 IN PRINT
     S1        B    DWPRNT           GO PRINT IT
     SLOW      DCW  @.....39@
     SADDR     DC   00400
               JOB  Test for a blank x00-x99 area
     * Reset ........xx to ........09.  Set starting
     * position for dots to 221.  Check for a blank line
     * without word marks.
               ORG  333
     TBSTRT    MN   DW14&1,DWLOW-1   ZERO TO ........x9
     TB1       MN   WLOOP-1,WLOOP&4  322 BACK TO 222
     TB2       MCW  X2,X1
     TB3       SW   323
     TBLOOP    C    9&X1,332         BLANK AREA?
               BU   DWPRNT           NO, PRINT
     TB4       BW   DWPRNT,0&X1      WORDMARK? NO, PRINT
     TB5       BCE  WRET,X1-1,9      DONE?
     TB6       A    X3-2,X1          BUMP X1 BY 10 -- MA FOR BIG CORE
     TB7       B    TBLOOP           AROUND AGAIN
     MSIZ      DCW  @014@            MEMORY SIZE / 100
               JOB  Card 20 of core dump routine
     * Move some code to 333-364.  Set some word marks.
               ORG  1
     TSTART    CW   S1,SLOW-6
               LCA  T2,TBLOOP&6
               SW   TB1,TB2
               NOP
               NOP  0,0,0
     T1        SW   TB3,TBLOOP
               CW   T1,T1
               R    USTART
     T2        DCW  @D173188D014019M094089,323C0'9332@
               JOB  Card 21 of core dump routine
     * Move some code to 365-396.  Set some word marks.
               ORG  1
     USTART    LCA  U2,TB7&3
               SW   U1,V1
               SW   TB4,TB5
               NOP
               SW   TB6,TB7
     U1        NOP  0,0,0
               SW   DWSTRT,DWSTRT
               R    VSTART
               DCW  @B@              B OF  BU DWPRNT
     U2        DC   @100/V1000'01B0490889A097089B358@
               JOB  Card 22 of core dump routine
     * Set some word marks.  Change SWITCH to 2060N
     * Change first ........x9 to ........09.
     * Move the core size to 396-399.
               ORG  1
     VSTART    SW   XRET,W4
               SW   W5,WTEST
               M    VSWICH,SWITCH&3  CHANGE SWITCH TO 2060
               M
     V1        MN   DWREAD&1,DWLOW-1  X9 TO ........09
               NOP  0,0,0
               LCA  VCORE,MSIZ       SAVE CORE SIZE
               R    WSTART           READ THE NEXT CARD
               W    XRET             NEW FOR SWITCH
     VSWICH    NOP
               DC   @  @
     VCORE     DCW  014              CORE SIZE / 100
               DC   00               TENS DIGIT OF CORE
               DCW  @  CORE SIZE@    JUST A COMMENT
               JOB  Card 23 of core dump routine
     * Move "xxxxx-AREA " with zero supression to 201-211.
     * Update xxxxx by 100.
     * Put ........09 - ........99 to 212-311.
     * Go put data and word marks in the print area and
     * print the data.  Print the word marks on return.
               ORG  1
     WSTART    MCS  DWAREA,211
               A    DWREAD,DWBEGN-2  BUMP ADDR BY 100
     WLOOP     LCA  DWLOW,221        ........X9 TO PRINT
               LCA
               A    DWREAD,WLOOP&5   BUMP ........X9 POSN
               BCE  TBSTRT,DWLOW-1,9  DONE WITH ........X9?
               A    DWREAD,DWLOW-1   BUMP X IN ........X9
               B    WLOOP            AROUND AGAIN
     WRET      A    DWREAD&2,X2      BUMP CORE START BY 100 - MA IF BIG
               B    WTEST
     XRET         2)                 PRINT THE WORD MARKS
     W4        CC   J                SKIP ONE LINE
     W5        MN   DW14&1,X3-2      ZERO TO HIGH DIGIT
     WTEST     C    MSIZ,DWBEGN-2    DONE?
               BU   WSTART           DOESN'T FIT, BUT OK
     *                               (rest is on card R)
               JOB  Card 24 of core dump routine
     * Print whether Sense switch A is on.
               ORG  1
     YSTART    SW   Y1,Y3
               CW   XRET,WTEST
               SW   Y2,YHALT
               SW
               CW   W4,DWSTRT
               NOP
     Y1        CS   332
               CS
     Y2           N0
               LCA  YSWA,213
               SW   YHALT&4
               BSS  YPRINT,A         SS A ON?
     Y3           N0
               MCW  DFF,214          CHANGE MSG TO  OFF
     YPRINT    W
     YHALT     H    YHALT            ALL DONE
     YSWA      DCW  @SENSE SW A ON@
               JOB  Alternative card 12 of core dump routine
     * Clear routine that gets moved to 81-92
               ORG  81
               CS   80
     SETWM2    SW   1
     READX2    R    1
     *
     * First card of two-card alternative sequence for cards 12-14
     * Move appropriate comparison indicators to 247..265.  Move
     * R 001  to 92.
               ORG  1
               SFX  L
     INC       DCW  5003             INC FOR TWO ADDRS
               DC   #6
     START     BU   INDON            INDICATOR ON?
               LCA  MREAD&3,READX2&3  SOME INDICATOR WILL BE OFF
               B    INDOF
               DC   #3               B WITH BLANK D NEEDS NO WM
     MREAD     R    001              GETS MOVED TO 89-92
               DCW  #7
     INDON     MCW  110,256          MOVE INDICATOR TO PR
               NOP
     INDOF     A    READ,START&4    INCR INDICATOR TEST
               A    INC,INDON&6     INCR BOTH ADDRS
               BCE  READ,START&4,V  DONE?
               NOP
               B    START            AROUND AGAIN
     READ      R    STARTM           READ THE NEXT CARD
               DCW  #1
               JOB  Alternative card 13 of core dump routine
     * Second card of two-card alternative sequence for cards 12-14
     * Construct overflow off (or on) indicator.  Move it to 268..277.
     * Move CS 80, SW 1 to 81-88.  Set word marks for it.
     * Print indicators. Clear 200-299 and 0-80.  Set word mark in 1,
     * read a card and branch to 1.
               SFX  M
               ORG  1
     OVMSG     DCW  @OVFLO ON @
               DC   #1
     START     BAV  OVON             OVERFLOW ON?
               MCW  OVFF,OVMSG       NO, CHANGE ON TO OFF
     OVON      MCW  OVMSG,277        MOVE MESSAGE TO PRINT AREA
               SW   OVCC             NEED A WM
               LCA  OVCLR,SETWM2&3   MOVE PART OF CLEAR ROUTINE
               SW   SETWM2,READX2&4  IT NEEDS A WM
               NOP
               B    OVFIN
               DCW  #3               BRANCH WITH BLANK D NEEDS NO WM
     OVFF      DCW  @FF@
               DC   #5
               CS   80               GETS MOVED TO 81-84
     OVCLR     DC   @,001@           GETS MOVED TO 85-88
     OVFIN     W
               CC   L                SKIP 3 LINES
     OVCC      CC   K                SKIP 2 LINES
               CS   299
               NOP
               END
               JOB  Card 1 of core dump routine
     * SET WORD MARKS FOR THE SECOND CARD
               ORG  1
               SW   A1,A2
     A1        SW   A3,A4
     A2        NOP  0,0,0
     A3        SW   A5,A6
     A4        NOP  0,0,0
     A5        SW   A7
     A6        SW   A8,A9
     A7        SW   A10
     A8        SW   A11
     A9           N0
     A10       SW   A12
     A11       SW   A13
     A12       R    BLOOP            READ THE NEXT CARD
     A13       DCW  #1
               JOB  Card 2 of core dump routine
     * Replace group marks in 81-399 by ).
               ORG  1
     BLOOP     MCW  BADDR,BTESTG&6   SET TEST ADDRESS
               MCW  BADDR,BREPLG&6   SET REPLACEMENT ADDR
     BTESTG    BCE  BREPLG,5777&X1,}  GROUP MARK? (B REPLACED) 
     BBUMP     A    BINCR,BADDR      UPDATE TEST ADDRESS
               BCE  BDONE,BADDR-2,4  DONE WITH SCAN?
               B    BLOOP            AROUND AGAIN
     BREPLG    MCW  BLOZ,5777&X1     REPLACE GROUP MARK (B REPLACED)
               B    BBUMP            UPDATE TEST ADDRESS
     BADDR     DCW  @081@
               DC   @ @
     BDONE     CC   K                SKIP TWO LINES
               CS   *-3              NEED NEW WORD MARKS
               SW   CSTART           READY FOR A NEW CARD
     BINCR     R    CSTART           READ A NEW CARD
     BLOZ      DCW  @)@              LOZENGE ON THE  A  CHAIN
               JOB  Card 3 of core dump routine
     * Set word marks for the next card, print the print
     * area, then print the word marks.
               ORG  1
     CSTART    SW   C1,C2
     C1        SW   C3
     C2        SW   C4
     C3        SW   C5,C6
     C4        SW   C7,C8
     C5        SW   C9
     C6        SW   C10,C11
     C7        SW   DLOAD,C14
     C8        SW
     C9        SW   C15,C16
     C10       SW   C17,C12
     C11       CW   C4
     C12       SW   DLOAD2
     C13       W
     C14          2)
     C15          N0
     C16       R    DSTART
     C17       NOP
               JOB  Card 4 of core dump routine
     * Clear 300-332 to make sure 330 isn't a zero.  Fill
     * in the dots and numbers 210-330, print them.
               ORG  1
               DCW  @.......@
     DNUM      DCW  @210@
               DC   #1
     DSTART    CS   332              ENSURE 330 IS NOT @0@
                  N00
               NOP
     DLOAD     LCA  DNUM,210         LOAD NUM TO PRINT
     DLOAD2    LCA                   LOAD DOTS
               CW   C8
               A    DREAD&1,DNUM     ADD 10 T0 NUM
               BCE  DDONE,330,0      DONE?
               A    DREAD&1,DLOAD&6  ADD 10 TO LOAD PLACE
               LCA  2,332            LAST TWO DOTS TO PRINT
               B    DLOAD            AROUND AGAIN
     DDONE     CW   DLOAD2
               W
                  N0
               CC   J                SKIP ONE LINE
     DREAD     R    ESTART           READ THE NEXT CARD
               DCW  #1
               JOB  Card 5 of core dump routine
     * Clear 300-332. Remember whether 101 had a word mark.
     * Set one so we can load from 101 upward.  Load 101-200
     * and its word marks to 201-300.  Clear (or don't
     * clear) the word mark in 201.  Print.  Print word marks.
               ORG  1
     EHAVWM    MCW  ENOP,ECW         CHANGE CW TO NOP
               B    ELOOP
     ESTART    SW   E1
               NOP
     E1        CS   332
               NOP
               BW   EHAVWM,101       WM IN 101?
               SW   101              NO, SET ONE
     ELOOP     LCA  101,201          LOAD TO PRINT AREA
               BCE  ECW,ELOOP&4,3    STORING AT 300 YET?
               A    EREAD,ELOOP&3    UPDATE FROM ADDRESS
               A    EREAD,ELOOP&6    UPDATE TO ADDRESS
               B    ELOOP            NO
     ECW       CW   201              OR MAYBE NOT
               W
                  2)                 PRINT THE WORD MARKS
                  N0
     EREAD     R    FSTART           READ THE NEXT CARD
     ENOP      NOP
               JOB  Card 6 of core dump routine
     * Clear 300 to make sure it isn't zero.  Fill in the
     * dots and numbers 110-200.  Print them.
               ORG  1
               DCW  @.......@
     FNUM      DCW  @110@
               DC   #1
     FSTART    CS   300              ENSURE 300 ISN'T 0
               NOP
               SW   FLOAD2
               NOP
     FLOAD     LCA  FNUM,210         LOAD NUM TO PRINT
     FLOAD2    LCA                   LOAD THE DOTS
               NOP  0
               A    FREAD&1,FNUM     ADD 10 T0 NUM
               BCE  FDONE,300,0      DONE?
               A    FREAD&1,FLOAD&6  ADD 10 TO LOAD PLACE
               NOP  0,0
               B    FLOAD            AROUND AGAIN
     FDONE     CW   FLOAD2
               W
                  N0
               CC   J                SKIP ONE LINE
     FREAD     R    GSTART           READ THE NEXT CARD
               NOP
               JOB  Card 7 of core dump routine
     * Clear 300.  Remember whether 81 had a word mark.  Set
     * one.  Load 81-99 and its word marks to 281-299.
     * Clear (or don't clear) the word mark in 281.  Print.
     * Print word marks.
               ORG  1
     GHAVWM    MCW  GNOP,GCW         CHANGE CW TO NOP
               B    GLOOP
               DCW  #4
               DCW  #1
     GSTART    CS   300
               CS
               BW   GHAVWM,81        WM IN 81?
               SW   81               NO, SET ONE
     GLOOP     LCA  81,201           LOAD TO PRINT AREA
               BCE  GCW,GLOOP&4,3    STORING AT 300 YET?
               A    GREAD,GLOOP&3    UPDATE FROM ADDRESS
               A    GREAD,GLOOP&6    UPDATE TO ADDRESS
               B    GLOOP            NO
     GCW       CW   281              OR MAYBE NOT
               W
                  2)                 PRINT THE WORD MARKS
                  N0
     GREAD     R    HSTART           READ THE NEXT CARD
     GNOP      NOP
               JOB  Card 8 of core dump routine
     * Load index register identification to 281-300.
               ORG  1
     HDOTS     DCW  @......*@
     HINDX1    DCW  @1*..@
               DCW  @*2*.@
     H1        DCW  @.@
     HINDX     DCW  @*3*.@
               DC   #1
     H2        DCW  #1
     H3        DC   #7
     HSTART    SW   H4
               CW   HDOTS&1,HINDX&1
               CW   H2,H1&1
     H4        CW
               LCA  HINDX,300        MOVE XR ID TO 300
               SW   H1,H2&1
               R    ISTART           READ THE NEXT CARD
               DCW  #4
               DCW  #1
               DCW  #2
               DCW  #2
               DCW  #4
               DCW  #1
               JOB  Card 9 of core dump routine
     * Load sense switch identifiers to 201-234.
               ORG  1
     ISSTXT    DCW  @SENSE SWS   ON@
               DC   #1
               DCW  #7
               DCW  #7
     IOFF      DCW  @OFF@
               DC   #1
               DCW  #7
               DCW  #7
               DCW  #1
     ISTART    LCA  ISSTXT,214       LOAD SS ON TEXT TO 214
               LCA  IOFF,234         LOAD SS OFF
               CW   C15
               CW   C12
               NOP
               SW   JSTART
               R    JSTART           READ THE NEXT CARD
               DCW  #1
               JOB  Card 10 of core dump routine
     * Put list of on and off sense switches in 236... (on)
     * or 216... (off).
               ORG  1
     JTWO      DCW  2
               DC   #9
     JSTART    BSS  JON,B            SWITCH ON?
     JOFF      M    JB,236           NO, MOVE SS ID TO OFF
               A    JTWO,JOFF&6      INCR OFF ID SPOT
               B    JBOTH
     JON       M    JB,216           YES, MOVE SS ID TO ON
               A    JTWO,JON&6
               NOP
     JBOTH     A    JREAD,JSTART&4   INCR SWITCH TEST
               A    JREAD,JB         INCR SS ID
               BCE  JREAD,JB,H       DONE?
               NOP
               B    JSTART           AROUND AGAIN
     JREAD     R    KSTART           READ THE NEXT CARD
     JB        DCW  @B@              SS ID TO PRINT
               JOB  Card 11 of core dump routine
     * Save comparison indicators in 100..125.
               ORG  1
     KUNEQ     DCW  @   UNEQUAL@
     KEQUAL    DCW  @EQUAL@
     KHIGH     DCW  @ HIGH@
               DC   #2
     KLOW      DCW  @LOW@
               DC   #4
               DCW  #4
     KSTART    LCA  KUNEQ,110        SAVE  UNEQUAL
               LCA  KEQUAL,115       SAVE  EQUAL
               NOP
               LCA  KHIGH,120        SAVE  HIGH
               LCA  KLOW,125         SAVE  LOW
               NOP  0,0,0
               NOP
               NOP  0
               R    LSTART
               DCW  #1
               JOB  Card 12 of core dump routine
     * Move appropriate comparison indicators to 247..265.
               ORG  1
     LINC      DCW  5003             INC FOR TWO ADDRS
               DC   #6
     LSTART    BU   LINDON           INDICATOR ON?
               NOP  0,0
               NOP  0,0
               B    LINDOF           NO
               DCW  #7
     LINDON    MCW  110,256          MOVE INDICATOR TO PR
               NOP
     LINDOF    A    LREAD,LSTART&4   INCR INDICATOR TEST
               A    LINC,LINDON&6    INCR BOTH ADDRS
               BCE  LREAD,LSTART&4,V  DONE?
               NOP
               B    LSTART           AROUND AGAIN
     LREAD     R    MSTART           READ THE NEXT CARD
               DCW  #1
               JOB  Card 13 of core dump routine
     * Construct overflow off (or on) indicator.
     * Move it to 268..277.
               ORG  1
     MOVFF     DCW  @OVFLO OFF@
               DC   #1
     MSTART    BAV  MOVFL            OVERFLOW?
     MOVON     DCW  @N @             NOP, AND  N  FOR MSG
               DC   @00000@          REST OF THE NOP INSTR
               NOP  0,0
               B    MOVFON
               DCW  #7
     MOVFL     MCW  MOVON,MOVFF      CHANGE  OFF  TO  ON
               NOP
     MOVFON    MCW  MOVFF,277        MOVE MSG TO PRINT AREA
               NOP  0,0
               NOP  0,0,0
               NOP
               NOP  0
               R    NSTART
               DCW  #1
               JOB  Card 14 of core dump routine
     * Move clear routines for 200-299 and 0-80 to
     * 101-116.  Print indicators. Clear 200-299 and 0-80.
     * Set word mark in 1, read a card and branch to 1.
               ORG  1
               DCW  @/299/080,0@     CLEAR STORAGE ROUTINE
               DCW  @01100@          SEE SOURCE CODE BELOW
     NCLEAR    DCW  @1@
               DC   #6
               DCW  #7
               DCW  #4
     NSTART    SW   N1,N2
               CW   JSTART,NCLEAR
               CW
               LCA  NCLEAR,NCLEND-1
               SW   NCLEND,NCL3
               SW   NCL2
     N1        SW   NCL1
               W
               CC   L                SKIP THREE LINES
     N2        CC   K                SKIP TWO LINES
               B    NCLBEG
               DCW  #1
     * Routine to clear 200-299 and 0-80, then set a word
     * mark at 1, read a card and branch to 1.  The text of
     * this routine is punched in cc 1-16 of card N.
               ORG  101
     NCLBEG    CS   299
     NCL1      CS   80
     NCL2      SW   1
     NCL3      R    OSTART
     NCLEND    DCW  #1
               JOB  Move data and word marks to print area
     * Routine to move data and word marks to print area.
     * Convert group marks to ).
     * Read a card when done.
               ORG  78
     DWSTRT    BU   WSTART
     DW1       B    SWITCH
     X1        DCW  @X00@
     DFF       DCW  @FF@
     X2        DCW  333
     DW3       DCW  01
     X3        DC   033
     DWPRNT    W
     DW5       CS   332
               CS
     DWLOOP    SW   212&X3           ASSUME DATA HAS WM
     DW7       MCW  0&X2,212&X3      MOVE THE DATA
     DW8       BW   GOTWM,0&X2       DID IT HAVE WM?
     LOZ       CW   212&X3           NO, CLEAR ASSUMED WM
     GOTWM     BCE  GOTGM,0&X3,}     GROUP MARK?
     DW9       B    NOGM             NO
     GOTGM     MCW  LOZ,212&X3       REPL GROUP MARK WITH )
     NOGM      A    DWREAD,X3        BUMP X3
               A                     BUMP X2 -- MA FOR BIG CORE
     DW12      BCE  DWLOOP,X3-2,0    AROUND AGAIN
               CW   DWSTRT           CHANGED LATER TO W 060
     SWITCH    NOP  080              CHANGED TO N OR /
     DW14      SW   PSTART
     DWREAD    R    PSTART           READ THE NEXT CARD
     DWDOTS    DCW  @........@
     DWLOW     DCW  49               LOW ORDER TWO DIGITS
     DWBEGN    DCW  00333            BEGIN OF LINE
     DWAREA    DC   @-AREA @
               JOB  Card 15 of core dump routine
     * Set word marks, move some code to 164-200.
               ORG  1
     OSTART    SW   O1,O2
     O1        SW   O3,O4
     O2        SW   O5,O6
     O3        NOP
     O4        SW   O7
     O5        SW   O8
     O6        LCA  O9,DWAREA
     O7        R    PSTART
     O8        DCW  @)@              CW JUST BEFORE SWITCH
     O9        DC   @078N080,0011001........4900333-AREA @
               JOB  Card 16 of core dump routine
     * Move some code to 125-163, set some word marks.
               ORG  1
     PSTART    LCA  P1,DW12&7
               SW   DWBEGN-4,DWLOW-1
               SW   DW12,DW12
               SW
               SW   DWDOTS-7
               SW   DWREAD
               SW   DW14,SWITCH
               R    QSTART
               DCW  @)2A2B1410!0}B148M1252A2A176099A@
     P1        DC   @B1060970@
               JOB  Card 17 of core dump routine
     * Move some code to 87-124, set some word marks.
               ORG  1
     QSTART    LCA  Q1,DW8&7
               SW   NOGM,GOTGM
               SW   DW5,DWLOOP
               SW
               SW   DW9
               SW   GOTWM
               SW   DW8,DW7
               R    RSTART
               DCW  @X00FF333010332/332/,2A2M0!02A2@
     Q1        DC   @V1290!01@
               JOB  Card 18 of core dump routine
     * Set some word marks, move some code to 78-86
     * (actually part of an instruction)
               ORG  1
     RSTART    SW   R1,SDONE
               SW   S1,SLOW-6
               LCA  R5,DW1&3
               NOP
               CW   O8
               CW   O5
               SW   X2&1,X2-2
               SW   X1&1,DW1
     R1        R    SSTART
               DCW  #11
     R5        DCW  @   1/B168@
               JOB  Card 19 of core dump routine
     * Move "00333-AREA " with zero suppression to
     * 201-211.  Update "xxxxx-AREA " to 00400.  Put
     * .....39 - ........99 in print area.  Go to print it
     * and to set up to print 333-399 area.
               ORG  1
     SSTART    MCS  DWAREA,211
               MCW  SADDR,DWBEGN     REPLACE 333 WITH 400
     SLOOP     LCA  DWLOW,261        FIRST DOTS OFFSET 49
               LCA                   MOVE THE DOTS
               BCE  SDONE,DWLOW-1,9  DONE FILLING DOTS?
               A    DWREAD,DWLOW-1   BUMP DOTS ADDR BY 10
               A    DWREAD,SLOOP&5   BUMP DOTS POINT BY 10
               B    SLOOP            AROUND AGAIN
     SDONE     LCA  SLOW,251         PUT ......39 IN PRINT
     S1        B    DWPRNT           GO PRINT IT
     SLOW      DCW  @.....39@
     SADDR     DC   00400
               JOB  Test for a blank x00-x99 area
     * Reset ........xx to ........09.  Set starting
     * position for dots to 221.  Check for a blank line
     * without word marks.
               ORG  333
     TBSTRT    MN   DW14&1,DWLOW-1   ZERO TO ........x9
     TB1       MN   WLOOP-1,WLOOP&4  322 BACK TO 222
     TB2       MCW  X2,X1
     TB3       SW   323
     TBLOOP    C    9&X1,332         BLANK AREA?
               BU   DWPRNT           NO, PRINT
     TB4       BW   DWPRNT,0&X1      WORDMARK? NO, PRINT
     TB5       BCE  WRET,X1-1,9      DONE?
     TB6       A    X3-2,X1          BUMP X1 BY 10 -- MA FOR BIG CORE
     TB7       B    TBLOOP           AROUND AGAIN
     MSIZ      DCW  @014@            MEMORY SIZE / 100
               JOB  Card 20 of core dump routine
     * Move some code to 333-364.  Set some word marks.
               ORG  1
     TSTART    CW   S1,SLOW-6
               LCA  T2,TBLOOP&6
               SW   TB1,TB2
               NOP
               NOP  0,0,0
     T1        SW   TB3,TBLOOP
               CW   T1,T1
               R    USTART
     T2        DCW  @D173188D014019M094089,323C0'9332@
               JOB  Card 21 of core dump routine
     * Move some code to 365-396.  Set some word marks.
               ORG  1
     USTART    LCA  U2,TB7&3
               SW   U1,V1
               SW   TB4,TB5
               NOP
               SW   TB6,TB7
     U1        NOP  0,0,0
               SW   DWSTRT,DWSTRT
               R    VSTART
               DCW  @B@              B OF  BU DWPRNT
     U2        DC   @100/V1000'01B0490889A097089B358@
               JOB  Card 22 of core dump routine
     * Set some word marks.  Change SWITCH to 2060N
     * Change first ........x9 to ........09.
     * Move the core size to 396-399.
               ORG  1
     VSTART    SW   XRET,W4
               SW   W5,WTEST
               M    VSWICH,SWITCH&3  CHANGE SWITCH TO 2060
               M
     V1        MN   DWREAD&1,DWLOW-1  X9 TO ........09
               NOP  0,0,0
               LCA  VCORE,MSIZ       SAVE CORE SIZE
               R    WSTART           READ THE NEXT CARD
               W    XRET             NEW FOR SWITCH
     VSWICH    NOP
               DC   @  @
     VCORE     DCW  014              CORE SIZE / 100
               DC   00               TENS DIGIT OF CORE
               DCW  @  CORE SIZE@    JUST A COMMENT
               JOB  Card 23 of core dump routine
     * Move "xxxxx-AREA " with zero supression to 201-211.
     * Update xxxxx by 100.
     * Put ........09 - ........99 to 212-311.
     * Go put data and word marks in the print area and
     * print the data.  Print the word marks on return.
               ORG  1
     WSTART    MCS  DWAREA,211
               A    DWREAD,DWBEGN-2  BUMP ADDR BY 100
     WLOOP     LCA  DWLOW,221        ........X9 TO PRINT
               LCA
               A    DWREAD,WLOOP&5   BUMP ........X9 POSN
               BCE  TBSTRT,DWLOW-1,9  DONE WITH ........X9?
               A    DWREAD,DWLOW-1   BUMP X IN ........X9
               B    WLOOP            AROUND AGAIN
     WRET      A    DWREAD&2,X2      BUMP CORE START BY 100 - MA IF BIG
               B    WTEST
     XRET         2)                 PRINT THE WORD MARKS
     W4        CC   J                SKIP ONE LINE
     W5        MN   DW14&1,X3-2      ZERO TO HIGH DIGIT
     WTEST     C    MSIZ,DWBEGN-2    DONE?
               BU   WSTART           DOESN'T FIT, BUT OK
     *                               (rest is on card R)
               JOB  Card 24 of core dump routine
     * Print whether Sense switch A is on.
               ORG  1
     YSTART    SW   Y1,Y3
               CW   XRET,WTEST
               SW   Y2,YHALT
               SW
               CW   W4,DWSTRT
               NOP
     Y1        CS   332
               CS
     Y2           N0
               LCA  YSWA,213
               SW   YHALT&4
               BSS  YPRINT,A         SS A ON?
     Y3           N0
               MCW  DFF,214          CHANGE MSG TO  OFF
     YPRINT    W
     YHALT     H    YHALT            ALL DONE
     YSWA      DCW  @SENSE SW A ON@
               JOB  Alternative card 12 of core dump routine
     * Clear routine that gets moved to 81-92
               ORG  81
               CS   80
     SETWM2    SW   1
     READX2    R    1
     *
     * First card of two-card alternative sequence for cards 12-14
     * Move appropriate comparison indicators to 247..265.  Move
     * R 001  to 92.
               ORG  1
               SFX  L
     INC       DCW  5003             INC FOR TWO ADDRS
               DC   #6
     START     BU   INDON            INDICATOR ON?
               LCA  MREAD&3,READX2&3  SOME INDICATOR WILL BE OFF
               B    INDOF
               DC   #3               B WITH BLANK D NEEDS NO WM
     MREAD     R    001              GETS MOVED TO 89-92
               DCW  #7
     INDON     MCW  110,256          MOVE INDICATOR TO PR
               NOP
     INDOF     A    READ,START&4    INCR INDICATOR TEST
               A    INC,INDON&6     INCR BOTH ADDRS
               BCE  READ,START&4,V  DONE?
               NOP
               B    START            AROUND AGAIN
     READ      R    STARTM           READ THE NEXT CARD
               DCW  #1
               JOB  Alternative card 13 of core dump routine
     * Second card of two-card alternative sequence for cards 12-14
     * Construct overflow off (or on) indicator.  Move it to 268..277.
     * Move CS 80, SW 1 to 81-88.  Set word marks for it.
     * Print indicators. Clear 200-299 and 0-80.  Set word mark in 1,
     * read a card and branch to 1.
               SFX  M
               ORG  1
     OVMSG     DCW  @OVFLO ON @
               DC   #1
     START     BAV  OVON             OVERFLOW ON?
               MCW  OVFF,OVMSG       NO, CHANGE ON TO OFF
     OVON      MCW  OVMSG,277        MOVE MESSAGE TO PRINT AREA
               SW   OVCC             NEED A WM
               LCA  OVCLR,SETWM2&3   MOVE PART OF CLEAR ROUTINE
               SW   SETWM2,READX2&4  IT NEEDS A WM
               NOP
               B    OVFIN
               DCW  #3               BRANCH WITH BLANK D NEEDS NO WM
     OVFF      DCW  @FF@
               DC   #5
               CS   80               GETS MOVED TO 81-84
     OVCLR     DC   @,001@           GETS MOVED TO 85-88
     OVFIN     W
               CC   L                SKIP 3 LINES
     OVCC      CC   K                SKIP 2 LINES
               CS   299
               NOP
               END

----------------------------------------------------------------------
Link-056

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Wed, Dec 03, 2014 12:40 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Wed, 2014-12-03 at 12:04 -0800, Van Snyder wrote:
> On Wed, 2014-12-03 at 11:17 -0800, Luca Severini wrote:
> > Hi Van,
> >
> > Your help is really making the difference.
> > I really hope you will forgive for pestering you with my questions...
> >
> > One more btw... ;-)
> > Let's say I have X2 pointing to a memory location but I need to change to another location
> > which is 10 locations before (below).

I wrote:

> Subtracting (or adding) a runtime-variable offset from an index register
> (or any address) is difficult. The address needs to be converted to
> decimal, then do the arithmetic, then convert back to an address.

...

> If the address to be modified is not in an index register, use the MA
> instruction (see page 78 of the Brownie Book):
>
> ma @010@,addr Add ten to Addr
> ma @I9?@,addr Subtract ten from Addr (actually add 15990)

If you need to subtract a runtime-variable amount known to be less than
1000 from an address, subtract the number from 16000. Then put BA zones
in the units and hundreds positions (because you know the result is
greater than 15000). Then use MA:

za &16000, adr5 Sets units zone to BA
s adr3, adr5 Leaves units zone as BA (pg 28 of Brownie Book)
mz adr5, adr5-2 Set hundreds zone to BA
ma adr5, x2 Subtract adr3 from x2
...
adr5 dcw #5 Work area
adr3 dcw #3 Offset to be subtracted

----------------------------------------------------------------------
Link-057

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Wed, Dec 03, 2014 1:41 pm
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401 Software Team < 1401_software@computerhistory.org>
Not really to Van, but to Luca and the group:
Those 3to5 and 5to3 routines are going to be very useful
for the C compiler, for pointer manipulation and comparison.
Side note to kibitzers who are not deep-C acolytes, the standard
allows pointers to have pretty much any format (including array
bounds), as long a a pointer can be converted to an integer
which can be converted back to the same pointer with no loss of
information. Pointers to different types can have different
formats at the bit level. Now, in reality, you will be flamed
mercilessly and go out of business selling a compiler that doesn't
store pointers as un-adorned indices into a big sea of bytes.

OTOH, as a class project, the ability to say "Hey, the C standard
does not require casting a pointer to an integer, XORing some
bits, and casting it back to do what you expect" can be priceless.

I'm still eager to see what Luca comes up with for the shifts and
logical ops. C pretty much mandates a binary machine, and the
majority of users expect that it be a twos-complement machine
with word-size a power of two, and the 1401 is just not that.

I do like the "stack grows down from the result of CS 0", and
I'm so far assuming that a 5-character cell and maybe some
6-character "registers" will be in there. C "char" variables
and the aforementioned logical ops will be interesting.

Popcorn at the ready...
-Mike
----------------------------------------------------------------------
Link-058

Subject:	
 Re: [1401_software] Storing I-Address register
	  	
From:	
Luca Severini < lucaseverini@mac.com>		 
Date:	Wed, Dec 03, 2014 1:55 pm
To:	John Gilmore < gnu@toad.com>
Cc:	1401_software@computerhistory.org
Hi John,

I like difficulties in things I'm interested in... ;-)
The fact the 1401 predates C of 10 full years is quite appealing...
I support recursion using index registers indeed. Van helped me a lot with that.
It's already working when I compile by hand because the JavaCC part needs some changes.
I think to expect the availability of index registers is understandable.
Thankfully we have them in one or both the machines at the museum.
Later I may think a way to avoid the use of index registers by "simulation", pre-computation or
other means...

For the bitwise operations I came out with this code which I'm now translating in Autocoder.
I found it in part on internet and changed it to fulfill my needs.
Is not optimized but it seems to work.
There is time for optimization...

Luca


----------------------------------------------------------------------
Link-059

 Subject:	
 	[1401_software] 1401 Macros
From:	
Paul Laughton < paul.laughton@gmail.com>		 
Date:	Wed, Dec 03, 2014 4:49 pm
To:	1401 Software Team < 1401_software@computerhistory.org>
The publication, Autocoder (on Disk) Language Specifications
IBM 1401, 1440, and 1460 ( C24-3258-2 ) describes a bunch of 1401 macros.

Are these macros available?
Is the source code for the macros available?

Paul

----------------------------------------------------------------------
Link-060

Subject:	
    Re: [1401_software] Storing I-Address register
	  	
From:	
Michael Albaugh < m.e.albaugh@gmail.com>		 
Date:	Wed, Dec 03, 2014 5:01 pm
To:	Luca Severini < lucaseverini@mac.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
(These are mostly about issues specific to C, and is long,
so strict 1401 aficionados may want to skip it.)

It looks like you are planning to support "long", but Small-C
originally had only int and char, and the unsigned variants of
them. no "long" and no "struct or union". I would suggest skipping
the pain until you really need to.

On the shifts, you seem to rely on multi and div, although those
will be slow, software emulated, and tricky to use in practice,
as the semantics of overflow need to be handled. Later, in the
logical ops, you use the "add to self to shift left" trick. You
might well use that for shifts as well. Zero-and-add the argument
to a longer (say, 11 character) "register", then "add to self"
n times (for << n) or 16-n times (for >> n) and take either the
rightmost 5 characters (for left-shift) or the next 5 up (for
right shift. Of course, you need to account for the modulo 2^^16
correction before the store.

You pass most parameters as "int", although you shift them by
adds or multiplies (or divides), and check the "sign bit", but
signed arithmetic has undefined behavior in many of these cases,
and will certainly need extreme care when "checking for sign bit"
In fact, the way you do the logicals (and, or, xor) depends on
the underlying arithmetic being unsigned binary, even though your
rop and lop are signed, so even expecting (lop += lop) to have
a "sign bit" as you expect is undefined behavior. On the 1401,
you will instead have to check by comparing > 65535, assuming
5-character "ints" that you trim to approximate 16 bits to
preserve the semantics you are looking for. In short, your
C examples work because you are running them on a machine
such as C expects. The 1401 is not such a machine. I will need
to study this further (not right now, as I am overdue on some
other things), but I suspect there are even darker corners.
Consider a machine with 8-bit (3 character) "int" and the
expression (12 & 8). "sign" would really be (var > 127)
As the loop proceeds, you will see
lop rop slop srop result
012 08 0 0 0
024 16 0 0 0
048 32 0 0 0
096 64 0 0 0
192 128 1 1 1
128 0 1 0 2
0 0 0 0 4
0 0 0 0 8

where slop, srop are "signs" of lop, rop respectively.

Note that unless you "unpack" a character to a two-digit
representation when you operate on it, logical ops won't
make sense. for example 'A" is BA1 but logical ops based
on adding will ignore the BA. So when you push a character
for use in an expression, you will need to make it Octal
or similar, so 'A' would become 061 in C notation.
Storing it back to a character would do the opposite,
so something like the test for ASCII vs EBCDIC (or BCD here):

is_ebcdic = ('J' - 'I') != 1;
would become something like
pushchar 'J' (pushes 041)
pushchar 'I' (pushes 071)
sub (result -030)
pushint 1
eqtest leaves 1 if top two stack elements match)
brcond branches if TOS is !=0

Long winded. Fascinating problem, if somewhat like Don Quixote.

-Mike

_________

----------------------------------------------------------------------
Link-061

Subject:	
 Re: [1401_software] 1401 Macros
	  	
From:	
Van Snyder < Van.Snyder@jpl.nasa.gov>		 
Date:	Wed, Dec 03, 2014 6:50 pm
To:	Paul Laughton < paul.laughton@gmail.com>
Cc:	1401 Software Team < 1401_software@computerhistory.org>
On Wed, 2014-12-03 at 16:49 -0800, Paul Laughton wrote:
> The publication, Autocoder (on Disk) Language Specifications
> IBM 1401, 1440, and 1460 ( C24-3258-2 ) describes a bunch of 1401
> macros.
>
>
> Are these macros available?
> Is the source code for the macros available?

I have an Autocoder tape from Dick Weaver that has all the standard
macros from Tape Autocoder, plus many more. I have another Autocoder
tape with IOCS macros, plus many more. The tapes are attached, as well
as dumps of them. The tapes are in SimH format. The dumps substitute
circumflex for blank, and have counts in the left margin, so some
editing will be necessary to extract the macros as source text. The
Fortran Autocoder doesn't know how to do IOCS, but you can easily run
"real" Autocoder in SimH. The tape with IOCS was set up to run on a
1410 in 1401 compatibility mode, so it has some 1410-related macros. At
208 in record 35, there's a six-character J instruction to get back into
the 1410 OS. SimH won't understand that, so don't push start when it
prints "SWITCH TO 1410 MODE, RESET START" at the end of the run.

[ Van attached 4 big files, totaling a megabyte - check with Van if interested.]

> Paul
> ___


----------------------------------------------------------------------
Link-062
Subject:	
  [1401_software] Subtracting from index registers
	  	
From:	
Luca Severini 	 	 
Date:	Sat, Dec 06, 2014 3:20 pm
To:	Van.Snyder@jpl.nasa.gov
Cc:	1401 Software Team <1401_software@computerhistory.org>
Hi Van,

It's me again. Sorry to disturb your weekend... ;-)

Your code below works perfectly until the runtime amount to subtract is less than 1000.
I have problems to figure out the right way if the amount is larger than 999.
I know that if I use ma with a value in 3-digit address format, it works but perhaps
there is a way to avoid to convert a decimal value in 3-digit address format.
May you please point me in the right direction?
Thank you!!

This doesn't work
ADR5 DCW 00000 Storage

MCW @000@, X2 CLEAR X2
SBR X2, 10000+X2 10000 in X2

MCW @6500@, ADR5 I want X2 to access a string at 500 so I do: 16000-9500 = 6500
MA ADR5, X2 Subtract adr5 from x2
X2 contains something else...

This works
ADR5 DCW 00000 Storage

MCW @000@, X2 CLEAR X2
SBR X2, 10000+X2 10000 in X2

MCW @N!'@, ADR5 I want X2 to access a string at 500 so I do: 16000-9500 = N!'
MA ADR5, X2 Subtract adr5 from x2
X2 contains 500

Luca


----------------------------------------------------------------------
Link-063
Subject:	
    [1401_software] Re: Subtracting from index registers
	  	
From:	
Van Snyder 	 	 
Date:	Sat, Dec 06, 2014 6:55 pm
To:	Luca Severini 
Cc:	1401 Software Team <1401_software@computerhistory.org>
On Sat, 2014-12-06 at 15:20 -0800, Luca Severini wrote:
...
>
>
> >
> > If you need to subtract a runtime-variable amount known to be less than
> > 1000 from an address, subtract the number from 16000. Then put BA zones
> > in the units and hundreds positions (because you know the result is
> > greater than 15000). Then use MA:
> >
> > za &16000, adr5 Sets units zone to BA
> > s adr3, adr5 Leaves units zone as BA (pg 28 of Brownie Book)
> > mz adr5, adr5-2 Set hundreds zone to BA
> > ma adr5, x2 Subtract adr3 from x2
> > ...
> > adr5 dcw #5 Work area
> > adr3 dcw #3 Offset to be subtracted
> >
> >
>


----------------------------------------------------------------------
Link-064
 Subject:	
 	[1401_software] Can someone fix the ROPE bug?
From:	
Paul Laughton 	 	 
Date:	Sat, Dec 06, 2014 10:17 pm
To:	1401 Software Team <1401_software@computerhistory.org>
The bug is that when you card reader input, the file that has the card reader cards appended to the object deck does not get updated with the latest object deck.

Right now, I have to:
Press the "Quite Program" button.
Go Delete the appended file.
Reassemble the source.
Open and close "RunTime Data" dialog (but not make any changes)
Restart the Simulator
Press Start Program

It would make things a lot easier if the appended file was deleted (or rebuilt) after every assembly.
_______________________________________
----------------------------------------------------------------------
Link-065
Subject:	
    [1401_software] Re: Subtracting from index registers
	  	
From:	
Van Snyder 	 	 
Date:	Sun, Dec 07, 2014 11:12 am
To:	Luca Severini 
Cc:	1401 Software Team <1401_software@computerhistory.org>
Luca Severini wrote:
> MCW @000@, X2 CLEAR X2
> SBR X2, 10000+X2 10000 in X2
>

Putting zero into X2 beforehand isn't necessary. All you need in order
to put 10000 into X2 is

SBR X2, 10000

> MCW @6500@, ADR5 I want X2 to access a string at 500 so I do: 16000-9500 = 6500
> MA ADR5, X2 Subtract adr5 from x2
> X2 contains something else...
>

The A and fields of MA is a three-character addresses, regardless of
word marks.

> This works
> ADR5 DCW 00000 Storage
>
> MCW @000@, X2 CLEAR X2
> SBR X2, 10000+X2 10000 in X2
>
> MCW @N!'@, ADR5 I want X2 to access a string at 500 so I do: 16000-9500 = N!'
>

The assembler can create an address constant equal to 16000-9500:

ADR5 DSA 16000-9500

The difficulty is in subtracting a number from an address if the
assembler doesn't know the number, i.e., if it's computed at run time.
In that case, the number needs to be subtracted from 16000 as a
five-digit decimal calculation, the result then needs to be converted to
a three-character address, and that result is then added using MA.

 

----------------------------------------------------------------------
Link-066
From:	
Van Snyder 	 	 
Date:	Sun, Dec 07, 2014 11:18 am
To:	Luca Severini 
Cc:	1401 Software Team <1401_software@computerhistory.org>
Keith Falkner wrote:
> Hi, Luca,
>
> I think this will work properly
>
> To subtract 1382 from X3, do this:
>
> SBR X3,14618&X3
>
> I don't have an actual 1401 handy to let me test this,
> but I think the index registers are forgiving of overflows,
> and will discard the 16000 excess when the calculation is done.

This is correct, if the assembler knows the offset. Autocoder knows how
to add and subtract addresses and offsets, so you could write

SBR X3,16000-1382&X3

(Or maybe you need to write 15999-1381; ask Autocoder -- not the
cross-assembler in Rope, but the real one.)

If the offset is a variable at run time, you need to convert it from a
five-digit decimal number to a three-character address, and then use MA
for the address arithmetic. If the offset is negative, you need to
subtract it from 16000 before converting the result to a three-character
address.

> Only 48 years have elapsed since I regularly programmed a 1401,
> but I surely remember decreasing an index register by one via
>
> SBR X3,15999&X3
>
> and then being amused to see that the B-address assembled as III.
>
> Good luck,
> Keith
>
 
----------------------------------------------------------------------
Link-067

----------------------------------------------------------------------
Link-068
 
----------------------------------------------------------------------
Link-069

----------------------------------------------------------------------
Link-070
 
----------------------------------------------------------------------
Link-071

----------------------------------------------------------------------
Link-072
 
----------------------------------------------------------------------