D

2019-06-25 Thread glen herrmannsfeldt
Someone wrote:

> Thought it was a double word 

> As in DS D

It is a doubleword, specifically a long (64 bit)  floating point type.

And yes,

 DS  D
 
and 

  DS 0D

are commonly used when floating point is not intended. 

And as Fortran programmers would know, E is the short (32 bit) floating point 
type.

Now that I think about it, I don’t remember the assembler notation for 128 bit
(extended precision) floating point constants, though am pretty sure that it
isn’t the Q that IBM and DEC  Fortran uses.

I suppose I don’t see anything wrong with 0D for doubleword alignment, even when
not for floating point data.  Probably better not to use D or 2D or others, 
though.

D would be the one that needed doubleword alignment for OS/360, and so its use
goes back that far.  One could use FL8 for fixed point data, but I suspect 
without
doubleword alignment.

debuggers

2018-08-06 Thread glen herrmannsfeldt
Bernd wrote:

> We also had a self-written batch debugger, which relied completely on 
> S0C1 and SPIE to do its instrumentation and implement the breakpoints; 
> at least in the  first version.

Reminds me of a debugger I used with Orvyl/370 in S/370 days.

I believe it used SVC 255 for breakpoints, which was fine.

The when you continue from the breakpoint, it has to somehow execute
the instruction at the breakpoint before continuing.  I had put a breakpoint
on a BR 0 instruction, which was common in the object code from PL/I (F).

The debugger branched to the address in register 0.

Fortunately, I knew who to contact to fix the bug.  No-one had 
ever tried that before.


S0C1

2018-08-06 Thread glen herrmannsfeldt
Shmuel (Seymour J.) Metz wrote:

> No; it is guarantied to generate a program 001 interrupt.
> You only get an ABEND S0C1 if there is no SPIE/ESPIE exit.

I suspect that some use S0C1 as shorthand, and as you note
incorrect, description for program interrupt 1.j

It might be that some SPIE routines handle the interrupt,
maybe print a message, and then allow it through to the OS.

I do still remember S0C0 from the 360/91 days, which doesn’t
mean program interrupt 0, though the low bits will be .
Dreaded by anyone debugging from a hex dump.

> I've written code that distinguished[1] between a S/360 and a S/370
> with a SPIE[2] for codes 1 and 2; the exit assumed that it was a S/370
> if the code was 2.

I wouldn’t have thought of that one.  Pretty neat.


local labels

2018-08-05 Thread Glen

I believe that some DEC assemblers allow local labels of
the form d$ where d is a digit from 0 to 9.

Local labels need to be unique between any two normal labels.
References to them would, then, only work between those same labels.

-- glen


Re: Count Words?

2018-06-14 Thread glen herrmannsfeldt
Nothing against discussions on how to write fast code, but I don’t believe that 
this is normally necessary.

About 20 years ago, I was counting words, not just how many, but how many of 
each word, on gigabytes of text.  
(Full text US patents for two years.)  I did it in Java (with JIT compiler on), 
and it was plenty fast enough.

I did it using the Java StringTokenizer:  
https://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html

which takes a regular expression for the delimiter.  Then each word found was 
either added to a HashTable,
or the count for it was incremented.

As computers are much faster now, it should be able to do terabytes of text, 
today.

There was one non-obvious thing about the Java code, though.  It seems that the 
way Java
normally does substrings is with a reference to the whole character array, 
which in my case
was a line of text.  That filled up memory faster than it should have.  Using 
new String() on
each word, fixed that problem.  (It only does that for the actual entry in the 
hash table.)

But if you do have exabytes of text, then there might be need for assembly 
speed-up.
Well, OK, petabytes are enough.

Oh, you might also look at the unix wc command, which counts words.  (More 
specifically,
the GNU utilities version, with source available.)

About 25 years ago, I compiled the GNU utilities (as they then existed) to run 
on my OS/2
system.  (That is before Linux, and such, that are so convenient today.)


Re: SDWA - SDWACMPC conversion

2018-04-16 Thread glen herrmannsfeldt
> Maybe I'm missing something, as this is a bit trickier than the usual
> shlop, but wouldn't it be more efficient to OI the last byte of 
> with x'F0', and skip the MVZ?  Using =C'0123...'-C'0'  for the TR table of
> course.

Maybe you are planning to do this a few billion times. 

Otherwise, do you mean more efficient in execution time,
memory used, or time spent coding and debugging?

Using the offset translation table requires that the origin is
appropriate, such that the displacement isn’t negative. 

As a general purpose macro, when you can’t be sure where
or when it might be used, that could be a problem. 

In addition, note the trial execution required when the translate
table crosses a page boundary.  

But most likely more time has been spent discussing the efficiency
than lost by any inefficiencies in the macro.

—glen

tail recursion

2018-02-07 Thread Glen

Someone wrote:


  "yes, I Had to do the Same, when I implemented Quicksort in REXX, 
because

   the OS/2 Implementation of REXX only supported some 32 nesting Levels."


The usual way to write recursive quicksort is to take advantage of tail 
recursion.


Each call will generate two recursive calls for two partitions of the input.

One is done with an actual recursive call, and the other, which would 
normally


occur just before return, is done with a branch back to the top.

This is tail recursion elimination.


If the smaller partition is done with a recursive call, it is guaranteed to

be smaller than half the input, so at most log2(N) levels of recursion.


OOP

2018-02-06 Thread Glen

Someone wrote:


  "OOP is, I think, quite a bit more than a calling standard - it boils 
down to an


abstracted thought process that you simply cannot do in Assembler.

As noted however, you an certainly write a dynamite compiler in HLASM that

compiles a OOP language. "

You can write OOP in Fortran 66, as I have known it done, and you can 
also do it in HLASM.


Yes it is an abstraction, and yes Fortran 66 and HLASM don't help you so 
much, but


the abstraction itself can be written in pretty much any language. Some 
languages have


protection that stops you from cheating, but you can decide not to cheat.

Some have features that help with readability, but again HLASM doesn't.


Re: Fair comparison C vs HLASM

2018-01-31 Thread Glen

On January 31, 2018 at 8:06 AM Kirk Wolf wrote:
On Tue, Jan 30, 2018 at 9:39 PM, Jon Perryman wrote:


C is a byte by byte language. Anything not hidden in a primitive or
function must be processed byte by byte. In primitives and functions, the
compiler can choose how to implement it. The point is C programmers must
process byte by byte unless they can find a function.

I'm sorry, but can't agree with anything of this.



1) Compilers can generate machine instruction implementations that take
advantage of the instructions and architecture available. Even if you
write byte-by-byte code, a compiler may rewrite it to use zArch
instructions that are not byte-by-byte but equivalent. This is distinctly
different from how assemblers work.


I think I at least somewhat understand what he means.
It occurred to me some time ago, that there is no C library
routine to do what MVCIN does.  Not that it is hard to do,
but there just isn't one.  I doubt many compilers compile
the appropriate for loop into MVCIN.



2) The "C Standard Library" is part of the C language standard(s). For
all of the supposed byte-by-byte C programmers that can't find any
functions to use, here are links to the XL/C++ documentation, where the
"Runtime Library Reference" can be found:
https://www-01.ibm.com/support/docview.wss?uid=swg27036892

The bottom line is that this:

memcpy(field1, field2, sizeof(field1));

generates an MVC instruction (or several or a loop or an unrolled loop of
MVC instructions).
To say that the "C Language" is byte-by-byte is pedantic.


It does.  But note that C doesn't have some statements that
other languages have, that generate a lot of code from a small
statement.  No array expressions, for example.


3) I also do not agree with your repeated assertion that it means 
something

significant that C was originally developed on a RISC machine ( I believe
that it was a PDP-7) with only certain instructions.


The RISC/CISC idea didn't come until later.  Machines like the
PDP-7  have simpler instructions to keep costs down, and make
them easier to build.


I would have thought that this kind of argument about the relative 
benefits

of assemblers vs compilers (or assembler vs C) would have been over a
couple of decades ago. A more current argument is static vs dynamic
(VM+JIT) compilation.


Re: Fair comparison C vs HLASM

2018-01-31 Thread Glen

The 360/20 has MVC and CLC, but, strangely, not LR.


(You can use SR and AR instead, so no need for LR.)


Re: Fair comparison C vs HLASM

2018-01-25 Thread Glen

On January 25, 2018 at 10:57 AM Bernd Oppolzer wrote:


(snip)

I would like to add:

Mainframe ASSEMBLER IMHO is the only Assembler language
(or the only instruction set) where humans can write reasonably programs
in.
All other Assemblers or instruction sets lack the same user friendliness
and orthogonality that this platform has from the early days of the 360
system.

VAX is pretty human readable, too.
That was considered important at the time, though just at the
transition away from mostly writing OS in assembler.

But yes, RISC assembler programs are not so readable, and also
x86 (for any value of x) are not so readable.

(snip)


BTW: I know of an old PL/1 compiler (Multics), which did the same
loop unrolling and outperformed ASSEMBLER programmers this way;
my example goes like this:

SUM = 0;
DO I = 1 to 1;
SUM = SUM + I;
END;
PUT SKIP DATA (SUM);


Loop unrolling was a favorite example for the PL/I
preprocessor.  change to %DO and %END and you have an unrolled loop.


Re: Fair comparison C vs HLASM

2018-01-25 Thread Glen

(snip on optimizing and compilers)



On January 24, 2018 at 8:54 PM Paul Raulerson wrote:

Of course, the C compiler took this:

#include

int main(int argc, char *argv[]) {
int c=0;
int x=0;

for (x=0; x< 1; x++) { c++; }

printf ("\nThe final value is [%d]\n", c);
}


and optimized it during compile time.

In fact it optimized it so much it simply generated a LHI of a 
register with 1 in it. (grin) Needless to say, it ran somewhat 
faster than my friend’s program. Even counting the screen print. :)

ite: http://www.gkc.org.uk/gkc | Erdos number: 4


There is a story from the OS/360 days of a popular Fortran benchmark 
that evaluated

complicated math functions and such, all done using statement functions.

It seems that Fortran H expands statement functions inline, and also 
does constant evaluation

at  compile time.

As in the above example, the compiler evaluated the whole thing at 
compile time

(very slowly) and at run time printed out the precomputed value (fast).

If Fortran H could do it 40 years ago, C compilers should do it today.
(But I don't know that Fortran H did loop evaluation.)

-- glen


Re: Load module

2017-11-14 Thread glen herrmannsfeldt
> Yes. My question was "In a called module, how do we determine
> if it was called dynamically or statically”

The whole design, since OS/360, is that you don’t.

If you want to know, pass an argument to the load module that has a different
value for the dynamic case.  

Using LINK, your module is called by the system in pretty much the
same way as any other module is called. The only difference is in the
arguments, which for statically called (or the first of dynamic) is
the PARM string. 

If another load module calls you, with one argument that is a string
after a two byte length, you should work exactly the same way as if
you were not called from another load module. 

Re: Load module

2017-11-12 Thread glen herrmannsfeldt
> Sorry for the confusion caused. I strongly agree this is a basic question
> and I too understand the Static, all the loads will be loaded in to main
> memory and the load will be placed in to the main memory during execution
> time, Dynamic. We can give Call macro and Load macro for the same. My
> question was, what are all the possible options where we can say Static /
> Dynamic by seeing anything? once again, am sorry for the confusion caused.

There may be other explanations, but I usually think about the way the Fortran 
and PL/I (F)
compilers are written.

Fortran H uses the usual OS/360 static overlay system, which all goes 
into one load module.

PL/I (F) uses a dynamic overlay, with around 100 load modules with names 
starting with IEM,
and the first being IEMAA.  Others have names like IEMAB, IEMAC, etc.

So, it isn’t that one load module is dynamic, but the set of 100 all together.

Re: Branch table

2015-10-02 Thread glen herrmannsfeldt
>  "Tony Harminc" <t...@harminc.com> wrote:
(snip)

>L  R14,R4

(snip)

> This sets R14 to the address of the adcon in the entry you just found
> in the table (or it would if the above-mentioned boundary alignment
> problem wasn't there). You need
   
No, this loads R14 from an address near the beginning of memory.  

Pretty sneaky calling it R4, but the value is 4, so the result is actually

L  R14,4

or more precisely

L  R14,4(0,0)

(unless you are on a PDP-10, where the registers are addressable as
the first 16 locations in memory).

-- glen



Re: local labels

2015-07-02 Thread glen herrmannsfeldt
As well as I know it, Macro-11, the assembler for the PDP-11, 
has local labels with the scope delimited by non-local labels.

From: https://en.wikipedia.org/wiki/MACRO-11

.TITLE  HELLO WORLD
.MCALL  .TTYOUT,.EXIT
HELLO:: MOV #MSG,R1  ;STARTING ADDRESS OF STRING
1$: MOVB(R1)+,R0 ;FETCH NEXT CHARACTER
BEQ DONE ;IF ZERO, EXIT LOOP
.TTYOUT  ;OTHERWISE PRINT IT
BR  1$   ;REPEAT LOOP
DONE:   .EXIT

MSG:.ASCIZ /Hello, world!/
.ENDHELLO

The double colon makes an external label, single colon an
ordinary non-extern label, and the 1$: is a local label,
with scope between the HELLO:: and DONE:.

The scope is delimited by ordinary labels, .PSECT, .CSECT, or .ASECT
directives, but not equate symbol assignment.

More convenient than thinking up dumb names for things that don't
really need a name.

http://bitsavers.trailing-edge.com/pdf/dec/pdp11/rsx11/RSX11M_V2/DEC-11-OIMRA-A-D_MACRO_75.pdf

-- glen


360/20 instruction macros

2015-05-26 Thread glen herrmannsfeldt
OK, here are the macros as I use them, with the test for host machine removed.

They come from the HRTPB360 program that is part of HASP.

Note that OS/360 assemblers support BAS and BASR, possibly for the 360/67.

-- glen

*** V0082000
 TITLE 'H A S P / R T P  *MACRO DEFINITIONS*(MODEL 20 INSTS.)'  V0083000
*   V0084000
*   V0115000
*   CIO*  CONTROL I/O   V0116000
*   V0117000
 MACRO  V0118000
NAMECIO   A,BV0119000
 GBLA  MACHINE V012
NAMENULL   V0121000
 DCX'9B'V0123000
 DCAL1(B)  V0124000
 DCS(A)V0125000
 AGO   .END V0126000
 EJECT  V0133000
*   V0134000
*DIALS READ MOD 20 DIALSV0135000
*  DATA 1,2 IN LOC 252  V0136000
*  ADDRESS 1,2,3,4 IN 253-254 DEC   V0137000
 MACRO  V0138000
NAMEDIALS NULLV0139000
NAMEDS0H   V014
 DCX'83000300' �   READ DIALS INTO CORE 
V01410
00
 MEND   V0142000
 SPACE 4V0143000
*   V0144000
*   HPR*  HALT AND PROCEED  V0145000
*   V0146000
*   V0147000
 MACRO  V0148000
NAMEHPR   NUM V0149000
 GBLA  MACHINE V015
NAMENULL   V0151000
 DCX'9900',S(NUM)  V0153000
.END MEND   V0156000
 SPACE 4V0157000
*   V0158000
*   TIOB   *  TEST I/O AND BRANCH   V0159000
*   V016
*   V0161000
 MACRO  V0162000
NAMETIOB  A,BV0163000
 GBLA  MACHINE V0164000
NAMENULL   V0165000
 DCX'9A'V0167000
 DCAL1(B)  V0168000
 AIF   ('A' EQ '*').A2 V0169000
 DCS(A)V017
 AGO   .END V0171000
.A2  ANOP   V0172000
 DCS(*-2)   V0173000
.END MEND   V0177000
 EJECT  V0178000
 SPACE 16   V0179000
*   
V018*   XIO*  TRANSFER I/O  
V0181000
*   V0182000
*   V0183000
 MACRO  V0184000
NAME

BASR

2015-05-25 Thread glen herrmannsfeldt
(someone wrote)

   I may be wrong but I have the Impression hat the 360/20 version of 
BAS/BASR (that machine's equivalent to BAL/BALR had a different op 
code from the current BAS/BASR.

I have assembled BAS and BASR with the Tachyon assemmbler with the
right X'4D' and X'0D' opcodes.  I believe these are from the 360/67.

There are some other diagnoses.

I believe one jumps to a specified address in microcode, but the
useful addresses aren't well documented.

More are for the later serial numbers, with microcode in core.

-- glen


unusual instructions

2015-05-21 Thread glen herrmannsfeldt
  The OP said he was working with code for a model 20.
   That was only barely a true S360 and had a few 
   instructions peculiar to it.

Yes. XIO is the I/O instruction that reads or writes.
Like other 360's, I/O is asynchronous. You have to test
(with TIOB) to see if it is done yet.

With 8K core, half the core is available without a base register.
As I understand it, many were only 4K. 

It does have some fairly complex instructions, such as DP, ED, and TR,
and leaves out some simple ones like L and LR.

Registers are 16 bits, so LH, AH, SH, CH, and STH are there.
AR and SR, but not most of the other RR instructions.
PACK, UNPK, MVO, ZAP, AP, SP, CP, MP, DP so full decimal arithmetic.
MVI, MVN, MVZ, CLI, MVC, CLC, NI, OI, ED, BR, B, BASR, BAS.

and then the model 20 specific: XIO, TIOB, HPR, SPSW.

-- glen


360/20 instructions

2015-05-21 Thread glen herrmannsfeldt
The detail on the instructions are in:

httt://www.bitsavers.org/pdf/ibm/360/funcChar/A26-5847-3_360-20_funChar_Apr67.pdf

The HRTBP360 program that IBM still distributes, I am told, with HASP,
uses macros for the 360/20 specific instructions.  (It was written
to assembler with OS/360 or OS/VS2 assemblers.)

The macros seem to still work with new assemblers.

-- glen


absolute addressing, continued

2015-05-20 Thread glen herrmannsfeldt
Thanks all for the help with this one.  I have known for a long
time that the assembler could generate absolute addresses, but
never asked why.  For those still following, here is the program
that reads the object deck:

 BASR  11,0-2:  0DB0
 XIO   78(19,11),80 0:  D012B04E0050
 BCR   5,11 6:  075B
 TIOB  8(11),16 8:  9A10B008
 TIOB  68(11),1 C:  9A11B044
 CLI   78(11),210:  9502B04E
 BNER  11  14:  077B
 LH12,84(11)   16:  48C0B054
 CLI   80(11),X'D5'1A:  95D5B050
 BER   15  1E:  078F
 CLI   80(11),X'E7'20:  95E7B050
 BNER  11  24:  077B
 LH15,88(11)   26:  48F0B058
 AH15,74(11)   2A:  4AF0B04A
 STH   15,50(11)   2E:  40F0B032
 MVC   0(28,12),94(11) 32:  D21BC000B05E
 BASR  15,11   38:  0DFB
 XIO   76(21,11),1 3A:  D014B04C0001
 BCR   5,1540:  075F
 BR12  42:  07FC
 HPR   2   44:  9902
 BR11  48:  07FB
 DCX'D1FF' 4A:  D1FF

which runs on a real 360/20, though not, so far, with a real
card reader.  (Instead, I have an FPGA based virtual card reader.)

I didn't write this one, it seems that it is related to HASP,
and a program to make a 360/20, or larger 360, into an RJE station.
(There is a different loader for other 360's, which I didn't 
disassemble.

For those following such things, the PSW in the 360/20 does 
have an A bit, and I have run some decimal instructions with
it set.

-- glen


absolute addressing

2015-05-18 Thread glen herrmannsfeldt
(snip, I wrote)
I wonder if USING 0,0 and USING 4096,1 should work correctly.

What are you trying to accomplish? There are three forms of USING, 
and all three require an address as the first operand. This is given as 
a label to tell the assembler that the address of that label is in the 
register specified. The assembler then computes the displacements 
for other operands based upon the value that you have told the 
assembler that you have placed in the register.

I have tried it with START 1000, and START 5000, respectively,

What do you hope to accomplish with that?

This is my first time trying to assemble for absolute addresses.

Do you mean that you are not using labels? If so, why?

What do you mean by absolute addresses? Do you intend that your 
program will be loaded into a specific location in memory, determined 
at assembly time? 

Yes, it will be loaded into the address specified at assembly.

If I say:

 START 1000

the assembler generates addresses starting from 1000, and the program
is loaded into those addresses.

In z/Architecture, and dating back to System/370, there 
are three kinds of addresses:

Dating back to S/360, actually...

o Virtual addresses. These are the addresses that programs normally 
  work with.
o Real addresses. These are the result of Dynamic Address 
  Translation of a virtual address.
o Absolute addresses. These are the result of applying the Prefix 
  register to a real address.

Well, real addresses also work with DAT off, or on machines that don't
have DAT. 

For actual use with OS/360, this likely only happens in an FLIH, 
(First Level Interrupt Handler), and the routine that first gets
control on IPL, but the assemblers have to be able to do that.

Someone from Tachyonsoft has told me the answer, though I am still
not sure that I understand it.  It goes like:

XXX START 1000
USING XXX,0

In the usual case, the displacement is computed by subtracting
the desired offset from the offset in the base register, 1000
in this case. But it seems that the assembler instead subtracts
zero.

I haven't yet tried:

USING XXX,0,1

to see if it subtracts 4096, and generates displacements
from register 1.

-- glen


absolute addressing example doesn't work

2015-05-15 Thread glen herrmannsfeldt
In the HLASM release 5 manual, there is an example:

  If a register is specified with base address zero, the 
   assembler will use it in preference to the default use 
   of register zero. For example:

   | USING 3,0
   | LA 7,5
   | generates the instruction X'41703005'; in the absence of 
   | the USING statement, the generated instruction would 
   | be X'4175'.

I suppose that works if it said  USING 0,3 but what I
really want to know how to do is to generate real absolute
addresses.  

I now have an example from Tachyonsoft that looks like:

MYCODE   START  1000
 USING MYCODE,0
LOOP MP X,Y
 DP X,Z
 ZAP X,X(13)
 B LOOP
XDC PL16'8000'
YDC PL3'8001'
ZDC PL3'8000'
 END  LOOP

which seems to work.  It does generate offsets from zero, 
instead of from 1000 that it looks like it would.
I still don't know why it doesn't subtract 1000 from the
displacements.

-- glen


USING 0,0

2015-05-15 Thread glen herrmannsfeldt
I wonder if USING 0,0 and USING 4096,1 should work correctly.

I have tried it with START 1000, and START 5000, respectively,
such that addresses are in the appropriate range, but, using
the Tachyon assembler, get addressability errors.

Or maybe there is an assembler option to allow this that 
I don't see.

This is my first time trying to assemble for absolute addresses.

-- glen


Intel Virtualization

2015-03-25 Thread glen herrmannsfeldt
 As for the ISA, Intel seems to be very ad hoc compared to the z
 architecture. Especially in the virtualization arena. Basically, 
 the z has a _single_ virtualization instruction: SIE. 
 Intel has I don't know how many different versions of different 
 instructions to let hypervisors run at all. I don't
 know how efficient vitualization actually is on Intel. 
 But it wouldn't surprise me if it were a pig.

As far as I know, the biggest advantage z/ has over Intel 
(and many others) is the wait state. 

It is sometimes difficult for virtualization to figure out when
the guest isn't doing anything.  Most other systems use a null
process with a small loop, while waiting for an interrupt.
(But if you know you are running virtual, there might be some
way around it.)

I beleive that the wait state came from the days of usage meters,
when the meter would stop while the processor was waiting.  If not
for rentals of S/360, it might not have had the wait state.

-- glen

 


Re: CE key

2015-03-12 Thread glen herrmannsfeldt
Here are pictures of the key switch:

https://commons.wikimedia.org/wiki/File:Customer_Engineer_Key_Switch_for_IBM_S-360_computer,_view_1.JPG

https://commons.wikimedia.org/wiki/File:Customer_Engineer_Key_Switch_for_IBM_S-360_computer,_view_2.JPG


new instructions (was: LZRG ...)

2015-03-11 Thread glen herrmannsfeldt
(snip, someone wrote)
  And POPCNT is another one. Why do I need to 
 know the number of 1 bits in each individual byte in a GPR? 
  
On 2015-03-11, at 08:49, John McKown wrote:
 Because CDC had it first?  I suspect that it became a built-in
 function in Pascal, CARD(), because Pascal was developed on a
 CDC which had the hardware.  

As I understand it, it is used in cryptography. 

Also, it can be done fast in hardware and isn't that hard
if you want to do it.

 Is POPCNT an inexpensive extension of the Wallace Tree?

The ones I know of use a carry save adder tree.
I think that is related to the Wallace tree, but I forget the
exact way they work.

 And I suspect FORTRAN's transfer-of-sign, SIGNF() happened 
 because it was a hardware instruction on the 704.

I suppose. But now that IEEE cares about negative zero, it
has an extra use. 

Even without the special instruction, it is easy to do with 
bitwise AND and OR and most hardware.  (Though you have to be
able to get floating point values in a place where you can do
bitwise operations.)

-- glen


CE key

2015-03-11 Thread glen herrmannsfeldt
I wonder if anyone knows where to find CE keys for S/360 CPUs.

thanks,

-- glen


Re: CE key

2015-03-11 Thread glen herrmannsfeldt
 If you're talking about the CE key that switched metering from
 customer to IBM, I have no idea. Those were a real pin-tumbler lock;
 not just a simple latch. They may even have been unique to each
 machine, though I think it would've been impractical to have each CE
 carry a jangling bunch of them around. I've never seen one on eBay,
 but then there's precious little S/360 stuff on there of any kind.

Yes, that one.

I know that DEC used the same key for all the CPUs, and was
guessing that IBM did, too.

Also, I don't know if it would match the blank that ordinary
locksmiths would sell.

thanks,

-- glen


Decimal intructions, was: Redesigning POps.

2014-11-14 Thread glen herrmannsfeldt
Gary wrote:

 I have heard that only one machine was ever delivered without the 
 decimal set, but it may have just been rumour.

All the 360/91's were delivered without the decimal instructions.
The OS emulates them when the illegal instruction exception is
generated. 

But maybe you meant only on machines where decimal was in option.

The 360/20 has the decimal instructions except for SRP, but not most
of the binary instructions. (It has MP and DP but not M, MR, D, or DR.)

Without having ever looked at it, I presume that RPG does mostly
decimal arithmetic, other than address calculations.

-- glen


Reference summary for 360/20

2014-11-14 Thread glen herrmannsfeldt
The mention of instruction sets and green cards reminds me,
does anyone have a (scan of) a 360/20 Reference Summary?

Some places indicate that it might be yellow or red.

-- glen


Trial execution

2014-05-21 Thread glen herrmannsfeldt
Someone wrote:

  The problem with TRT is it validates the whole TRT table before
   it starts to do the TRT.

As far as I know, TR, but not TRT, can do a trial execution.

First, it is only needed if the translate table starts within 256
bytes before a page boundary.

But it is needed for TR, as TR modifies the first argument before it
knows the extent (on both sides of the boundary) of the second
argument. TRT does not modify its argument, and so doesn't have that
problem.

It might be also for ED and EDMK, though I have never used either.

The other SS instructions know the extent of both operands before
any data is modified, and can generate the page fault interrupt
at that time.

-- glen


architecture book

2014-02-17 Thread glen herrmannsfeldt
My favorite book describing the variety of computer architectures
is the Blaauw  Brooks book. Many of the examples have a little
more detail for S/360 and S/370, but they have all of the
important details for many other older and newer systems.

Otherwise, the previously mentioned book seems to be available
in the paperback international version for a lower price, and
used in the hardback not so much more.

-- glen


Re: OT: SI units and precision

2014-01-06 Thread glen herrmannsfeldt
Someone wrote:

 At least that explains I don't need to worry that km is
 not suddenly 1024m as soon as I carry a storage device ;-)

Reminds me that I used to wonder if IBM sold computers
in units of $1024, that is, k$.

I presume everyone here knows that the serial numbers on S/370
CPUs are in hex.

-- glen


Re: Why is division by zero permitted?

2013-10-23 Thread glen herrmannsfeldt
From C28-6514-5 on bitsavers, on page 16:

  Division by zero is permitted and yields a zero result.

After that, (and presumably also earlier) it has to stay that
way as code (macros) might depend on that.

There is no reason given.

-- glen


Re: handling a remainder form a DP

2013-07-18 Thread glen herrmannsfeldt
 My result from a DP in dividing 1300 by 3 is 00 00 00 43 3C 00 1C
 but on a calculator it is displayed as 433.3 - which is what
 I want to display in a field on a screen. How do I turn that
 remainder of 1C into the decimal value ?

You should have enough to do it as scaled decimal.

Consider the dividend as 1300., divide by 3 and you
get 433. ( and remainder 0.0001)

Multiply the dividend by 1 (probably with SRP) then do the
divide, and the quotient will have four digits after the decimal
point. Print at appropriately.

If you don't have enough digits to do that, you can convert the
already computed remainder by muliplying it by 1 (SRP)
and then dividing it by the original divisor, 3, to
get  remainder 1. That is, considering the shift, 0.
remainder 0.0001.

-- glen


Re: Instruction Lists/Counts.

2013-02-15 Thread glen herrmannsfeldt
Instructions are hard to count, though instruction count isn't a
very good way to determine CISCness.

RISC tends to have a small number of instruction lengths, often 1.
S/360 through z/ have three lengths. Not too CISCy, but not RISC.
(VAX might have 14 or so, from one byte on up.)

RISC tends to minimize address modes. Some have been added lately,
but the largest fraction of instructions executed should still be
RR or RX. Not too CISCy, but not so RISCy, either.

VAX has many address modes, 21 on the list that I have, but 14
of those also have an indexed mode, so it should be 35.
And there can be more than one such address per instruction.
(Many operands are register only, but I am pretty sure that there
are some where two operands can have one of those 35.)

Many RISC systems try to execute every instruction in one cycle.
That brought things like MULTIPLY_STEP, an instruction that did
part of a multiply, but that had to be executed many times
to do an actual multiply. Most try to avoid this now.

There are some pretty complicated instructions even from S/360,
and many complicated ones added later, which are pretty CISCy.

Still, in terms of instruction length and address modes, not
so bad.

Since S/360 through z/ use different opcodes for different
addressing modes of the same instruction, do you count those
as separate instructions, or just one? (Compare to VAX,
where there is an opcode byte and address mode byte.)

-- glen


Re: OPSYN self execution

2013-01-18 Thread glen herrmannsfeldt
Jonathan Scott wrote:

 If you want to modify DC, you need to define an opcode which
 refers to the original DC first so that you can invoke it from
 within the macro.

 DC_  OPSYN DC  Set up alias for original DC
 DC   OPSYN MYDCRedirect DC to my macro

 Then within the macro you can use
  DC_   whatever   Issue real DC

But John Ehrman's method is neater, as it doesn't require a
special OPSYN from the outside.

Some one could directly call MYDC, or use OPSYN, either
way it would work.

I have never used OPSYN, but I have written postscript programs
that redefined the \def operator.

Now, what happens if OPSYN is OPSYNed?

-- glen


more than one base register

2012-06-04 Thread glen herrmannsfeldt
Someone wrote:

 MYCSECT  CSECT
  USING *,R15
  B BYID
 ID   DCC'module-name'
 BASESDCA(MYCSECT)
  DCA(MYCSECT+4096)
  DCA(MYCSECT+2*4096)
  DCA(MYCSECT+3*4096)
 BYID DS0H
  LMR9,R12,BASES
  DROP R15
  USING MYCSECT,R9,R10,R11,R12

This looks more like compiler generated code than what I
would expect from a person. Then again, my start on learning
assembler was reading the LIST output from the compilers.

When I saw the 4095 in the subject, I was expecting the old:

L 12,4095(15)
L 11,4095(12)
L 10,4095(11)
USING MYCSECT,15
USING MYCSECT+4095,12
USING MYCSECT+2*4095,11
USING MYCSECT+3*4095,10

The LM form seems to waste fewer bytes loading the base registers
(including the A constants), especially if one already has the
branch around the csect name.

But, why the DS 0H instead of putting the label on the LM?

-- glen


DS 0H

2012-06-04 Thread glen herrmannsfeldt
(snip, I wrote)
 But, why the DS 0H instead of putting the label on the LM?

 I do the same thing for labels to code. Why? Hum, I guess
 from reading the HASP code long ago. Also, it makes it
 easier to insert a new instruction at that logical point in
 the program without remembering to remove the label from the
 old instruction and move it to the new one.

That I don't disagree with, but what is the probability of wanted
to add new code between the B and the LM? I suppose one still
has over 4000 bytes of code (not counting data references) before
one needs the next base register, but, really, what else would
you want to do there?

Now that I write that, where is the STM 14,12,12(13)?
Still, that isn't the kind of change I would plan ahead for.

At the time, I was considering differences between compiler
generated and human generated code. I suppose that one isn't
a very good test, though.

 In addition, if you use SUPERC to compare the two sources
 (before  after), then the old instruction does not show
 up an a delete and add. Only the new inst ruction shows up
 as an add. Remember the days of IEBUPDTE to update source.
 Fewer updated cards means fewer mistakes.

Oh, yes, in the general case I agree. It just seemed unneeded
in this specific case.

-- glen


bit masking

2012-05-28 Thread glen herrmannsfeldt
 I am working with some IPv6 addresses that are 128 bits long.
 The input to the program is an ip name or address and the
 number of high bits that I need to use for a compare against
 another ip address.

 So, I want to create run time routine to build the a
 16 byte 'and' bit field based on the input number of bits.
 (I will then 'and' both addresses and then use a simple CLC.)

There is no double 64 bit (that is, 128 bit) shift instruction
as far as I know.

Most obvious is to store the bits in some number of bytes,
halfwords, words, or doublewords. Then, based on the shift
amount, fill some with all ones, and use a shift instruction
(or smaller table) for the boundary case. I would probably
choose words. Using shift and mask, split the shift amount
into 32's and a remainder (or use Divide).

For bytes in memory, EX an MVC, or a loop of MVI, to fill the
high bytes. Use a table of bytes to IC and STC the boundary byte.

-- glen


Re: MNEMONICS

2012-02-13 Thread glen herrmannsfeldt
(someone wrote)

 IHMO, the mnemonic for BCT was not well-chosen.
 Better might have been DBZ
 for Decrement and Branch on Zero.

That would be Decrement and Branch on Not Zero, DBNZ,
and also DBNZR. Sounds too much like DEC to me.(*)

I believe none of the S/360 instructions are more than four
letters long, though.

As for the below case of BALR, clearly, there needed to
be yet another instruction :-

(*) I was doing S/370 assembly programming for a few years
before I first programmed a DEC system, a PDP-10 running TOPS-10.

The DEC mnemonics are a little different, but the decrement
and skip/jump are usual.

Note that on the PDP-10, the JUMP instruction doesn't jump,
the JUMPA instruction actually does, but usually JRST is used
instead.

-- glen


Underscore character

2012-01-12 Thread glen herrmannsfeldt
(snip, someone wrote)
 You've sometimes admonished me for taking the synchronic view
 rather than the diachronic.  But here, you're being narrowly
 synchronic.  In the Bad Old Days of Yore, mechanical serial
 printers could be commanded to underscore with the sequence
 underscorebackspacecharacter-to-be-underscored.  In this
 diachronic perspective, underscore is not a misnomer, merely
 antiquated.

No, you write a second line with a '+' as carriage control character.

This is even so popular as to be a special case for the 3800, which
otherwise does not allow writing two characters on one print column.

Presumably it builds a record in a buffer, allowing overprint with
different fonts, and a special bit to indicate underlining.

With ink and ribbon printers, you can get darker print (bold-like)
by overprinting the same characters using '+', though I believe
that the 3800 also doesn't do that.

-- glen


Re: FORTRAN II functions

2012-01-08 Thread glen herrmannsfeldt
(snip, someone wrote)

 o IBM hexadecimal floating-point, HFP,

 o ANSI binary floating-point, BFP, and

 o ANSI decimal floating-point, DFP.

 Of these the first two, HFP and BFP, make zeros positive; but the
 third, DFP, supports both positive and negative zeros.

The change to the Fortran standard comes, I believe, from support
for IEEE binary floating point, which is what went into IBM's BFP.

Among others, the reciprocal of -Infinity is supposed to be negative zero.

DFP, from the new IEEE standard, should also include all the negative
zero properties of the old standard.

(snip, someone else wrote)
 What is x'8000 ' interpreted as HFP?

I do remember that LNER and LCER generate negative zero, but
I am not sure about some other cases.  How about:

  X=-1e73
  Y=1e-10/X

with exponent underflow mask bit off?

In any case, in all three (HFP, BFP, and DFP) negative zero and
positive zero compare as equal. It is only with tests like SIGN(X)
in Fortran that you can detect negative zero.

Many years ago, I learned that the CALL/OS Fortran compiler
(or, more likely, library) would print +0.0 if given a negative zero.
No sign was printed for positive zero.

-- glen


Fortran II functions

2012-01-07 Thread glen herrmannsfeldt
 Finally, ISTR, but can find no references, that FORTRAN II had
 a two argument SGNF(X,Y) defined as the magnitude of X with the
 sign of Y.  A plausible motivation is this was a single machine
 instruction on the IBM 70x series -- doubleword shift with a
 count of zero.

The SIGN function is still in Fortran, along with the more specific
functions ISIGN and DSIGN (for integer and double precision).

(Fortran II function names had to end in F, a restriction removed
for Fortran IV and the ANSI Fortran 66 version.)

(Newer standards include the effect when X is zero on machines
supporting a negative floating point zero.)

The arithmetic IF is still in Fortran, though its use is discourage
and it is, I believe, on the obsolescence list.

-- glen


calling convention

2011-10-14 Thread glen herrmannsfeldt
(someone wrote)
 My understanding is that the C standard calls for all parameters
 to be passed by value.  My experience is that IBM's C usually
 passes parameters by reference except that if a parameter is a
 pointer it gets passed by value.  Go figger.

That is most consistent with the way it was traditionally done.

The requirement is for as if to work.  It should be possible to
pass the addresses and the callee makes a local copy, or pass
addresses of copies.

The OS/360 Fortran compilers (G and H) make local copies of scalar
variables, and then copy them back before return.  (Usually
described as call by value result.)  That is legal Fortran.

For a Fortran call, local variables will have compile time
(relocatable) address constants, but dummy arguments arrays
will use the address passed in with the call.

PL/I passes the address of a temporary variable for expression
arguments, or arguments known to have different attributes.

To be most consistent with the OS/360 calling conventions,
as a series of A-type address constants, the last with the high
bit set, one would either pass addresses of copies, or expect
the called routine to make copies.  That would allow for calls
between C and other languages.

-- glen


Re: EDIT instruction

2011-09-02 Thread glen herrmannsfeldt
(previously I wrote)
 The book Computer Architecture: Concepts and Evolution by
 Blaauw and Brooks has many descriptions on how instructions got
 to be the way they did.

 (Blaauw was the main designer of S/360...

 I thought that Gene Amdahl was the principle architect of 360.
 A search to check my facts seems to reveal that Amdahl, Blaauw
 and Brooks led the design team.

I don't know the actual hierarchy, but yes it was those three.

My feeling was that Blaauw made the higher level decisions
(should we have an EDIT instruction) and Amdahl the lower
level decisions (can we really implement this, how many
digits can it do, etc.)   Both are pretty important.
Brooks, at least as described in Mythical Man Month,
led the OS/360 project.

In the above mentioned book Blaauw takes the blames for what
he considers his mistake in adding the EDIT instruction.

As to programming, microcode is now usually considered
firmware, though the term is likely more recent than S/360.
The microcode of most S/360 models was actually hardware,
physical capacitors or transformers.   The floppy disk
was origially meant to load the microcode store in S/370
models, replacing the hardware microcode storage.

More recently, hardware is designed in verilog or VHDL,
hardware descriptor languages.  Logic gates can be written
out as easily as software.  As the cost of masks has increased,
hardware is more often done through programmable logic where
bits activate gates on a chip.  Even more, there are system
that allow for dynamic reconfiguration, the hardware equivalent
of self-modifying code!

-- glen


Instruction selection

2011-08-30 Thread glen herrmannsfeldt
Someone wrote:

 Should we have machine instructions to compute a polynome of grade n?
 I don't think so (but there were machines in the 60s which did just that,
 and - in that period - they were faster by using such instructions).

VAX had polynomial evaluation in the 1980's, and it was well known
to be slower than doing it with separate instructions.  For that
reason, it was likely rarely used, even if it got faster in
later versions.

The VAX instruction for doing subscript calculations, including
bounds checking, was also known to be slower than doing the same
thing without the special instruction.

RISC or CISC, if some operation is done often enough it makes
sense to have a special instruction.  As Blaauw did much of the
design of the S/360 architecture, in many cases he is criticizing
himself.  It would be rare for ED or EDMK to be used enough in
a program to make a significant contribution to the CPU usage.
(Most likely even in 1963.)

Decisions that make sense one year might not the next.
The S/360 instructions have done well over the years.

-- glen


Re: CDS and alignment question

2010-08-17 Thread glen herrmannsfeldt
It is the address in memory that matters.

This reminds me of programs with two base registers, using LA
to set the registers such that the offset of the second is 4095
from the first.  All instruction addresses (an branch instructions)
will then have an odd offset, legal but it looks funny.

On the other hand, consider all the wasted bits in even offset
branch instructions.

-- glen