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 SeveriniDate: 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 ----------------------------------------------------------------------