mirror of
https://github.com/moshix/mvs.git
synced 2026-01-11 23:43:00 +00:00
15850 lines
465 KiB
Plaintext
15850 lines
465 KiB
Plaintext
//NLTLIB JOB 'S322-0C4','WFJM',
|
|
// USER=HERC01,PASSWORD=CUL8TR,
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CREDS EXEC PGM=IEBUPDTE,PARM=NEW
|
|
//SYSPRINT DD SYSOUT=A
|
|
//SYSUT2 DD DSNAME=HERC01.LTLIB,
|
|
// UNIT=3350,VOL=SER=PUB000,
|
|
// SPACE=(80,(2000,200,15)),DISP=(NEW,CATLG),
|
|
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=3120)
|
|
//SYSIN DD DATA,DLM='@@'
|
|
./ ADD NAME=$$$INDEX,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//********************************************************************
|
|
//*
|
|
//* Name: HERC01.LTLIB($$$INDEX)
|
|
//*
|
|
//* Desc: Short index of PDS with MVS 3.8j language test jobs
|
|
//*
|
|
//* For full information consult GitHub project wfjm/mvs38j-langtest
|
|
//* https://github.com/wfjm/mvs38j-langtest/blob/master/README.md
|
|
//*
|
|
//* The index simply gives the relation between the 7 character
|
|
//* PDS member names and the jcl file names of the project.
|
|
//* Member names as well as file name are composed of
|
|
//* Case ID - test case identifier (hewo,sine,....)
|
|
//* Compiler ID - compiler identifier (a60,asm,....)
|
|
//* Job type - t --> test jobs
|
|
//* f --> benchmark jobs
|
|
//* p --> print benchmark jobs (for soep/soeq)
|
|
//*
|
|
//********************************************************************
|
|
Membername Short description x
|
|
---------- ------------------------------------------------------------
|
|
HEWO --- section --- The classical 'Hello Word'
|
|
HEWOA60 hewo_a60.jcl
|
|
HEWOASM hewo_asm.jcl
|
|
HEWOCOB hewo_cob.jcl
|
|
HEWOFOG hewo_forg.jcl
|
|
HEWOFOH hewo_forh.jcl
|
|
HEWOFOW hewo_forw.jcl
|
|
HEWOGCC hewo_gcc.jcl
|
|
HEWOJCC hewo_jcc.jcl
|
|
HEWOPAS hewo_pas.jcl
|
|
HEWOPLI hewo_pli.jcl
|
|
HEWOSIM hewo_sim.jcl
|
|
SINE --- section --- Line printer plot of sine and cosine
|
|
SINEA60 sine_a60.jcl
|
|
SINEFOG sine_forg.jcl
|
|
SINEFOH sine_forh.jcl
|
|
SINEFOW sine_forw.jcl
|
|
SINEGCC sine_gcc.jcl
|
|
SINEJCC sine_jcc.jcl
|
|
SINEPAS sine_pas.jcl
|
|
SINEPLI sine_pli.jcl
|
|
SINESIM sine_sim.jcl
|
|
SOEP --- section --- Sieve of Eratosthenes prime search (byte)
|
|
SOEPA60 soep_a60_f.jcl
|
|
SOEPA60 soep_a60_p.jcl
|
|
SOEPA60 soep_a60_t.jcl
|
|
SOEPASM soep_asm_f.jcl
|
|
SOEPASM soep_asm_p.jcl
|
|
SOEPASM soep_asm_t.jcl
|
|
SOEPGCC soep_gcc_f.jcl
|
|
SOEPGCC soep_gcc_p.jcl
|
|
SOEPGCC soep_gcc_t.jcl
|
|
SOEPJCC soep_jcc_f.jcl
|
|
SOEPJCC soep_jcc_p.jcl
|
|
SOEPJCC soep_jcc_t.jcl
|
|
SOEPFOG soep_forg_f.jcl
|
|
SOEPFOG soep_forg_p.jcl
|
|
SOEPFOG soep_forg_t.jcl
|
|
SOEPFOH soep_forh_f.jcl
|
|
SOEPFOH soep_forh_p.jcl
|
|
SOEPFOH soep_forh_t.jcl
|
|
SOEPFOW soep_forw_f.jcl
|
|
SOEPFOW soep_forw_p.jcl
|
|
SOEPFOW soep_forw_t.jcl
|
|
SOEPPAS soep_pas_f.jcl
|
|
SOEPPAS soep_pas_p.jcl
|
|
SOEPPAS soep_pas_t.jcl
|
|
SOEPPLI soep_pli_f.jcl
|
|
SOEPPLI soep_pli_p.jcl
|
|
SOEPPLI soep_pli_t.jcl
|
|
SOEPSIM soep_sim_f.jcl
|
|
SOEPSIM soep_sim_p.jcl
|
|
SOEPSIM soep_sim_t.jcl
|
|
SOEQ --- section --- Sieve of Eratosthenes prime search (bit)
|
|
SOEQASM soeq_asm_f.jcl
|
|
SOEQASM soeq_asm_p.jcl
|
|
SOEQASM soeq_asm_t.jcl
|
|
SOEQGCC soeq_gcc_f.jcl
|
|
SOEQGCC soeq_gcc_p.jcl
|
|
SOEQGCC soeq_gcc_t.jcl
|
|
SOEQJCC soeq_jcc_f.jcl
|
|
SOEQJCC soeq_jcc_p.jcl
|
|
SOEQJCC soeq_jcc_t.jcl
|
|
SOEQPAS soeq_pas_f.jcl
|
|
SOEQPAS soeq_pas_p.jcl
|
|
SOEQPAS soeq_pas_t.jcl
|
|
SOEQPLI soeq_pli_f.jcl
|
|
SOEQPLI soeq_pli_p.jcl
|
|
SOEQPLI soeq_pli_t.jcl
|
|
TOWH --- section --- Tower of Hanoi solver
|
|
TOWHA60 towh_a60_f.jcl
|
|
TOWHA60 towh_a60_t.jcl
|
|
TOWHASM towh_asm_f.jcl
|
|
TOWHASM towh_asm_t.jcl
|
|
TOWHGCC towh_gcc_f.jcl
|
|
TOWHGCC towh_gcc_t.jcl
|
|
TOWHJCC towh_jcc_f.jcl
|
|
TOWHJCC towh_jcc_t.jcl
|
|
TOWHFOG towh_forg_f.jcl
|
|
TOWHFOG towh_forg_t.jcl
|
|
TOWHFOH towh_forh_f.jcl
|
|
TOWHFOH towh_forh_t.jcl
|
|
TOWHFOW towh_forw_f.jcl
|
|
TOWHFOW towh_forw_t.jcl
|
|
TOWHPAS towh_pas_f.jcl
|
|
TOWHPAS towh_pas_t.jcl
|
|
TOWHPLI towh_pli_f.jcl
|
|
TOWHPLI towh_pli_t.jcl
|
|
TOWHSIM towh_sim_f.jcl
|
|
TOWHSIM towh_sim_t.jcl
|
|
MCPI --- section --- Monte Carlo estimate of pi
|
|
MCPIA60 mcpi_a60_f.jcl
|
|
MCPIA60 mcpi_a60_t.jcl
|
|
MCPIASM mcpi_asm_f.jcl
|
|
MCPIASM mcpi_asm_t.jcl
|
|
MCPIGCC mcpi_gcc_f.jcl
|
|
MCPIGCC mcpi_gcc_t.jcl
|
|
MCPIJCC mcpi_jcc_f.jcl
|
|
MCPIJCC mcpi_jcc_t.jcl
|
|
MCPIFOG mcpi_forg_f.jcl
|
|
MCPIFOG mcpi_forg_t.jcl
|
|
MCPIFOH mcpi_forh_f.jcl
|
|
MCPIFOH mcpi_forh_t.jcl
|
|
MCPIFOW mcpi_forw_f.jcl
|
|
MCPIFOW mcpi_forw_t.jcl
|
|
MCPIPAS mcpi_pas_f.jcl
|
|
MCPIPAS mcpi_pas_t.jcl
|
|
MCPIPLI mcpi_pli_f.jcl
|
|
MCPIPLI mcpi_pli_t.jcl
|
|
MCPISIM mcpi_sim_f.jcl
|
|
MCPISIM mcpi_sim_t.jcl
|
|
./ ADD NAME=HEWOA60,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
OUTSTRING (1,'('Hello World !')');
|
|
'END'
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOASM,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=128K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
PRINT NOGEN don't show macro expansions
|
|
HEWO START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING HEWO,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BNE ABND8 abort if open failed
|
|
PUT SYSPRINT,MSG write the message
|
|
CLOSE SYSPRINT close SYSPRINT
|
|
*
|
|
L R13,SAVE+4 get old save area back
|
|
RETURN (14,12),RC=0 return to OS
|
|
*
|
|
ABND8 ABEND 8 bail out with abend U008
|
|
*
|
|
* File and work area definitions
|
|
*
|
|
SAVE DS 18F local save area
|
|
MSG DC CL133' Hello World !'
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=1330
|
|
YREGS ,
|
|
END HEWO define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOCOB,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#COB JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=2048K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC COBUCLG,
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//COB.SYSIN DD *
|
|
000100 IDENTIFICATION DIVISION.
|
|
000200 PROGRAM-ID. 'HEWO'.
|
|
000300 ENVIRONMENT DIVISION.
|
|
001000 DATA DIVISION.
|
|
100000 PROCEDURE DIVISION.
|
|
100100 00-MAIN.
|
|
100500 DISPLAY 'Hello World !'.
|
|
100600 STOP RUN.
|
|
/*
|
|
//GO.SYSIN DD *
|
|
//GO.SYSOUT DD SYSOUT=*
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOFOG,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM HEWO
|
|
WRITE(6,9000)
|
|
STOP
|
|
C
|
|
9000 FORMAT(1X,'Hello World !')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOFOH,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM HEWO
|
|
WRITE(6,9000)
|
|
STOP
|
|
C
|
|
9000 FORMAT(1X,'Hello World !')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOFOW,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB HEWO#FOW,T=(1,0),P=100,CHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM HEWO
|
|
WRITE(6,9000)
|
|
STOP
|
|
C
|
|
9000 FORMAT(1X,'Hello World !')
|
|
C
|
|
END
|
|
$ENTRY
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOGCC,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
#include <stdio.h>
|
|
|
|
int main ()
|
|
{
|
|
printf ("Hello World !\n");
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOJCC,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
#include <stdio.h>
|
|
|
|
int main ()
|
|
{
|
|
printf ("Hello World !\n");
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOPAS,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=1024K,
|
|
// OPT='M+',
|
|
// GOPARM='/STACK=512k'
|
|
//COMPILE.SYSIN DD *
|
|
program hewo(input,output);
|
|
begin
|
|
writeln(' ','Hello World !');
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOPLI,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
HELLO: PROC OPTIONS(MAIN) REORDER;
|
|
PUT SKIP LIST('Hello World !');
|
|
END HELLO;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=HEWOSIM,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//HEWO#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
BEGIN
|
|
OutText( "Hello World !" );
|
|
OutImage;
|
|
OutImage;
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SINEA60,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
'COMMENT'
|
|
* $Id: sine_a60.a60 978 2017-12-28 21:32:18Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-27 978 1.1 use outsymbol
|
|
* 2017-09-05 946 1.0 Initial version
|
|
*;
|
|
|
|
'INTEGER' I,J,ISIN,ICOS;
|
|
'REAL' X,XRAD,FSIN,FCOS;
|
|
'INTEGER' 'ARRAY' PLOT[1:81];
|
|
|
|
'COMMENT' set record lenth = 132 and page length = 64;
|
|
SYSACT(1,6,132);
|
|
SYSACT(1,8,64);
|
|
|
|
OUTSTRING (1,'(' x sin(x) cos(x) ')');
|
|
OUTSTRING (1,'('-1 -0.5 0')');
|
|
OUTSTRING (1,'(' +0.5 +1')');
|
|
SYSACT(1,14,1);
|
|
OUTSTRING (1,'(' ')');
|
|
OUTSTRING (1,'('+-------------------.-------------------:')');
|
|
OUTSTRING (1,'('-------------------.-------------------+')');
|
|
SYSACT(1,14,1);
|
|
|
|
'FOR' I := 0 'STEP' 1 'UNTIL' 60 'DO' 'BEGIN'
|
|
X := 6.0 * I;
|
|
XRAD := X/57.2957;
|
|
FSIN := SIN(XRAD);
|
|
FCOS := COS(XRAD);
|
|
OUTINTEGER(1,6*I);
|
|
OUTREAL(1,FSIN);
|
|
OUTREAL(1,FCOS);
|
|
|
|
'COMMENT' printer plot symbols: 1=+ 2=. 3=: 4=* 5=# 6=blank;
|
|
'FOR' J := 1 'STEP' 1 'UNTIL' 81 'DO' PLOT[J] := 6;
|
|
PLOT[ 1] := 1;
|
|
PLOT[21] := 2;
|
|
PLOT[41] := 3;
|
|
PLOT[61] := 2;
|
|
PLOT[81] := 1;
|
|
ISIN := ENTIER(41.5 + 40.0 * FSIN);
|
|
ICOS := ENTIER(41.5 + 40.0 * FCOS);
|
|
PLOT[ISIN] := 4;
|
|
PLOT[ICOS] := 5;
|
|
'FOR' J := 1 'STEP' 1 'UNTIL' 81 'DO'
|
|
OUTSYMBOL (1,'('+.:*# ')',PLOT[J]);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
OUTSTRING (1,'(' ')');
|
|
OUTSTRING (1,'('+-------------------.-------------------:')');
|
|
OUTSTRING (1,'('-------------------.-------------------+')');
|
|
SYSACT(1,14,1);
|
|
|
|
'END'
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SINEFOG,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: sine_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SINE
|
|
INTEGER PLOT(81)
|
|
INTEGER I,J,ISIN,ICOS
|
|
REAL*4 X,XRAD,FSIN,FCOS
|
|
INTEGER CBL,CPL,CDO,CCO,CST,CHA
|
|
DATA CBL/1H /,CPL/1H+/,CDO/1H./,CCO/1H:/,CST/1H*/,CHA/1H#/
|
|
C
|
|
WRITE(6,9000)
|
|
WRITE(6,9010)
|
|
C
|
|
C Fortran IV(1966): DO limits must all to be > 0 -- FORTRAN-G enforces this
|
|
DO 100 I=1,61
|
|
X = 6. * (I-1)
|
|
XRAD = X/57.2957795131
|
|
FSIN = SIN(XRAD)
|
|
FCOS = COS(XRAD)
|
|
DO 200 J=1,81
|
|
PLOT(J) = CBL
|
|
200 CONTINUE
|
|
PLOT( 1) = CPL
|
|
PLOT(21) = CDO
|
|
PLOT(41) = CCO
|
|
PLOT(61) = CDO
|
|
PLOT(81) = CPL
|
|
ISIN = 41.5 + 40. * FSIN
|
|
ICOS = 41.5 + 40. * FCOS
|
|
PLOT(ISIN) = CST
|
|
PLOT(ICOS) = CHA
|
|
WRITE(6,9020) X,FSIN,FCOS,PLOT
|
|
100 CONTINUE
|
|
WRITE(6,9010)
|
|
STOP
|
|
C
|
|
9000 FORMAT(1X,' x sin(x) cos(x) ',
|
|
* '-1 -0.5 0',
|
|
* ' +0.5 +1')
|
|
9010 FORMAT(1X,' ',
|
|
* '+-------------------.-------------------:',
|
|
* '-------------------.-------------------:')
|
|
9020 FORMAT(1X,F6.0,1X,F8.5,1X,F8.5,3X,81A1)
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SINEFOH,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: sine_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SINE
|
|
INTEGER PLOT(81)
|
|
INTEGER I,J,ISIN,ICOS
|
|
REAL*4 X,XRAD,FSIN,FCOS
|
|
INTEGER CBL,CPL,CDO,CCO,CST,CHA
|
|
DATA CBL/1H /,CPL/1H+/,CDO/1H./,CCO/1H:/,CST/1H*/,CHA/1H#/
|
|
C
|
|
WRITE(6,9000)
|
|
WRITE(6,9010)
|
|
C
|
|
C Fortran IV(1966): DO limits must all to be > 0 -- FORTRAN-G enforces this
|
|
DO 100 I=1,61
|
|
X = 6. * (I-1)
|
|
XRAD = X/57.2957795131
|
|
FSIN = SIN(XRAD)
|
|
FCOS = COS(XRAD)
|
|
DO 200 J=1,81
|
|
PLOT(J) = CBL
|
|
200 CONTINUE
|
|
PLOT( 1) = CPL
|
|
PLOT(21) = CDO
|
|
PLOT(41) = CCO
|
|
PLOT(61) = CDO
|
|
PLOT(81) = CPL
|
|
ISIN = 41.5 + 40. * FSIN
|
|
ICOS = 41.5 + 40. * FCOS
|
|
PLOT(ISIN) = CST
|
|
PLOT(ICOS) = CHA
|
|
WRITE(6,9020) X,FSIN,FCOS,PLOT
|
|
100 CONTINUE
|
|
WRITE(6,9010)
|
|
STOP
|
|
C
|
|
9000 FORMAT(1X,' x sin(x) cos(x) ',
|
|
* '-1 -0.5 0',
|
|
* ' +0.5 +1')
|
|
9010 FORMAT(1X,' ',
|
|
* '+-------------------.-------------------:',
|
|
* '-------------------.-------------------:')
|
|
9020 FORMAT(1X,F6.0,1X,F8.5,1X,F8.5,3X,81A1)
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SINEFOW,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB SINE#FOW,T=(1,0),P=100,CHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: sine_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SINE
|
|
INTEGER PLOT(81)
|
|
INTEGER I,J,ISIN,ICOS
|
|
REAL*4 X,XRAD,FSIN,FCOS
|
|
INTEGER CBL,CPL,CDO,CCO,CST,CHA
|
|
DATA CBL/1H /,CPL/1H+/,CDO/1H./,CCO/1H:/,CST/1H*/,CHA/1H#/
|
|
C
|
|
WRITE(6,9000)
|
|
WRITE(6,9010)
|
|
C
|
|
C Fortran IV(1966): DO limits must all to be > 0 -- FORTRAN-G enforces this
|
|
DO 100 I=1,61
|
|
X = 6. * (I-1)
|
|
XRAD = X/57.2957795131
|
|
FSIN = SIN(XRAD)
|
|
FCOS = COS(XRAD)
|
|
DO 200 J=1,81
|
|
PLOT(J) = CBL
|
|
200 CONTINUE
|
|
PLOT( 1) = CPL
|
|
PLOT(21) = CDO
|
|
PLOT(41) = CCO
|
|
PLOT(61) = CDO
|
|
PLOT(81) = CPL
|
|
ISIN = 41.5 + 40. * FSIN
|
|
ICOS = 41.5 + 40. * FCOS
|
|
PLOT(ISIN) = CST
|
|
PLOT(ICOS) = CHA
|
|
WRITE(6,9020) X,FSIN,FCOS,PLOT
|
|
100 CONTINUE
|
|
WRITE(6,9010)
|
|
STOP
|
|
C
|
|
9000 FORMAT(1X,' x sin(x) cos(x) ',
|
|
* '-1 -0.5 0',
|
|
* ' +0.5 +1')
|
|
9010 FORMAT(1X,' ',
|
|
* '+-------------------.-------------------:',
|
|
* '-------------------.-------------------:')
|
|
9020 FORMAT(1X,F6.0,1X,F8.5,1X,F8.5,3X,81A1)
|
|
C
|
|
END
|
|
$ENTRY
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=SINEGCC,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: sine_cc.c 964 2017-11-19 08:47:46Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-07-30 931 0.1 Initial version */
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
int main ()
|
|
{
|
|
char plot[82];
|
|
int i,j,isin,icos;
|
|
double x,xrad,fsin,fcos;
|
|
char* f1 = " x sin(x) cos(x) "
|
|
"-1 -0.5 0"
|
|
" +0.5 +1";
|
|
char* f2 = " "
|
|
"+-------------------.-------------------:"
|
|
"-------------------.-------------------:";
|
|
|
|
plot[81] = 0;
|
|
printf ("%s\n",f1);
|
|
printf ("%s\n",f2);
|
|
|
|
for (i=0; i<=60; i++) {
|
|
x = 6. * i;
|
|
xrad = x/57.2957795131;
|
|
fsin = sin(xrad);
|
|
fcos = cos(xrad);
|
|
for (j=0; j<81; j++) plot[j] = ' ';
|
|
plot[ 0] = '+';
|
|
plot[20] = '.';
|
|
plot[40] = ':';
|
|
plot[60] = '.';
|
|
plot[80] = '+';
|
|
isin = 40.5 + 40. * fsin;
|
|
icos = 40.5 + 40. * fcos;
|
|
plot[isin] = '*';
|
|
plot[icos] = '#';
|
|
printf("%6.0f %8.5f %8.5f %s\n", x,fsin,fcos,plot);
|
|
}
|
|
printf ("%s\n",f2);
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SINEJCC,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: sine_cc.c 964 2017-11-19 08:47:46Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-07-30 931 0.1 Initial version */
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
int main ()
|
|
{
|
|
char plot[82];
|
|
int i,j,isin,icos;
|
|
double x,xrad,fsin,fcos;
|
|
char* f1 = " x sin(x) cos(x) "
|
|
"-1 -0.5 0"
|
|
" +0.5 +1";
|
|
char* f2 = " "
|
|
"+-------------------.-------------------:"
|
|
"-------------------.-------------------:";
|
|
|
|
plot[81] = 0;
|
|
printf ("%s\n",f1);
|
|
printf ("%s\n",f2);
|
|
|
|
for (i=0; i<=60; i++) {
|
|
x = 6. * i;
|
|
xrad = x/57.2957795131;
|
|
fsin = sin(xrad);
|
|
fcos = cos(xrad);
|
|
for (j=0; j<81; j++) plot[j] = ' ';
|
|
plot[ 0] = '+';
|
|
plot[20] = '.';
|
|
plot[40] = ':';
|
|
plot[60] = '.';
|
|
plot[80] = '+';
|
|
isin = 40.5 + 40. * fsin;
|
|
icos = 40.5 + 40. * fcos;
|
|
plot[isin] = '*';
|
|
plot[icos] = '#';
|
|
printf("%6.0f %8.5f %8.5f %s\n", x,fsin,fcos,plot);
|
|
}
|
|
printf ("%s\n",f2);
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SINEPAS,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=1024K,
|
|
// OPT='M+',
|
|
// GOPARM='/STACK=512k'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: sine_pas.pas 964 2017-11-19 08:47:46Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-09-08 949 1.0 Initial version *)
|
|
|
|
program sine(input,output);
|
|
var
|
|
i,j,isin,icos : integer;
|
|
x,xrad,fsin,fcos : real;
|
|
plot : ARRAY[1 .. 81] of char;
|
|
|
|
begin
|
|
|
|
writeln(' ',' x sin(x) cos(x) ',
|
|
'-1 -0.5 0',
|
|
' +0.5 +1');
|
|
writeln(' ', ' ',
|
|
'+-------------------.-------------------:',
|
|
'-------------------.-------------------+');
|
|
|
|
for i := 0 to 60 do begin
|
|
x := 6.0 * i;
|
|
xrad := x/57.2957795131;
|
|
fsin := sin(xrad);
|
|
fcos := cos(xrad);
|
|
for j := 1 to 81 do plot[j] := ' ';
|
|
plot[ 1] := '+';
|
|
plot[21] := '.';
|
|
plot[41] := ':';
|
|
plot[61] := '.';
|
|
plot[81] := '+';
|
|
isin := trunc(41.5 + 40.0 * fsin);
|
|
icos := trunc(41.5 + 40.0 * fcos);
|
|
plot[isin] := '*';
|
|
plot[icos] := '#';
|
|
write(' ',x:6:1,fsin:9:5,fcos:9:5,' ');
|
|
for j := 1 to 81 do write(plot[j]:1);
|
|
writeln(' ');
|
|
end;
|
|
writeln(' ', ' ',
|
|
'+-------------------.-------------------:',
|
|
'-------------------.-------------------+');
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SINEPLI,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: sine_pli.pli 964 2017-11-19 08:47:46Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-09-07 947 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
SINE: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (I,ISIN,ICOS) BIN FIXED(31);
|
|
DCL (X,XRAD,FSIN,FCOS) DEC FLOAT(6);
|
|
DCL PLOT CHAR(81);
|
|
|
|
PUT SKIP EDIT(' x sin(x) cos(x) ',
|
|
'-1 -0.5 0',
|
|
' +0.5 +1')
|
|
(A,A,A);
|
|
PUT SKIP EDIT(' ',
|
|
'+-------------------.-------------------:',
|
|
'-------------------.-------------------+')
|
|
(A,A,A);
|
|
|
|
DO I=0 TO 60;
|
|
X = 6. * I;
|
|
XRAD = X/57.2957795131;
|
|
FSIN = SIN(XRAD);
|
|
FCOS = COS(XRAD);
|
|
PLOT = ' ';
|
|
SUBSTR(PLOT, 1,1) = '+';
|
|
SUBSTR(PLOT,21,1) = '.';
|
|
SUBSTR(PLOT,41,1) = ':';
|
|
SUBSTR(PLOT,61,1) = '.';
|
|
SUBSTR(PLOT,81,1) = '+';
|
|
ISIN = 41.5 + 40. * FSIN;
|
|
ICOS = 41.5 + 40. * FCOS;
|
|
SUBSTR(PLOT,ISIN,1) = '*';
|
|
SUBSTR(PLOT,ICOS,1) = '#';
|
|
PUT SKIP EDIT (X,FSIN,FCOS,PLOT)
|
|
(F(6,0),X(1),F(8,5),X(1),F(8,5),X(3),A);
|
|
END;
|
|
|
|
PUT SKIP EDIT(' ',
|
|
'+-------------------.-------------------:',
|
|
'-------------------.-------------------+')
|
|
(A,A,A);
|
|
|
|
END SINE;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SINESIM,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SINE#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
COMMENT
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-09-08 949 1.0 Initial version
|
|
*;
|
|
|
|
BEGIN
|
|
INTEGER i,j,isin,icos;
|
|
REAL x,xrad,fsin,fcos;
|
|
CHARACTER ARRAY plot(1:81);
|
|
|
|
OutText(" x sin(x) cos(x) ");
|
|
OutText("-1 -0.5 0");
|
|
OutText(" +0.5 +1");
|
|
OutImage;
|
|
OutText(" ");
|
|
OutText("+-------------------.-------------------:");
|
|
OutText("-------------------.-------------------+");
|
|
OutImage;
|
|
|
|
FOR i := 0 STEP 1 UNTIL 60 DO BEGIN
|
|
x := 6.0 * i;
|
|
xrad := x/57.2957795131;
|
|
fsin := sin(xrad);
|
|
fcos := cos(xrad);
|
|
FOR j := 1 STEP 1 UNTIL 81 DO plot(j) := ' ';
|
|
plot( 1) := '+';
|
|
plot(21) := '.';
|
|
plot(41) := ':';
|
|
plot(61) := '.';
|
|
plot(81) := '+';
|
|
isin := Entier(41.5 + 40.0 * fsin);
|
|
icos := Entier(41.5 + 40.0 * fcos);
|
|
plot(isin) := '*';
|
|
plot(icos) := '#';
|
|
OutFix(x,0,6);
|
|
OutFix(fsin,5,9);
|
|
OutFix(fcos,5,9);
|
|
OutText(" ");
|
|
FOR j := 1 STEP 1 UNTIL 81 DO OutChar(plot(j));
|
|
OutImage;
|
|
END;
|
|
OutText(" ");
|
|
OutText("+-------------------.-------------------:");
|
|
OutText("-------------------.-------------------+");
|
|
OutImage;
|
|
OutImage;
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPA60F,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
'COMMENT'
|
|
* $Id: soep_a60.a60 975 2017-12-25 19:22:43Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end
|
|
* 2017-12-23 972 1.1 change (n-1)/2 --> n'/'2
|
|
* use integer '/' divide
|
|
* 2017-09-17 951 1.0 Initial version
|
|
* 2017-09-05 946 0.1 First draft
|
|
*;
|
|
|
|
'INTEGER' NMAX,PRNT,IMAX,NMSQRT;
|
|
'INTEGER' I,N,IMIN;
|
|
'INTEGER' NP,IL,NL;
|
|
|
|
'COMMENT' set record lenth = 132 and page length = 64;
|
|
SYSACT(1,6,132);
|
|
SYSACT(1,8,64);
|
|
|
|
ININTEGER(0,NMAX);
|
|
ININTEGER(0,PRNT);
|
|
|
|
'IF' NMAX <= 10 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('nmax must be >= 10, abort')');
|
|
'GOTO' DONE;
|
|
'END';
|
|
|
|
NMSQRT := ENTIER(SQRT(NMAX));
|
|
IMAX := (NMAX-1)'/'2;
|
|
|
|
'BEGIN'
|
|
'BOOLEAN' 'ARRAY' PRIME[0:IMAX];
|
|
'FOR' I := 0 'STEP' 1 'UNTIL' IMAX 'DO' PRIME[I] := 'TRUE';
|
|
|
|
'FOR' N := 3 'STEP' 2 'UNTIL' NMSQRT 'DO' 'BEGIN'
|
|
'IF' PRIME[N'/'2] 'THEN' 'BEGIN'
|
|
IMIN := (N*N) '/' 2;
|
|
'FOR' I := IMIN 'STEP' N 'UNTIL' IMAX 'DO' PRIME[I] := 'FALSE';
|
|
'END';
|
|
'END';
|
|
|
|
'IF' PRNT > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('List of Primes up to ')');
|
|
OUTINTEGER(1, NMAX);
|
|
SYSACT(1,14,1);
|
|
OUTINTEGER(1, 2);
|
|
NP := 1;
|
|
'FOR' I := 1 'STEP' 1 'UNTIL' IMAX 'DO' 'BEGIN'
|
|
'IF' PRIME[I] 'THEN' 'BEGIN'
|
|
OUTINTEGER(1, 1+2*I);
|
|
NP := NP + 1;
|
|
'IF' NP = 10 'THEN' 'BEGIN'
|
|
SYSACT(1,14,1);
|
|
NP := 0;
|
|
'END';
|
|
'END';
|
|
'END';
|
|
'IF' NP > 0 'THEN' SYSACT(1,14,1);
|
|
'END';
|
|
|
|
IL := 4;
|
|
NL := 10;
|
|
NP := 1;
|
|
'FOR' I := 1 'STEP' 1 'UNTIL' IMAX 'DO' 'BEGIN'
|
|
'IF' PRIME[I] 'THEN' NP := NP+ 1;
|
|
'IF' I = IL 'THEN' 'BEGIN'
|
|
NL := 2*IL + 2;
|
|
OUTSTRING (1,'('pi(')');
|
|
OUTINTEGER(1, NL);
|
|
OUTSTRING (1,'('):')');
|
|
OUTINTEGER(1, NP);
|
|
SYSACT(1,14,1);
|
|
IL := 10*(IL+1)-1;
|
|
'END';
|
|
'END';
|
|
|
|
'IF' NL < NMAX 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('pi(')');
|
|
OUTINTEGER(1, NMAX);
|
|
OUTSTRING (1,'('):')');
|
|
OUTINTEGER(1, NP);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
'END';
|
|
|
|
DONE:
|
|
'END'
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
10000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPA60P,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
'COMMENT'
|
|
* $Id: soep_a60.a60 975 2017-12-25 19:22:43Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end
|
|
* 2017-12-23 972 1.1 change (n-1)/2 --> n'/'2
|
|
* use integer '/' divide
|
|
* 2017-09-17 951 1.0 Initial version
|
|
* 2017-09-05 946 0.1 First draft
|
|
*;
|
|
|
|
'INTEGER' NMAX,PRNT,IMAX,NMSQRT;
|
|
'INTEGER' I,N,IMIN;
|
|
'INTEGER' NP,IL,NL;
|
|
|
|
'COMMENT' set record lenth = 132 and page length = 64;
|
|
SYSACT(1,6,132);
|
|
SYSACT(1,8,64);
|
|
|
|
ININTEGER(0,NMAX);
|
|
ININTEGER(0,PRNT);
|
|
|
|
'IF' NMAX <= 10 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('nmax must be >= 10, abort')');
|
|
'GOTO' DONE;
|
|
'END';
|
|
|
|
NMSQRT := ENTIER(SQRT(NMAX));
|
|
IMAX := (NMAX-1)'/'2;
|
|
|
|
'BEGIN'
|
|
'BOOLEAN' 'ARRAY' PRIME[0:IMAX];
|
|
'FOR' I := 0 'STEP' 1 'UNTIL' IMAX 'DO' PRIME[I] := 'TRUE';
|
|
|
|
'FOR' N := 3 'STEP' 2 'UNTIL' NMSQRT 'DO' 'BEGIN'
|
|
'IF' PRIME[N'/'2] 'THEN' 'BEGIN'
|
|
IMIN := (N*N) '/' 2;
|
|
'FOR' I := IMIN 'STEP' N 'UNTIL' IMAX 'DO' PRIME[I] := 'FALSE';
|
|
'END';
|
|
'END';
|
|
|
|
'IF' PRNT > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('List of Primes up to ')');
|
|
OUTINTEGER(1, NMAX);
|
|
SYSACT(1,14,1);
|
|
OUTINTEGER(1, 2);
|
|
NP := 1;
|
|
'FOR' I := 1 'STEP' 1 'UNTIL' IMAX 'DO' 'BEGIN'
|
|
'IF' PRIME[I] 'THEN' 'BEGIN'
|
|
OUTINTEGER(1, 1+2*I);
|
|
NP := NP + 1;
|
|
'IF' NP = 10 'THEN' 'BEGIN'
|
|
SYSACT(1,14,1);
|
|
NP := 0;
|
|
'END';
|
|
'END';
|
|
'END';
|
|
'IF' NP > 0 'THEN' SYSACT(1,14,1);
|
|
'END';
|
|
|
|
IL := 4;
|
|
NL := 10;
|
|
NP := 1;
|
|
'FOR' I := 1 'STEP' 1 'UNTIL' IMAX 'DO' 'BEGIN'
|
|
'IF' PRIME[I] 'THEN' NP := NP+ 1;
|
|
'IF' I = IL 'THEN' 'BEGIN'
|
|
NL := 2*IL + 2;
|
|
OUTSTRING (1,'('pi(')');
|
|
OUTINTEGER(1, NL);
|
|
OUTSTRING (1,'('):')');
|
|
OUTINTEGER(1, NP);
|
|
SYSACT(1,14,1);
|
|
IL := 10*(IL+1)-1;
|
|
'END';
|
|
'END';
|
|
|
|
'IF' NL < NMAX 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('pi(')');
|
|
OUTINTEGER(1, NMAX);
|
|
OUTSTRING (1,'('):')');
|
|
OUTINTEGER(1, NP);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
'END';
|
|
|
|
DONE:
|
|
'END'
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPA60T,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
'COMMENT'
|
|
* $Id: soep_a60.a60 975 2017-12-25 19:22:43Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end
|
|
* 2017-12-23 972 1.1 change (n-1)/2 --> n'/'2
|
|
* use integer '/' divide
|
|
* 2017-09-17 951 1.0 Initial version
|
|
* 2017-09-05 946 0.1 First draft
|
|
*;
|
|
|
|
'INTEGER' NMAX,PRNT,IMAX,NMSQRT;
|
|
'INTEGER' I,N,IMIN;
|
|
'INTEGER' NP,IL,NL;
|
|
|
|
'COMMENT' set record lenth = 132 and page length = 64;
|
|
SYSACT(1,6,132);
|
|
SYSACT(1,8,64);
|
|
|
|
ININTEGER(0,NMAX);
|
|
ININTEGER(0,PRNT);
|
|
|
|
'IF' NMAX <= 10 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('nmax must be >= 10, abort')');
|
|
'GOTO' DONE;
|
|
'END';
|
|
|
|
NMSQRT := ENTIER(SQRT(NMAX));
|
|
IMAX := (NMAX-1)'/'2;
|
|
|
|
'BEGIN'
|
|
'BOOLEAN' 'ARRAY' PRIME[0:IMAX];
|
|
'FOR' I := 0 'STEP' 1 'UNTIL' IMAX 'DO' PRIME[I] := 'TRUE';
|
|
|
|
'FOR' N := 3 'STEP' 2 'UNTIL' NMSQRT 'DO' 'BEGIN'
|
|
'IF' PRIME[N'/'2] 'THEN' 'BEGIN'
|
|
IMIN := (N*N) '/' 2;
|
|
'FOR' I := IMIN 'STEP' N 'UNTIL' IMAX 'DO' PRIME[I] := 'FALSE';
|
|
'END';
|
|
'END';
|
|
|
|
'IF' PRNT > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('List of Primes up to ')');
|
|
OUTINTEGER(1, NMAX);
|
|
SYSACT(1,14,1);
|
|
OUTINTEGER(1, 2);
|
|
NP := 1;
|
|
'FOR' I := 1 'STEP' 1 'UNTIL' IMAX 'DO' 'BEGIN'
|
|
'IF' PRIME[I] 'THEN' 'BEGIN'
|
|
OUTINTEGER(1, 1+2*I);
|
|
NP := NP + 1;
|
|
'IF' NP = 10 'THEN' 'BEGIN'
|
|
SYSACT(1,14,1);
|
|
NP := 0;
|
|
'END';
|
|
'END';
|
|
'END';
|
|
'IF' NP > 0 'THEN' SYSACT(1,14,1);
|
|
'END';
|
|
|
|
IL := 4;
|
|
NL := 10;
|
|
NP := 1;
|
|
'FOR' I := 1 'STEP' 1 'UNTIL' IMAX 'DO' 'BEGIN'
|
|
'IF' PRIME[I] 'THEN' NP := NP+ 1;
|
|
'IF' I = IL 'THEN' 'BEGIN'
|
|
NL := 2*IL + 2;
|
|
OUTSTRING (1,'('pi(')');
|
|
OUTINTEGER(1, NL);
|
|
OUTSTRING (1,'('):')');
|
|
OUTINTEGER(1, NP);
|
|
SYSACT(1,14,1);
|
|
IL := 10*(IL+1)-1;
|
|
'END';
|
|
'END';
|
|
|
|
'IF' NL < NMAX 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('pi(')');
|
|
OUTINTEGER(1, NMAX);
|
|
OUTSTRING (1,'('):')');
|
|
OUTINTEGER(1, NP);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
'END';
|
|
|
|
DONE:
|
|
'END'
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPASMF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NOLIST,NOXREF,NORLD,NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: soep_asm.asm 972 2017-12-23 20:55:41Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-11-12 961 1.0 Initial version
|
|
* 2017-10-03 954 0.1 First draft
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Prime number search
|
|
* RC = 0 ok
|
|
* RC = 4 NMAX out of range
|
|
* RC = 8 unexpected SYSIN EOF
|
|
* RC = 12 open SYSIN failed
|
|
* RC = 16 open SYSPRINT failed
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'0C'
|
|
B EXIT quit with RC=12
|
|
IOPENOK EQU *
|
|
*
|
|
* read input parameters, and check range ------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get NMAX
|
|
ST R1,NMAX
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,PRNT
|
|
*
|
|
L R1,NMAX
|
|
C R1,=F'10' is NMAX >= 10
|
|
BL NMAXBAD if < not
|
|
C R1,=F'10000000' is NMAX <= 10000000
|
|
BNH NMAXOK if <= yes
|
|
NMAXBAD L R1,MSGPERR
|
|
BAL R14,OTEXT print error
|
|
BAL R14,OPUTLINE write line
|
|
MVI RC+3,X'04'
|
|
B EXIT quit with RC=4
|
|
NMAXOK EQU *
|
|
*
|
|
* setup phase ---------------------------------------------------------
|
|
*
|
|
* calculate sqrt(nmax) -----------------------------------
|
|
* use simple bi-section method
|
|
* R4 low bound
|
|
* R5 high bound
|
|
* R7 middle (low+high)/2
|
|
*
|
|
LA R4,1 set low bound
|
|
L R5,NMAX set high bound
|
|
LA R6,32 set iteration limit
|
|
NMSQRTLP LR R7,R4 R7:= low
|
|
AR R7,R5 R7:= (low+high)
|
|
SRA R7,1 R7:= (low+high)/2
|
|
LR R3,R7
|
|
MR R2,R7 (R2,R3) := R7*R7
|
|
LTR R2,R2 more than 32 bit ?
|
|
BNE NMSQRTHI if != yes, mid too high
|
|
CL R3,NMAX mid*mid > NMAX
|
|
BH NMSQRTHI if > yes, mid too high
|
|
LR R4,R7 here mid to low: low := mid
|
|
B NMSQRTGO
|
|
NMSQRTHI LR R5,R7 here mid to high: high := mid
|
|
NMSQRTGO LR R8,R5 R8 := high
|
|
SR R8,R4 R8 := high-low
|
|
LR R1,R6
|
|
C R8,=F'1' spread <= 1 ?
|
|
BNH NMSQRTOK if <= yes, quit
|
|
BCT R6,NMSQRTLP
|
|
ABEND 99 abort if doesn't converge
|
|
NMSQRTOK EQU *
|
|
ST R4,NMSQRT
|
|
|
|
* allocate PRIME array -----------------------------------
|
|
L R2,NMAX
|
|
BCTR R2,0 NMAX-1
|
|
SRA R2,1 (NMAX-1)/2
|
|
ST R2,IMAX
|
|
LA R5,1(R2) IMAX+1 (24 bit enough)
|
|
GETMAIN RU,LV=(5) allocate storage for PRIME
|
|
ST R1,PRIME store sieve base
|
|
LR R9,R1 R9 := PRIME base
|
|
*
|
|
* set each PRIME array byte to X'01' ---------------------
|
|
LR R4,R1 R4 := PRIME
|
|
* R5 := IMAX+1 (still)
|
|
XR R6,R6 R6 := 0
|
|
L R7,=X'01000000' R7 := padding=1 and length=0
|
|
MVCL R4,R6 set all PRIME bytes to 1
|
|
*
|
|
* sieve phase ---------------------------------------------------------
|
|
* outer loop: ind R6 n
|
|
* inc R4 2
|
|
* lim R5 sqrt(NMAX)
|
|
* inner loop: ind R3 p
|
|
* inc R6 n
|
|
* lim R7 pmax
|
|
* R0,R1,R2 temporaries
|
|
* register usage:
|
|
* R0 temporary
|
|
* R1 temporary
|
|
* R2 temporary
|
|
* R3 inner loop ind p
|
|
* R4 outer loop inc 2
|
|
* R5 outer loop lim sqrt(NMAX)
|
|
* R6 inner loop inc n (and outer loop ind !!)
|
|
* R7 inner loop lim pmax
|
|
* R8 -- unused --
|
|
* R9 &prime
|
|
* R10 -- unused --
|
|
* R11 -- unused --
|
|
*
|
|
*
|
|
* equivalent C code:
|
|
* pmax = &prime[imax];
|
|
* for (n=3; n<=nmsqrt; n+=2) {
|
|
* if (prime[(n-1)/2] == 0) continue;
|
|
* for (p=&prime[(n*n-1)/2]; p<=pmax; p+=n) *p = 0;
|
|
* }
|
|
*
|
|
LA R6,3 outer ind: R6:=3
|
|
LA R4,2 outer inc: R4:=2
|
|
L R5,NMSQRT outer lim: R5:=NMSQRT
|
|
LR R7,R9 R7:=&prime
|
|
A R7,IMAX inner lim: R7:=&prime[imax]
|
|
SIEVO LR R2,R6 R2:=n
|
|
SRA R2,1 R2:=n/2
|
|
AR R2,R9 R2:=&prime[n/2]
|
|
CLI 0(R2),X'00' test prime candidate
|
|
BE SIEVOC if = not, continue outer loop
|
|
*
|
|
LR R1,R6 R1:=n
|
|
MR R0,R6 R1:=n*n (lower half, enough)
|
|
LR R3,R1 R3:=n*n too
|
|
*
|
|
SRA R3,1 R3:=(n*n)/2
|
|
AR R3,R9 R3:=&prime[(n*n-1)/2]
|
|
*
|
|
SIEVI MVI 0(R3),X'00' *p=0
|
|
BXLE R3,R6,SIEVI
|
|
*
|
|
SIEVOC BXLE R6,R4,SIEVO
|
|
*
|
|
* print primes table --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
*
|
|
CLI PRNT,X'00' primes to be printed ?
|
|
BE NOPRNT if = skip
|
|
L R1,MSGLIST
|
|
BAL R14,OTEXT print heading
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LA R1,2
|
|
BAL R14,OINT10 print "2" (1st prime...)
|
|
LA R2,1 np=1
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,IMAX lim: R5:=IMAX
|
|
PRTLOOP LR R6,R3 R6:=i
|
|
AR R6,R9 R6:=&primes[i]
|
|
CLI 0(R6),X'00' test whether prime
|
|
BE PRTLOOPC if = not, continue
|
|
LR R1,R3 R1:=i
|
|
SLA R1,1 R1:=2*i
|
|
LA R1,1(R1) R1:=1+2*i
|
|
BAL R14,OINT10 and print F(10)
|
|
LA R2,1(R2) np+=1
|
|
C R2,=F'10' check wheter = 10
|
|
BNZ PRTLOOPC if != not, continue
|
|
BAL R14,OPUTLINE write line
|
|
XR R2,R2 np=0
|
|
PRTLOOPC EQU *
|
|
BXLE R3,R4,PRTLOOP
|
|
*
|
|
LTR R2,R2 check prime count np
|
|
BZ NOPRNT
|
|
BAL R14,OPUTLINE write line
|
|
NOPRNT EQU *
|
|
*
|
|
* print primes count --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R7 il
|
|
* R8 nl
|
|
*
|
|
LA R2,1 np=1
|
|
LA R7,4 il=4
|
|
LA R8,10 nl=10
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,IMAX lim: R5:=IMAX
|
|
TBLLOOP LR R6,R3 R6:=i
|
|
AR R6,R9 R6:=&primes[i]
|
|
CLI 0(R6),X'00' test whether prime
|
|
BE NOPRIME if = not
|
|
LA R2,1(R2) np+= 1
|
|
NOPRIME CR R3,R7 test i != il
|
|
BNE TBLLOOPC
|
|
LR R8,R7 nl=il
|
|
SLA R8,1 nl=2*il
|
|
LA R8,2(R8) nl=2+2*il
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
LR R1,R8
|
|
BAL R14,OINT10 print nl
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LR R1,R7 R1:=il
|
|
LA R1,1(R1) R1:=il+1
|
|
M R0,=F'10' R1:=10*(il+1)
|
|
S R1,=F'1' R1:=10*(il+1)-1
|
|
LR R7,R1 update il
|
|
*
|
|
TBLLOOPC EQU *
|
|
BXLE R3,R4,TBLLOOP
|
|
*
|
|
C R8,NMAX is nl != nmax ?
|
|
BE TBLNOTR if = not, skip extra summary
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
TBLNOTR EQU *
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R13,SAVE+4 get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT10 ---------------------------------------------------
|
|
* read integer, like PL/I F(10) or C %10d format
|
|
*
|
|
IINT10 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(10,R15) pack next 10 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,10(R15) push pointer by 10 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
SAVE DS 18F local save area
|
|
RC DC F'0' return code
|
|
NMAX DC F'10000000' highest prime to search for
|
|
NMSQRT DS F sqrt(NMAX)
|
|
IMAX DS F highest prime array index
|
|
PRIME DS F prime array pointer
|
|
PRNT DC X'00' print enable flag
|
|
*
|
|
* message strings
|
|
*
|
|
MSGPERR OTXTDSC C'NMAX must be >= 10 and <= 10000000, abort'
|
|
MSGLIST OTXTDSC C'List of Primes up to '
|
|
MSGPI OTXTDSC C'pi('
|
|
MSGPISEP OTXTDSC C'): '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
10000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPASMP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NOLIST,NOXREF,NORLD,NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: soep_asm.asm 972 2017-12-23 20:55:41Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-11-12 961 1.0 Initial version
|
|
* 2017-10-03 954 0.1 First draft
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Prime number search
|
|
* RC = 0 ok
|
|
* RC = 4 NMAX out of range
|
|
* RC = 8 unexpected SYSIN EOF
|
|
* RC = 12 open SYSIN failed
|
|
* RC = 16 open SYSPRINT failed
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'0C'
|
|
B EXIT quit with RC=12
|
|
IOPENOK EQU *
|
|
*
|
|
* read input parameters, and check range ------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get NMAX
|
|
ST R1,NMAX
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,PRNT
|
|
*
|
|
L R1,NMAX
|
|
C R1,=F'10' is NMAX >= 10
|
|
BL NMAXBAD if < not
|
|
C R1,=F'10000000' is NMAX <= 10000000
|
|
BNH NMAXOK if <= yes
|
|
NMAXBAD L R1,MSGPERR
|
|
BAL R14,OTEXT print error
|
|
BAL R14,OPUTLINE write line
|
|
MVI RC+3,X'04'
|
|
B EXIT quit with RC=4
|
|
NMAXOK EQU *
|
|
*
|
|
* setup phase ---------------------------------------------------------
|
|
*
|
|
* calculate sqrt(nmax) -----------------------------------
|
|
* use simple bi-section method
|
|
* R4 low bound
|
|
* R5 high bound
|
|
* R7 middle (low+high)/2
|
|
*
|
|
LA R4,1 set low bound
|
|
L R5,NMAX set high bound
|
|
LA R6,32 set iteration limit
|
|
NMSQRTLP LR R7,R4 R7:= low
|
|
AR R7,R5 R7:= (low+high)
|
|
SRA R7,1 R7:= (low+high)/2
|
|
LR R3,R7
|
|
MR R2,R7 (R2,R3) := R7*R7
|
|
LTR R2,R2 more than 32 bit ?
|
|
BNE NMSQRTHI if != yes, mid too high
|
|
CL R3,NMAX mid*mid > NMAX
|
|
BH NMSQRTHI if > yes, mid too high
|
|
LR R4,R7 here mid to low: low := mid
|
|
B NMSQRTGO
|
|
NMSQRTHI LR R5,R7 here mid to high: high := mid
|
|
NMSQRTGO LR R8,R5 R8 := high
|
|
SR R8,R4 R8 := high-low
|
|
LR R1,R6
|
|
C R8,=F'1' spread <= 1 ?
|
|
BNH NMSQRTOK if <= yes, quit
|
|
BCT R6,NMSQRTLP
|
|
ABEND 99 abort if doesn't converge
|
|
NMSQRTOK EQU *
|
|
ST R4,NMSQRT
|
|
|
|
* allocate PRIME array -----------------------------------
|
|
L R2,NMAX
|
|
BCTR R2,0 NMAX-1
|
|
SRA R2,1 (NMAX-1)/2
|
|
ST R2,IMAX
|
|
LA R5,1(R2) IMAX+1 (24 bit enough)
|
|
GETMAIN RU,LV=(5) allocate storage for PRIME
|
|
ST R1,PRIME store sieve base
|
|
LR R9,R1 R9 := PRIME base
|
|
*
|
|
* set each PRIME array byte to X'01' ---------------------
|
|
LR R4,R1 R4 := PRIME
|
|
* R5 := IMAX+1 (still)
|
|
XR R6,R6 R6 := 0
|
|
L R7,=X'01000000' R7 := padding=1 and length=0
|
|
MVCL R4,R6 set all PRIME bytes to 1
|
|
*
|
|
* sieve phase ---------------------------------------------------------
|
|
* outer loop: ind R6 n
|
|
* inc R4 2
|
|
* lim R5 sqrt(NMAX)
|
|
* inner loop: ind R3 p
|
|
* inc R6 n
|
|
* lim R7 pmax
|
|
* R0,R1,R2 temporaries
|
|
* register usage:
|
|
* R0 temporary
|
|
* R1 temporary
|
|
* R2 temporary
|
|
* R3 inner loop ind p
|
|
* R4 outer loop inc 2
|
|
* R5 outer loop lim sqrt(NMAX)
|
|
* R6 inner loop inc n (and outer loop ind !!)
|
|
* R7 inner loop lim pmax
|
|
* R8 -- unused --
|
|
* R9 &prime
|
|
* R10 -- unused --
|
|
* R11 -- unused --
|
|
*
|
|
*
|
|
* equivalent C code:
|
|
* pmax = &prime[imax];
|
|
* for (n=3; n<=nmsqrt; n+=2) {
|
|
* if (prime[(n-1)/2] == 0) continue;
|
|
* for (p=&prime[(n*n-1)/2]; p<=pmax; p+=n) *p = 0;
|
|
* }
|
|
*
|
|
LA R6,3 outer ind: R6:=3
|
|
LA R4,2 outer inc: R4:=2
|
|
L R5,NMSQRT outer lim: R5:=NMSQRT
|
|
LR R7,R9 R7:=&prime
|
|
A R7,IMAX inner lim: R7:=&prime[imax]
|
|
SIEVO LR R2,R6 R2:=n
|
|
SRA R2,1 R2:=n/2
|
|
AR R2,R9 R2:=&prime[n/2]
|
|
CLI 0(R2),X'00' test prime candidate
|
|
BE SIEVOC if = not, continue outer loop
|
|
*
|
|
LR R1,R6 R1:=n
|
|
MR R0,R6 R1:=n*n (lower half, enough)
|
|
LR R3,R1 R3:=n*n too
|
|
*
|
|
SRA R3,1 R3:=(n*n)/2
|
|
AR R3,R9 R3:=&prime[(n*n-1)/2]
|
|
*
|
|
SIEVI MVI 0(R3),X'00' *p=0
|
|
BXLE R3,R6,SIEVI
|
|
*
|
|
SIEVOC BXLE R6,R4,SIEVO
|
|
*
|
|
* print primes table --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
*
|
|
CLI PRNT,X'00' primes to be printed ?
|
|
BE NOPRNT if = skip
|
|
L R1,MSGLIST
|
|
BAL R14,OTEXT print heading
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LA R1,2
|
|
BAL R14,OINT10 print "2" (1st prime...)
|
|
LA R2,1 np=1
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,IMAX lim: R5:=IMAX
|
|
PRTLOOP LR R6,R3 R6:=i
|
|
AR R6,R9 R6:=&primes[i]
|
|
CLI 0(R6),X'00' test whether prime
|
|
BE PRTLOOPC if = not, continue
|
|
LR R1,R3 R1:=i
|
|
SLA R1,1 R1:=2*i
|
|
LA R1,1(R1) R1:=1+2*i
|
|
BAL R14,OINT10 and print F(10)
|
|
LA R2,1(R2) np+=1
|
|
C R2,=F'10' check wheter = 10
|
|
BNZ PRTLOOPC if != not, continue
|
|
BAL R14,OPUTLINE write line
|
|
XR R2,R2 np=0
|
|
PRTLOOPC EQU *
|
|
BXLE R3,R4,PRTLOOP
|
|
*
|
|
LTR R2,R2 check prime count np
|
|
BZ NOPRNT
|
|
BAL R14,OPUTLINE write line
|
|
NOPRNT EQU *
|
|
*
|
|
* print primes count --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R7 il
|
|
* R8 nl
|
|
*
|
|
LA R2,1 np=1
|
|
LA R7,4 il=4
|
|
LA R8,10 nl=10
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,IMAX lim: R5:=IMAX
|
|
TBLLOOP LR R6,R3 R6:=i
|
|
AR R6,R9 R6:=&primes[i]
|
|
CLI 0(R6),X'00' test whether prime
|
|
BE NOPRIME if = not
|
|
LA R2,1(R2) np+= 1
|
|
NOPRIME CR R3,R7 test i != il
|
|
BNE TBLLOOPC
|
|
LR R8,R7 nl=il
|
|
SLA R8,1 nl=2*il
|
|
LA R8,2(R8) nl=2+2*il
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
LR R1,R8
|
|
BAL R14,OINT10 print nl
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LR R1,R7 R1:=il
|
|
LA R1,1(R1) R1:=il+1
|
|
M R0,=F'10' R1:=10*(il+1)
|
|
S R1,=F'1' R1:=10*(il+1)-1
|
|
LR R7,R1 update il
|
|
*
|
|
TBLLOOPC EQU *
|
|
BXLE R3,R4,TBLLOOP
|
|
*
|
|
C R8,NMAX is nl != nmax ?
|
|
BE TBLNOTR if = not, skip extra summary
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
TBLNOTR EQU *
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R13,SAVE+4 get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT10 ---------------------------------------------------
|
|
* read integer, like PL/I F(10) or C %10d format
|
|
*
|
|
IINT10 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(10,R15) pack next 10 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,10(R15) push pointer by 10 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
SAVE DS 18F local save area
|
|
RC DC F'0' return code
|
|
NMAX DC F'10000000' highest prime to search for
|
|
NMSQRT DS F sqrt(NMAX)
|
|
IMAX DS F highest prime array index
|
|
PRIME DS F prime array pointer
|
|
PRNT DC X'00' print enable flag
|
|
*
|
|
* message strings
|
|
*
|
|
MSGPERR OTXTDSC C'NMAX must be >= 10 and <= 10000000, abort'
|
|
MSGLIST OTXTDSC C'List of Primes up to '
|
|
MSGPI OTXTDSC C'pi('
|
|
MSGPISEP OTXTDSC C'): '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPASMT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=128K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: soep_asm.asm 972 2017-12-23 20:55:41Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-11-12 961 1.0 Initial version
|
|
* 2017-10-03 954 0.1 First draft
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Prime number search
|
|
* RC = 0 ok
|
|
* RC = 4 NMAX out of range
|
|
* RC = 8 unexpected SYSIN EOF
|
|
* RC = 12 open SYSIN failed
|
|
* RC = 16 open SYSPRINT failed
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'0C'
|
|
B EXIT quit with RC=12
|
|
IOPENOK EQU *
|
|
*
|
|
* read input parameters, and check range ------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get NMAX
|
|
ST R1,NMAX
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,PRNT
|
|
*
|
|
L R1,NMAX
|
|
C R1,=F'10' is NMAX >= 10
|
|
BL NMAXBAD if < not
|
|
C R1,=F'10000000' is NMAX <= 10000000
|
|
BNH NMAXOK if <= yes
|
|
NMAXBAD L R1,MSGPERR
|
|
BAL R14,OTEXT print error
|
|
BAL R14,OPUTLINE write line
|
|
MVI RC+3,X'04'
|
|
B EXIT quit with RC=4
|
|
NMAXOK EQU *
|
|
*
|
|
* setup phase ---------------------------------------------------------
|
|
*
|
|
* calculate sqrt(nmax) -----------------------------------
|
|
* use simple bi-section method
|
|
* R4 low bound
|
|
* R5 high bound
|
|
* R7 middle (low+high)/2
|
|
*
|
|
LA R4,1 set low bound
|
|
L R5,NMAX set high bound
|
|
LA R6,32 set iteration limit
|
|
NMSQRTLP LR R7,R4 R7:= low
|
|
AR R7,R5 R7:= (low+high)
|
|
SRA R7,1 R7:= (low+high)/2
|
|
LR R3,R7
|
|
MR R2,R7 (R2,R3) := R7*R7
|
|
LTR R2,R2 more than 32 bit ?
|
|
BNE NMSQRTHI if != yes, mid too high
|
|
CL R3,NMAX mid*mid > NMAX
|
|
BH NMSQRTHI if > yes, mid too high
|
|
LR R4,R7 here mid to low: low := mid
|
|
B NMSQRTGO
|
|
NMSQRTHI LR R5,R7 here mid to high: high := mid
|
|
NMSQRTGO LR R8,R5 R8 := high
|
|
SR R8,R4 R8 := high-low
|
|
LR R1,R6
|
|
C R8,=F'1' spread <= 1 ?
|
|
BNH NMSQRTOK if <= yes, quit
|
|
BCT R6,NMSQRTLP
|
|
ABEND 99 abort if doesn't converge
|
|
NMSQRTOK EQU *
|
|
ST R4,NMSQRT
|
|
|
|
* allocate PRIME array -----------------------------------
|
|
L R2,NMAX
|
|
BCTR R2,0 NMAX-1
|
|
SRA R2,1 (NMAX-1)/2
|
|
ST R2,IMAX
|
|
LA R5,1(R2) IMAX+1 (24 bit enough)
|
|
GETMAIN RU,LV=(5) allocate storage for PRIME
|
|
ST R1,PRIME store sieve base
|
|
LR R9,R1 R9 := PRIME base
|
|
*
|
|
* set each PRIME array byte to X'01' ---------------------
|
|
LR R4,R1 R4 := PRIME
|
|
* R5 := IMAX+1 (still)
|
|
XR R6,R6 R6 := 0
|
|
L R7,=X'01000000' R7 := padding=1 and length=0
|
|
MVCL R4,R6 set all PRIME bytes to 1
|
|
*
|
|
* sieve phase ---------------------------------------------------------
|
|
* outer loop: ind R6 n
|
|
* inc R4 2
|
|
* lim R5 sqrt(NMAX)
|
|
* inner loop: ind R3 p
|
|
* inc R6 n
|
|
* lim R7 pmax
|
|
* R0,R1,R2 temporaries
|
|
* register usage:
|
|
* R0 temporary
|
|
* R1 temporary
|
|
* R2 temporary
|
|
* R3 inner loop ind p
|
|
* R4 outer loop inc 2
|
|
* R5 outer loop lim sqrt(NMAX)
|
|
* R6 inner loop inc n (and outer loop ind !!)
|
|
* R7 inner loop lim pmax
|
|
* R8 -- unused --
|
|
* R9 &prime
|
|
* R10 -- unused --
|
|
* R11 -- unused --
|
|
*
|
|
*
|
|
* equivalent C code:
|
|
* pmax = &prime[imax];
|
|
* for (n=3; n<=nmsqrt; n+=2) {
|
|
* if (prime[(n-1)/2] == 0) continue;
|
|
* for (p=&prime[(n*n-1)/2]; p<=pmax; p+=n) *p = 0;
|
|
* }
|
|
*
|
|
LA R6,3 outer ind: R6:=3
|
|
LA R4,2 outer inc: R4:=2
|
|
L R5,NMSQRT outer lim: R5:=NMSQRT
|
|
LR R7,R9 R7:=&prime
|
|
A R7,IMAX inner lim: R7:=&prime[imax]
|
|
SIEVO LR R2,R6 R2:=n
|
|
SRA R2,1 R2:=n/2
|
|
AR R2,R9 R2:=&prime[n/2]
|
|
CLI 0(R2),X'00' test prime candidate
|
|
BE SIEVOC if = not, continue outer loop
|
|
*
|
|
LR R1,R6 R1:=n
|
|
MR R0,R6 R1:=n*n (lower half, enough)
|
|
LR R3,R1 R3:=n*n too
|
|
*
|
|
SRA R3,1 R3:=(n*n)/2
|
|
AR R3,R9 R3:=&prime[(n*n-1)/2]
|
|
*
|
|
SIEVI MVI 0(R3),X'00' *p=0
|
|
BXLE R3,R6,SIEVI
|
|
*
|
|
SIEVOC BXLE R6,R4,SIEVO
|
|
*
|
|
* print primes table --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
*
|
|
CLI PRNT,X'00' primes to be printed ?
|
|
BE NOPRNT if = skip
|
|
L R1,MSGLIST
|
|
BAL R14,OTEXT print heading
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LA R1,2
|
|
BAL R14,OINT10 print "2" (1st prime...)
|
|
LA R2,1 np=1
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,IMAX lim: R5:=IMAX
|
|
PRTLOOP LR R6,R3 R6:=i
|
|
AR R6,R9 R6:=&primes[i]
|
|
CLI 0(R6),X'00' test whether prime
|
|
BE PRTLOOPC if = not, continue
|
|
LR R1,R3 R1:=i
|
|
SLA R1,1 R1:=2*i
|
|
LA R1,1(R1) R1:=1+2*i
|
|
BAL R14,OINT10 and print F(10)
|
|
LA R2,1(R2) np+=1
|
|
C R2,=F'10' check wheter = 10
|
|
BNZ PRTLOOPC if != not, continue
|
|
BAL R14,OPUTLINE write line
|
|
XR R2,R2 np=0
|
|
PRTLOOPC EQU *
|
|
BXLE R3,R4,PRTLOOP
|
|
*
|
|
LTR R2,R2 check prime count np
|
|
BZ NOPRNT
|
|
BAL R14,OPUTLINE write line
|
|
NOPRNT EQU *
|
|
*
|
|
* print primes count --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R7 il
|
|
* R8 nl
|
|
*
|
|
LA R2,1 np=1
|
|
LA R7,4 il=4
|
|
LA R8,10 nl=10
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,IMAX lim: R5:=IMAX
|
|
TBLLOOP LR R6,R3 R6:=i
|
|
AR R6,R9 R6:=&primes[i]
|
|
CLI 0(R6),X'00' test whether prime
|
|
BE NOPRIME if = not
|
|
LA R2,1(R2) np+= 1
|
|
NOPRIME CR R3,R7 test i != il
|
|
BNE TBLLOOPC
|
|
LR R8,R7 nl=il
|
|
SLA R8,1 nl=2*il
|
|
LA R8,2(R8) nl=2+2*il
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
LR R1,R8
|
|
BAL R14,OINT10 print nl
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LR R1,R7 R1:=il
|
|
LA R1,1(R1) R1:=il+1
|
|
M R0,=F'10' R1:=10*(il+1)
|
|
S R1,=F'1' R1:=10*(il+1)-1
|
|
LR R7,R1 update il
|
|
*
|
|
TBLLOOPC EQU *
|
|
BXLE R3,R4,TBLLOOP
|
|
*
|
|
C R8,NMAX is nl != nmax ?
|
|
BE TBLNOTR if = not, skip extra summary
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
TBLNOTR EQU *
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R13,SAVE+4 get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT10 ---------------------------------------------------
|
|
* read integer, like PL/I F(10) or C %10d format
|
|
*
|
|
IINT10 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(10,R15) pack next 10 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,10(R15) push pointer by 10 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
SAVE DS 18F local save area
|
|
RC DC F'0' return code
|
|
NMAX DC F'10000000' highest prime to search for
|
|
NMSQRT DS F sqrt(NMAX)
|
|
IMAX DS F highest prime array index
|
|
PRIME DS F prime array pointer
|
|
PRNT DC X'00' print enable flag
|
|
*
|
|
* message strings
|
|
*
|
|
MSGPERR OTXTDSC C'NMAX must be >= 10 and <= 10000000, abort'
|
|
MSGLIST OTXTDSC C'List of Primes up to '
|
|
MSGPI OTXTDSC C'pi('
|
|
MSGPISEP OTXTDSC C'): '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPGCCF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soep_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-10-15 956 1.0 Initial version */
|
|
/* 2017-08-17 941 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int imax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
char *prime;
|
|
char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
imax = (nmax-1)/2;
|
|
prime = malloc(imax+1); /* need [1,...,imax] */
|
|
pmax = &prime[imax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 1;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
if (prime[n/2] == 0) continue;
|
|
for (p=&prime[(n*n)/2]; p<=pmax; p+=n) *p = 0;
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (! prime[i]) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (prime[i]) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
10000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPGCCP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soep_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-10-15 956 1.0 Initial version */
|
|
/* 2017-08-17 941 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int imax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
char *prime;
|
|
char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
imax = (nmax-1)/2;
|
|
prime = malloc(imax+1); /* need [1,...,imax] */
|
|
pmax = &prime[imax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 1;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
if (prime[n/2] == 0) continue;
|
|
for (p=&prime[(n*n)/2]; p<=pmax; p+=n) *p = 0;
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (! prime[i]) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (prime[i]) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPGCCT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soep_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-10-15 956 1.0 Initial version */
|
|
/* 2017-08-17 941 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int imax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
char *prime;
|
|
char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
imax = (nmax-1)/2;
|
|
prime = malloc(imax+1); /* need [1,...,imax] */
|
|
pmax = &prime[imax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 1;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
if (prime[n/2] == 0) continue;
|
|
for (p=&prime[(n*n)/2]; p<=pmax; p+=n) *p = 0;
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (! prime[i]) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (prime[i]) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPJCCF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soep_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-10-15 956 1.0 Initial version */
|
|
/* 2017-08-17 941 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int imax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
char *prime;
|
|
char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
imax = (nmax-1)/2;
|
|
prime = malloc(imax+1); /* need [1,...,imax] */
|
|
pmax = &prime[imax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 1;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
if (prime[n/2] == 0) continue;
|
|
for (p=&prime[(n*n)/2]; p<=pmax; p+=n) *p = 0;
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (! prime[i]) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (prime[i]) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
10000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPJCCP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soep_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-10-15 956 1.0 Initial version */
|
|
/* 2017-08-17 941 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int imax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
char *prime;
|
|
char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
imax = (nmax-1)/2;
|
|
prime = malloc(imax+1); /* need [1,...,imax] */
|
|
pmax = &prime[imax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 1;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
if (prime[n/2] == 0) continue;
|
|
for (p=&prime[(n*n)/2]; p<=pmax; p+=n) *p = 0;
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (! prime[i]) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (prime[i]) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPJCCT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soep_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-10-15 956 1.0 Initial version */
|
|
/* 2017-08-17 941 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int imax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
char *prime;
|
|
char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
imax = (nmax-1)/2;
|
|
prime = malloc(imax+1); /* need [1,...,imax] */
|
|
pmax = &prime[imax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 1;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
if (prime[n/2] == 0) continue;
|
|
for (p=&prime[(n*n)/2]; p<=pmax; p+=n) *p = 0;
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (! prime[i]) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=imax;i++) {
|
|
if (prime[i]) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOGF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
10000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOGP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOGT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOHF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
10000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOHP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOHT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOWF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB SOEP#FOW,T=(1,0),P=100,CHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
$ENTRY
|
|
10000000 0
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOWP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB SOEP#FOW,T=(1,0),P=2000,NOCHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
$ENTRY
|
|
10000000 1
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPFOWT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB SOEP#FOW,T=(1,0),P=100,NOCHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: soep_for.f 975 2017-12-25 19:22:43Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-25 975 1.1 use sqrt(nmax) as outer loop end
|
|
C 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
C 2017-09-17 951 1.0 Initial version
|
|
C 2017-08-26 942 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM SOEP
|
|
INTEGER NMAX,PRNT,IMAX,NMSQRT
|
|
INTEGER I,N,IMIN
|
|
INTEGER NP,IL,NL
|
|
INTEGER PLIST(10)
|
|
LOGICAL*1 PRIME(5000000)
|
|
C
|
|
READ(5,9000,ERR=910,END=900) NMAX,PRNT
|
|
IF (NMAX .LT. 10 .OR. NMAX .GT. 10000000) GOTO 920
|
|
C
|
|
NMSQRT = IFIX(SQRT(FLOAT(NMAX)))
|
|
IMAX = (NMAX-1)/2
|
|
DO 100 I=1,IMAX
|
|
PRIME(I) = .TRUE.
|
|
100 CONTINUE
|
|
C
|
|
DO 300 N=3,NMSQRT,2
|
|
IF (.NOT. PRIME(N/2)) GOTO 300
|
|
IMIN = (N*N)/2
|
|
DO 200 I=IMIN,IMAX,N
|
|
PRIME(I) = .FALSE.
|
|
200 CONTINUE
|
|
300 CONTINUE
|
|
C
|
|
IF (PRNT .EQ. 0) GOTO 500
|
|
WRITE(6,9010) NMAX
|
|
PLIST(1) = 2
|
|
NP = 1
|
|
DO 400 I=1,IMAX
|
|
IF (.NOT. PRIME(I)) GOTO 400
|
|
NP = NP + 1
|
|
PLIST(NP) = 1+2*I
|
|
IF (NP .LT. 10) GOTO 400
|
|
WRITE(6,9020) PLIST
|
|
NP = 0
|
|
400 CONTINUE
|
|
IF (NP .NE. 0) WRITE(6,9020) (PLIST(I),I=1,NP)
|
|
500 CONTINUE
|
|
C
|
|
IL = 4
|
|
NL = 10
|
|
NP = 1
|
|
DO 600 I=1,IMAX
|
|
IF (PRIME(I)) NP = NP + 1
|
|
IF (I .NE. IL) GOTO 650
|
|
NL = 2*IL+2
|
|
WRITE(6,9030) NL,NP
|
|
IL = 10*(IL+1)-1
|
|
650 CONTINUE
|
|
600 CONTINUE
|
|
IF (NL .NE. NMAX) WRITE(6,9030) NMAX,NP
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
920 WRITE(6,9050)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I10)
|
|
9010 FORMAT(1X,'List of Primes up to',I8)
|
|
9020 FORMAT(10(1X,I7))
|
|
9030 FORMAT(1X,'pi(',I8,'): ',I8)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
9050 FORMAT(1X,'nmax out of range (10...10000000), abort')
|
|
C
|
|
END
|
|
$ENTRY
|
|
100000 1
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPPASF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6500K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=6500K,
|
|
// OPT='M+,D-',
|
|
// GOPARM='/STACK=5500K'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: soep_pas.pas 975 2017-12-25 19:22:43Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end *)
|
|
(* 2017-12-25 974 1.1 5M sieve array *)
|
|
(* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 *)
|
|
(* 2017-09-07 948 1.0 Initial version *)
|
|
|
|
program soep(input,output);
|
|
var
|
|
nmax,prnt,imax : integer;
|
|
nmsqrt : integer;
|
|
i,n,imin : integer;
|
|
np,il,nl : integer;
|
|
rnmax : real;
|
|
sieve : ARRAY[1 .. 5000000] of boolean;
|
|
|
|
begin
|
|
|
|
read(nmax);
|
|
read(prnt);
|
|
|
|
if (nmax < 10) or (nmax > 10000000) then begin
|
|
writeln(' ', 'nmax out of range (10...10000000), abort');
|
|
exit(8);
|
|
end;
|
|
|
|
rnmax := nmax;
|
|
nmsqrt := trunc(sqrt(nmax));
|
|
imax := (nmax-1) div 2;
|
|
for i := 1 to imax do sieve[i] := TRUE;
|
|
|
|
n := 3;
|
|
while n <= nmsqrt do begin
|
|
if sieve[n div 2] then begin
|
|
i := (n*n) div 2;
|
|
while i <= imax do begin
|
|
sieve[i] := FALSE;
|
|
i := i + n;
|
|
end;
|
|
end;
|
|
n := n + 2;
|
|
end;
|
|
|
|
if prnt > 0 then begin
|
|
writeln(' ', 'List of Primes up to ', nmax:8);
|
|
write(2:8);
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if sieve[i] then begin
|
|
write(1+2*i:8);
|
|
np := np + 1;
|
|
if np = 10 then begin
|
|
writeln(' ');
|
|
np := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
if np > 0 then writeln();
|
|
end;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if sieve[i] then np := np + 1;
|
|
if i = il then begin
|
|
nl := 2*il + 2;
|
|
writeln(' ', 'pi(', nl:8, '): ', np:8);
|
|
il := 10*(il+1)-1;
|
|
end;
|
|
end;
|
|
|
|
if nl < nmax then writeln(' ', 'pi(', nmax:8, '): ', np:8);
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
10000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPPASP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6500K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=6500K,
|
|
// OPT='M+,D-',
|
|
// GOPARM='/STACK=5500K'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: soep_pas.pas 975 2017-12-25 19:22:43Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end *)
|
|
(* 2017-12-25 974 1.1 5M sieve array *)
|
|
(* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 *)
|
|
(* 2017-09-07 948 1.0 Initial version *)
|
|
|
|
program soep(input,output);
|
|
var
|
|
nmax,prnt,imax : integer;
|
|
nmsqrt : integer;
|
|
i,n,imin : integer;
|
|
np,il,nl : integer;
|
|
rnmax : real;
|
|
sieve : ARRAY[1 .. 5000000] of boolean;
|
|
|
|
begin
|
|
|
|
read(nmax);
|
|
read(prnt);
|
|
|
|
if (nmax < 10) or (nmax > 10000000) then begin
|
|
writeln(' ', 'nmax out of range (10...10000000), abort');
|
|
exit(8);
|
|
end;
|
|
|
|
rnmax := nmax;
|
|
nmsqrt := trunc(sqrt(nmax));
|
|
imax := (nmax-1) div 2;
|
|
for i := 1 to imax do sieve[i] := TRUE;
|
|
|
|
n := 3;
|
|
while n <= nmsqrt do begin
|
|
if sieve[n div 2] then begin
|
|
i := (n*n) div 2;
|
|
while i <= imax do begin
|
|
sieve[i] := FALSE;
|
|
i := i + n;
|
|
end;
|
|
end;
|
|
n := n + 2;
|
|
end;
|
|
|
|
if prnt > 0 then begin
|
|
writeln(' ', 'List of Primes up to ', nmax:8);
|
|
write(2:8);
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if sieve[i] then begin
|
|
write(1+2*i:8);
|
|
np := np + 1;
|
|
if np = 10 then begin
|
|
writeln(' ');
|
|
np := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
if np > 0 then writeln();
|
|
end;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if sieve[i] then np := np + 1;
|
|
if i = il then begin
|
|
nl := 2*il + 2;
|
|
writeln(' ', 'pi(', nl:8, '): ', np:8);
|
|
il := 10*(il+1)-1;
|
|
end;
|
|
end;
|
|
|
|
if nl < nmax then writeln(' ', 'pi(', nmax:8, '): ', np:8);
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPPAST,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6500K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=6500K,
|
|
// OPT='M+',
|
|
// GOPARM='/STACK=5500K'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: soep_pas.pas 975 2017-12-25 19:22:43Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end *)
|
|
(* 2017-12-25 974 1.1 5M sieve array *)
|
|
(* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 *)
|
|
(* 2017-09-07 948 1.0 Initial version *)
|
|
|
|
program soep(input,output);
|
|
var
|
|
nmax,prnt,imax : integer;
|
|
nmsqrt : integer;
|
|
i,n,imin : integer;
|
|
np,il,nl : integer;
|
|
rnmax : real;
|
|
sieve : ARRAY[1 .. 5000000] of boolean;
|
|
|
|
begin
|
|
|
|
read(nmax);
|
|
read(prnt);
|
|
|
|
if (nmax < 10) or (nmax > 10000000) then begin
|
|
writeln(' ', 'nmax out of range (10...10000000), abort');
|
|
exit(8);
|
|
end;
|
|
|
|
rnmax := nmax;
|
|
nmsqrt := trunc(sqrt(nmax));
|
|
imax := (nmax-1) div 2;
|
|
for i := 1 to imax do sieve[i] := TRUE;
|
|
|
|
n := 3;
|
|
while n <= nmsqrt do begin
|
|
if sieve[n div 2] then begin
|
|
i := (n*n) div 2;
|
|
while i <= imax do begin
|
|
sieve[i] := FALSE;
|
|
i := i + n;
|
|
end;
|
|
end;
|
|
n := n + 2;
|
|
end;
|
|
|
|
if prnt > 0 then begin
|
|
writeln(' ', 'List of Primes up to ', nmax:8);
|
|
write(2:8);
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if sieve[i] then begin
|
|
write(1+2*i:8);
|
|
np := np + 1;
|
|
if np = 10 then begin
|
|
writeln(' ');
|
|
np := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
if np > 0 then writeln();
|
|
end;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if sieve[i] then np := np + 1;
|
|
if i = il then begin
|
|
nl := 2*il + 2;
|
|
writeln(' ', 'pi(', nl:8, '): ', np:8);
|
|
il := 10*(il+1)-1;
|
|
end;
|
|
end;
|
|
|
|
if nl < nmax then writeln(' ', 'pi(', nmax:8, '): ', np:8);
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPPLIF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=2200K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: soep_pli.pli 976 2017-12-26 15:35:59Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-26 976 1.3 use CHAR(1) array; go for max PRIME size*/
|
|
/* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end */
|
|
/* 2017-12-25 974 1.1 use 2-dim PRIME array */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-09-17 951 1.0 Initial version */
|
|
/* 2017-09-01 945 0.1 First draft */
|
|
|
|
SOEP: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (NMAX,PRNT,IMAX) BIN FIXED(31) INIT(0);
|
|
DCL (NMSQRT) BIN FIXED(31) INIT(0);
|
|
DCL (I,N,IMIN) BIN FIXED(31) INIT(0);
|
|
DCL (NP,IL,NL) BIN FIXED(31) INIT(0);
|
|
/* In PL/I(F) V5.5 array bounds are BIN(15) ! limited to 32k !! */
|
|
/* And the maximal aggregate size is 2 MByte !! */
|
|
/* So go for a 2-dimensional array; 1954*1024 = 2000896; */
|
|
/* Use 0 as lower bound to make index calculations easy: */
|
|
/* PRIME(I) turns into PRIME(I/1024,MOD(I,1024)) */
|
|
DCL PRIME(0:1953,0:1023) CHAR(1);
|
|
|
|
ON ENDFILE(SYSIN) BEGIN;
|
|
PUT SKIP EDIT('Unexpected EOF, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
ON CONVERSION BEGIN;
|
|
PUT SKIP EDIT('Conversion error, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
GET EDIT(NMAX,PRNT) (F(10),F(10));
|
|
|
|
/*IF NMAX < 10 | NMAX > 4000000 THEN DO;*/
|
|
IF NMAX > 4000000 THEN DO;
|
|
PUT SKIP EDIT('nmax out of range (10...4000000), abort') (A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
NMSQRT = FLOOR(SQRT(NMAX));
|
|
IMAX = (NMAX-1)/2;
|
|
|
|
DO I=1 TO IMAX;
|
|
PRIME(I/1024,MOD(I,1024)) = '1';
|
|
END;
|
|
|
|
DO N=3 TO NMSQRT BY 2;
|
|
I = N/2;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN DO;
|
|
IMIN = N*N/2;
|
|
DO I=IMIN TO IMAX BY N;
|
|
PRIME(I/1024,MOD(I,1024)) = '0';
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF PRNT > 0 THEN DO;
|
|
PUT SKIP EDIT('List of Primes up to ',NMAX) (A,F(8));
|
|
PUT SKIP EDIT(' ',2) (A,F(7));
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN DO;
|
|
PUT EDIT(' ',1+2*I) (A,F(7));
|
|
NP = NP + 1;
|
|
IF NP = 10 THEN DO;
|
|
PUT SKIP;
|
|
NP = 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF NP > 0 THEN PUT SKIP;
|
|
END;
|
|
|
|
IL = 4;
|
|
NL = 10;
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN NP = NP + 1;
|
|
IF I = IL THEN DO;
|
|
NL = 2*IL + 2;
|
|
PUT SKIP EDIT('pi(',NL,'): ',NP) (A,F(8),A,F(8));
|
|
IL = 10*(IL+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF NL < NMAX THEN PUT SKIP EDIT('pi(',NMAX,'): ',NP)
|
|
(A,F(8),A,F(8));
|
|
|
|
DONE:;
|
|
|
|
END SOEP;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
4000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPPLIP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=2200K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: soep_pli.pli 976 2017-12-26 15:35:59Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-26 976 1.3 use CHAR(1) array; go for max PRIME size*/
|
|
/* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end */
|
|
/* 2017-12-25 974 1.1 use 2-dim PRIME array */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-09-17 951 1.0 Initial version */
|
|
/* 2017-09-01 945 0.1 First draft */
|
|
|
|
SOEP: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (NMAX,PRNT,IMAX) BIN FIXED(31) INIT(0);
|
|
DCL (NMSQRT) BIN FIXED(31) INIT(0);
|
|
DCL (I,N,IMIN) BIN FIXED(31) INIT(0);
|
|
DCL (NP,IL,NL) BIN FIXED(31) INIT(0);
|
|
/* In PL/I(F) V5.5 array bounds are BIN(15) ! limited to 32k !! */
|
|
/* And the maximal aggregate size is 2 MByte !! */
|
|
/* So go for a 2-dimensional array; 1954*1024 = 2000896; */
|
|
/* Use 0 as lower bound to make index calculations easy: */
|
|
/* PRIME(I) turns into PRIME(I/1024,MOD(I,1024)) */
|
|
DCL PRIME(0:1953,0:1023) CHAR(1);
|
|
|
|
ON ENDFILE(SYSIN) BEGIN;
|
|
PUT SKIP EDIT('Unexpected EOF, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
ON CONVERSION BEGIN;
|
|
PUT SKIP EDIT('Conversion error, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
GET EDIT(NMAX,PRNT) (F(10),F(10));
|
|
|
|
/*IF NMAX < 10 | NMAX > 4000000 THEN DO;*/
|
|
IF NMAX > 4000000 THEN DO;
|
|
PUT SKIP EDIT('nmax out of range (10...4000000), abort') (A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
NMSQRT = FLOOR(SQRT(NMAX));
|
|
IMAX = (NMAX-1)/2;
|
|
|
|
DO I=1 TO IMAX;
|
|
PRIME(I/1024,MOD(I,1024)) = '1';
|
|
END;
|
|
|
|
DO N=3 TO NMSQRT BY 2;
|
|
I = N/2;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN DO;
|
|
IMIN = N*N/2;
|
|
DO I=IMIN TO IMAX BY N;
|
|
PRIME(I/1024,MOD(I,1024)) = '0';
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF PRNT > 0 THEN DO;
|
|
PUT SKIP EDIT('List of Primes up to ',NMAX) (A,F(8));
|
|
PUT SKIP EDIT(' ',2) (A,F(7));
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN DO;
|
|
PUT EDIT(' ',1+2*I) (A,F(7));
|
|
NP = NP + 1;
|
|
IF NP = 10 THEN DO;
|
|
PUT SKIP;
|
|
NP = 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF NP > 0 THEN PUT SKIP;
|
|
END;
|
|
|
|
IL = 4;
|
|
NL = 10;
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN NP = NP + 1;
|
|
IF I = IL THEN DO;
|
|
NL = 2*IL + 2;
|
|
PUT SKIP EDIT('pi(',NL,'): ',NP) (A,F(8),A,F(8));
|
|
IL = 10*(IL+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF NL < NMAX THEN PUT SKIP EDIT('pi(',NMAX,'): ',NP)
|
|
(A,F(8),A,F(8));
|
|
|
|
DONE:;
|
|
|
|
END SOEP;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
4000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPPLIT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=2200K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: soep_pli.pli 976 2017-12-26 15:35:59Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-26 976 1.3 use CHAR(1) array; go for max PRIME size*/
|
|
/* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end */
|
|
/* 2017-12-25 974 1.1 use 2-dim PRIME array */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-09-17 951 1.0 Initial version */
|
|
/* 2017-09-01 945 0.1 First draft */
|
|
|
|
SOEP: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (NMAX,PRNT,IMAX) BIN FIXED(31) INIT(0);
|
|
DCL (NMSQRT) BIN FIXED(31) INIT(0);
|
|
DCL (I,N,IMIN) BIN FIXED(31) INIT(0);
|
|
DCL (NP,IL,NL) BIN FIXED(31) INIT(0);
|
|
/* In PL/I(F) V5.5 array bounds are BIN(15) ! limited to 32k !! */
|
|
/* And the maximal aggregate size is 2 MByte !! */
|
|
/* So go for a 2-dimensional array; 1954*1024 = 2000896; */
|
|
/* Use 0 as lower bound to make index calculations easy: */
|
|
/* PRIME(I) turns into PRIME(I/1024,MOD(I,1024)) */
|
|
DCL PRIME(0:1953,0:1023) CHAR(1);
|
|
|
|
ON ENDFILE(SYSIN) BEGIN;
|
|
PUT SKIP EDIT('Unexpected EOF, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
ON CONVERSION BEGIN;
|
|
PUT SKIP EDIT('Conversion error, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
GET EDIT(NMAX,PRNT) (F(10),F(10));
|
|
|
|
/*IF NMAX < 10 | NMAX > 4000000 THEN DO;*/
|
|
IF NMAX > 4000000 THEN DO;
|
|
PUT SKIP EDIT('nmax out of range (10...4000000), abort') (A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
NMSQRT = FLOOR(SQRT(NMAX));
|
|
IMAX = (NMAX-1)/2;
|
|
|
|
DO I=1 TO IMAX;
|
|
PRIME(I/1024,MOD(I,1024)) = '1';
|
|
END;
|
|
|
|
DO N=3 TO NMSQRT BY 2;
|
|
I = N/2;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN DO;
|
|
IMIN = N*N/2;
|
|
DO I=IMIN TO IMAX BY N;
|
|
PRIME(I/1024,MOD(I,1024)) = '0';
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF PRNT > 0 THEN DO;
|
|
PUT SKIP EDIT('List of Primes up to ',NMAX) (A,F(8));
|
|
PUT SKIP EDIT(' ',2) (A,F(7));
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN DO;
|
|
PUT EDIT(' ',1+2*I) (A,F(7));
|
|
NP = NP + 1;
|
|
IF NP = 10 THEN DO;
|
|
PUT SKIP;
|
|
NP = 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF NP > 0 THEN PUT SKIP;
|
|
END;
|
|
|
|
IL = 4;
|
|
NL = 10;
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) = '1' THEN NP = NP + 1;
|
|
IF I = IL THEN DO;
|
|
NL = 2*IL + 2;
|
|
PUT SKIP EDIT('pi(',NL,'): ',NP) (A,F(8),A,F(8));
|
|
IL = 10*(IL+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF NL < NMAX THEN PUT SKIP EDIT('pi(',NMAX,'): ',NP)
|
|
(A,F(8),A,F(8));
|
|
|
|
DONE:;
|
|
|
|
END SOEP;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPSIMF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM=NOSUBCHK,
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
COMMENT
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end
|
|
* 2017-12-24 973 1.1 use WHILE not FOR to avoid compiler bug
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-09-17 951 1.0 Initial version
|
|
* 2017-09-08 949 0.1 First draft
|
|
*
|
|
* Note on SIMULA 67 (VERS 12.00) complier bug workaround
|
|
* - an inner loop codes as
|
|
* FOR i:= n2 // 2 STEP n UNTIL imax DO prime(i) := FALSE
|
|
* fails with 'FIXED POINT OVFL at line' of the FOR loop.
|
|
* - The equivalent WHILE loop used below works.
|
|
*;
|
|
|
|
BEGIN
|
|
INTEGER nmax,prnt,imax,nmsqrt;
|
|
INTEGER i,n,imin;
|
|
INTEGER np,il,nl;
|
|
BOOLEAN ARRAY prime(1:5000000);
|
|
|
|
nmax := InInt;
|
|
prnt := InInt;
|
|
|
|
IF nmax < 10 OR nmax > 10000000 THEN BEGIN
|
|
OutText("nmax out of range (10...10000000), abort");
|
|
GOTO done;
|
|
END;
|
|
|
|
nmsqrt := Entier(Sqrt(nmax));
|
|
imax := (nmax-1) // 2;
|
|
FOR i := 1 STEP 1 UNTIL imax DO prime(i) := TRUE;
|
|
|
|
FOR n := 3 STEP 2 UNTIL nmsqrt DO BEGIN
|
|
IF prime(n//2) THEN BEGIN
|
|
i := (n*n) // 2;
|
|
WHILE i <= imax DO BEGIN
|
|
prime(i) := FALSE;
|
|
i:= i + n;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF prnt > 0 THEN BEGIN
|
|
OutText("List of Primes up to ");
|
|
OutInt(nmax,8);
|
|
OutImage;
|
|
OutInt(2,8);
|
|
np := 1;
|
|
FOR i := 1 STEP 1 UNTIL imax DO BEGIN
|
|
IF prime(i) THEN BEGIN
|
|
OutInt(1+2*i,8);
|
|
np := np + 1;
|
|
IF np = 10 THEN BEGIN
|
|
OutImage;
|
|
np := 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF np > 0 THEN OutImage;
|
|
END;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
|
|
FOR i := 1 STEP 1 UNTIL imax DO BEGIN
|
|
IF prime(i) THEN np := np + 1;
|
|
IF i = il THEN BEGIN
|
|
nl := 2*il + 2;
|
|
OutText("pi(");
|
|
OutInt(nl,8);
|
|
OutText(")=");
|
|
OutInt(np,8);
|
|
OutImage;
|
|
il := 10*(il+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF nl < nmax THEN BEGIN
|
|
OutText("pi(");
|
|
OutInt(nmax,8);
|
|
OutText(")=");
|
|
OutInt(np,8);
|
|
OutImage;
|
|
END;
|
|
|
|
done:
|
|
OutImage;
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
10000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPSIMP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM=NOSUBCHK,
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
COMMENT
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end
|
|
* 2017-12-24 973 1.1 use WHILE not FOR to avoid compiler bug
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-09-17 951 1.0 Initial version
|
|
* 2017-09-08 949 0.1 First draft
|
|
*
|
|
* Note on SIMULA 67 (VERS 12.00) complier bug workaround
|
|
* - an inner loop codes as
|
|
* FOR i:= n2 // 2 STEP n UNTIL imax DO prime(i) := FALSE
|
|
* fails with 'FIXED POINT OVFL at line' of the FOR loop.
|
|
* - The equivalent WHILE loop used below works.
|
|
*;
|
|
|
|
BEGIN
|
|
INTEGER nmax,prnt,imax,nmsqrt;
|
|
INTEGER i,n,imin;
|
|
INTEGER np,il,nl;
|
|
BOOLEAN ARRAY prime(1:5000000);
|
|
|
|
nmax := InInt;
|
|
prnt := InInt;
|
|
|
|
IF nmax < 10 OR nmax > 10000000 THEN BEGIN
|
|
OutText("nmax out of range (10...10000000), abort");
|
|
GOTO done;
|
|
END;
|
|
|
|
nmsqrt := Entier(Sqrt(nmax));
|
|
imax := (nmax-1) // 2;
|
|
FOR i := 1 STEP 1 UNTIL imax DO prime(i) := TRUE;
|
|
|
|
FOR n := 3 STEP 2 UNTIL nmsqrt DO BEGIN
|
|
IF prime(n//2) THEN BEGIN
|
|
i := (n*n) // 2;
|
|
WHILE i <= imax DO BEGIN
|
|
prime(i) := FALSE;
|
|
i:= i + n;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF prnt > 0 THEN BEGIN
|
|
OutText("List of Primes up to ");
|
|
OutInt(nmax,8);
|
|
OutImage;
|
|
OutInt(2,8);
|
|
np := 1;
|
|
FOR i := 1 STEP 1 UNTIL imax DO BEGIN
|
|
IF prime(i) THEN BEGIN
|
|
OutInt(1+2*i,8);
|
|
np := np + 1;
|
|
IF np = 10 THEN BEGIN
|
|
OutImage;
|
|
np := 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF np > 0 THEN OutImage;
|
|
END;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
|
|
FOR i := 1 STEP 1 UNTIL imax DO BEGIN
|
|
IF prime(i) THEN np := np + 1;
|
|
IF i = il THEN BEGIN
|
|
nl := 2*il + 2;
|
|
OutText("pi(");
|
|
OutInt(nl,8);
|
|
OutText(")=");
|
|
OutInt(np,8);
|
|
OutImage;
|
|
il := 10*(il+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF nl < nmax THEN BEGIN
|
|
OutText("pi(");
|
|
OutInt(nmax,8);
|
|
OutText(")=");
|
|
OutInt(np,8);
|
|
OutImage;
|
|
END;
|
|
|
|
done:
|
|
OutImage;
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEPSIMT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEP#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
COMMENT
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end
|
|
* 2017-12-24 973 1.1 use WHILE not FOR to avoid compiler bug
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-09-17 951 1.0 Initial version
|
|
* 2017-09-08 949 0.1 First draft
|
|
*
|
|
* Note on SIMULA 67 (VERS 12.00) complier bug workaround
|
|
* - an inner loop codes as
|
|
* FOR i:= n2 // 2 STEP n UNTIL imax DO prime(i) := FALSE
|
|
* fails with 'FIXED POINT OVFL at line' of the FOR loop.
|
|
* - The equivalent WHILE loop used below works.
|
|
*;
|
|
|
|
BEGIN
|
|
INTEGER nmax,prnt,imax,nmsqrt;
|
|
INTEGER i,n,imin;
|
|
INTEGER np,il,nl;
|
|
BOOLEAN ARRAY prime(1:5000000);
|
|
|
|
nmax := InInt;
|
|
prnt := InInt;
|
|
|
|
IF nmax < 10 OR nmax > 10000000 THEN BEGIN
|
|
OutText("nmax out of range (10...10000000), abort");
|
|
GOTO done;
|
|
END;
|
|
|
|
nmsqrt := Entier(Sqrt(nmax));
|
|
imax := (nmax-1) // 2;
|
|
FOR i := 1 STEP 1 UNTIL imax DO prime(i) := TRUE;
|
|
|
|
FOR n := 3 STEP 2 UNTIL nmsqrt DO BEGIN
|
|
IF prime(n//2) THEN BEGIN
|
|
i := (n*n) // 2;
|
|
WHILE i <= imax DO BEGIN
|
|
prime(i) := FALSE;
|
|
i:= i + n;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF prnt > 0 THEN BEGIN
|
|
OutText("List of Primes up to ");
|
|
OutInt(nmax,8);
|
|
OutImage;
|
|
OutInt(2,8);
|
|
np := 1;
|
|
FOR i := 1 STEP 1 UNTIL imax DO BEGIN
|
|
IF prime(i) THEN BEGIN
|
|
OutInt(1+2*i,8);
|
|
np := np + 1;
|
|
IF np = 10 THEN BEGIN
|
|
OutImage;
|
|
np := 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF np > 0 THEN OutImage;
|
|
END;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
|
|
FOR i := 1 STEP 1 UNTIL imax DO BEGIN
|
|
IF prime(i) THEN np := np + 1;
|
|
IF i = il THEN BEGIN
|
|
nl := 2*il + 2;
|
|
OutText("pi(");
|
|
OutInt(nl,8);
|
|
OutText(")=");
|
|
OutInt(np,8);
|
|
OutImage;
|
|
il := 10*(il+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF nl < nmax THEN BEGIN
|
|
OutText("pi(");
|
|
OutInt(nmax,8);
|
|
OutText(")=");
|
|
OutInt(np,8);
|
|
OutImage;
|
|
END;
|
|
|
|
done:
|
|
OutImage;
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQASMF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6500K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NOLIST,NOXREF,NORLD,NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: soeq_asm.asm 972 2017-12-23 20:55:41Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-11-19 965 1.1 no XR in inner loop, bit reversed prime[]
|
|
* 2017-11-18 963 1.0 Initial version
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Prime number search
|
|
* RC = 0 ok
|
|
* RC = 4 open SYSPRINT failed
|
|
* RC = 8 open SYSIN failed
|
|
* RC = 12 unexpected SYSIN EOF
|
|
* RC = 16 NMAX out of range
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'04'
|
|
B EXIT quit with RC=4
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'08'
|
|
B EXIT quit with RC=8
|
|
IOPENOK EQU *
|
|
*
|
|
* read input parameters, and check range ------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get NMAX
|
|
ST R1,NMAX
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,PRNT
|
|
*
|
|
L R1,NMAX
|
|
C R1,=F'10' is NMAX >= 10
|
|
BL NMAXBAD if < not
|
|
C R1,=F'100000000' is NMAX <= 100000000
|
|
BNH NMAXOK if <= yes
|
|
NMAXBAD L R1,MSGPERR
|
|
BAL R14,OTEXT print error
|
|
BAL R14,OPUTLINE write line
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
NMAXOK EQU *
|
|
*
|
|
* setup phase ---------------------------------------------------------
|
|
*
|
|
* calculate sqrt(nmax) -----------------------------------
|
|
* use simple bi-section method
|
|
* R4 low bound
|
|
* R5 high bound
|
|
* R7 middle (low+high)/2
|
|
*
|
|
LA R4,1 set low bound
|
|
L R5,NMAX set high bound
|
|
LA R6,32 set iteration limit
|
|
NMSQRTLP LR R7,R4 R7:= low
|
|
AR R7,R5 R7:= (low+high)
|
|
SRA R7,1 R7:= (low+high)/2
|
|
LR R3,R7
|
|
MR R2,R7 (R2,R3) := R7*R7
|
|
LTR R2,R2 more than 32 bit ?
|
|
BNE NMSQRTHI if != yes, mid too high
|
|
CL R3,NMAX mid*mid > NMAX
|
|
BH NMSQRTHI if > yes, mid too high
|
|
LR R4,R7 here mid to low: low := mid
|
|
B NMSQRTGO
|
|
NMSQRTHI LR R5,R7 here mid to high: high := mid
|
|
NMSQRTGO LR R8,R5 R8 := high
|
|
SR R8,R4 R8 := high-low
|
|
LR R1,R6
|
|
C R8,=F'1' spread <= 1 ?
|
|
BNH NMSQRTOK if <= yes, quit
|
|
BCT R6,NMSQRTLP
|
|
ABEND 99 abort if doesn't converge
|
|
NMSQRTOK EQU *
|
|
ST R4,NMSQRT
|
|
|
|
* allocate PRIME array -----------------------------------
|
|
L R2,NMAX
|
|
BCTR R2,0 NMAX-1
|
|
SRA R2,1 (NMAX-1)/2
|
|
ST R2,BIMAX
|
|
A R2,=F'7' BIMAX+7
|
|
SRA R2,3 (BIMAX+7)/8
|
|
ST R2,WIMAX
|
|
LR R5,R2
|
|
A R5,=F'1' WIMAX+1
|
|
GETMAIN RU,LV=(5) allocate storage for PRIME
|
|
ST R1,PRIME store sieve base
|
|
LR R9,R1 R9 := PRIME base
|
|
*
|
|
* set each PRIME array byte to X'01' ---------------------
|
|
LR R4,R1 R4 := PRIME
|
|
* R5 := sizeof(PRIME) (still)
|
|
XR R6,R6 R6 := 0
|
|
L R7,=X'FF000000' R7 := padding=0xFF and length=0
|
|
MVCL R4,R6 set all PRIME words to 0xFFFF
|
|
*
|
|
* sieve phase ---------------------------------------------------------
|
|
* outer loop: ind R6 n
|
|
* inc R4 2
|
|
* lim R5 sqrt(NMAX)
|
|
* inner loop: ind R3 i
|
|
* inc R6 n
|
|
* lim R7 bimax
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 0xFF7F
|
|
* R0,R1,R2,R15 temporaries
|
|
*
|
|
*
|
|
* equivalent C code:
|
|
* for (n=3; n<=nmsqrt; n+=2) {
|
|
* i = n/2;
|
|
* if ((prime[i>>3] & (0x80>>(i&0x7))) == 0) continue;
|
|
* for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
* prime[i>>3] &= (0xff7f>>(i&0x7); '!!pseudo code !!'
|
|
* }
|
|
* }
|
|
*
|
|
LA R6,3 outer ind: R6:=3
|
|
LA R4,2 outer inc: R4:=2
|
|
L R5,NMSQRT outer lim: R5:=NMSQRT
|
|
L R7,BIMAX inner lim: R7:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
L R11,=X'FFFFFF7F' R11:=0xffffff7f
|
|
*
|
|
SIEVO LR R2,R6 R2:=n
|
|
SRA R2,1 R2:=n/2
|
|
LR R15,R2 i
|
|
NR R15,R10 i&0x07
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R15) 0x80>>(i&0x7)
|
|
SRL R2,3 i>>3
|
|
IC R2,0(R2,R9) prime[i>>3]
|
|
NR R2,R1 prime[i>>3] & (0x80>>(i&0x7))
|
|
BZ SIEVOC if =0 not, continue outer loop
|
|
*
|
|
LR R1,R6 R1:=n
|
|
MR R0,R6 R1:=n*n (lower half, enough)
|
|
LR R3,R1 R3:=n*n too
|
|
SRA R3,1 R3:=(n*n)/2
|
|
*
|
|
SIEVI LR R2,R3 i
|
|
NR R2,R10 i&0x7
|
|
LR R1,R11 0xff7f
|
|
SRL R1,0(R2) 0xff7f>>(i&0x7)
|
|
LR R2,R3 i
|
|
SRL R2,3 i>>3
|
|
IC R0,0(R2,R9) prime[i>>3]
|
|
NR R0,R1 & 0xff7f>>(i&0x7)
|
|
STC R0,0(R2,R9) prime[i>>3] &= 0xff7f>>(i&0x7)
|
|
BXLE R3,R6,SIEVI
|
|
*
|
|
SIEVOC BXLE R6,R4,SIEVO
|
|
*
|
|
* print primes table --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 1
|
|
PRT EQU *
|
|
CLI PRNT,X'00' primes to be printed ?
|
|
BE NOPRNT if = skip
|
|
L R1,MSGLIST
|
|
BAL R14,OTEXT print heading
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LA R1,2
|
|
BAL R14,OINT10 print "2" (1st prime...)
|
|
LA R2,1 np=1
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,BIMAX lim: R5:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
LA R11,1 R11:=1
|
|
PRTLOOP LR R6,R3 i
|
|
NR R6,R10 i&0x7
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R6) 0x80>>(i&0x7)
|
|
LR R6,R3 i
|
|
SRL R6,3 i>>3
|
|
IC R0,0(R6,R9) prime[i>>3]
|
|
NR R0,R1 prime[i>>3] & (0x80>>(i&0x7))
|
|
BE PRTLOOPC if = not, continue
|
|
LR R1,R3 R1:=i
|
|
SLA R1,1 R1:=2*i
|
|
AR R1,R11 R1:=1+2*i
|
|
BAL R14,OINT10 and print F(10)
|
|
AR R2,R11 np+=1
|
|
C R2,=F'10' check whether = 10
|
|
BNZ PRTLOOPC if != not, continue
|
|
BAL R14,OPUTLINE write line
|
|
XR R2,R2 np=0
|
|
PRTLOOPC EQU *
|
|
BXLE R3,R4,PRTLOOP
|
|
*
|
|
LTR R2,R2 check prime count np
|
|
BZ NOPRNT
|
|
BAL R14,OPUTLINE write line
|
|
NOPRNT EQU *
|
|
*
|
|
* print primes count --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R7 il
|
|
* R6 nl
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 1
|
|
*
|
|
TBL EQU *
|
|
LA R2,1 np=1
|
|
LA R7,4 il=4
|
|
LA R6,10 nl=10
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,BIMAX lim: R5:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
LA R11,1 R11:=1
|
|
TBLLOOP LR R15,R3 i
|
|
NR R15,R10 i&0x7
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R15) 0x80>>(i&0x7)
|
|
LR R15,R3 i
|
|
SRL R15,3 i>>3
|
|
IC R0,0(R15,R9) prime[i>>3]
|
|
NR R0,R1 prime[i>>3] & (1<<(i&0x7))
|
|
BE NOPRIME if = not
|
|
AR R2,R11 np+= 1
|
|
NOPRIME CR R3,R7 test i != il
|
|
BNE TBLLOOPC
|
|
LR R6,R7 nl=il
|
|
SLA R6,1 nl=2*il
|
|
A R6,=F'2' nl=2+2*il
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
LR R1,R6
|
|
BAL R14,OINT10 print nl
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LR R1,R7 R1:=il
|
|
AR R1,R11 R1:=il+1
|
|
M R0,=F'10' R1:=10*(il+1)
|
|
SR R1,R11 R1:=10*(il+1)-1
|
|
LR R7,R1 update il
|
|
*
|
|
TBLLOOPC EQU *
|
|
BXLE R3,R4,TBLLOOP
|
|
*
|
|
C R6,NMAX is nl != nmax ?
|
|
BE TBLNOTR if = not, skip extra summary
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
TBLNOTR EQU *
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R13,SAVE+4 get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT10 ---------------------------------------------------
|
|
* read integer, like PL/I F(10) or C %10d format
|
|
*
|
|
IINT10 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(10,R15) pack next 10 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,10(R15) push pointer by 10 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
SAVE DS 18F local save area
|
|
RC DC F'0' return code
|
|
NMAX DC F'10000000' highest prime to search for
|
|
NMSQRT DS F sqrt(NMAX)
|
|
BIMAX DS F highest prime array bit index
|
|
WIMAX DS F highest prime array word index
|
|
PRIME DS F prime array pointer
|
|
PRNT DC X'00' print enable flag
|
|
*
|
|
* message strings
|
|
*
|
|
MSGPERR OTXTDSC C'NMAX must be >= 10 and <= 100000000, abort'
|
|
MSGLIST OTXTDSC C'List of Primes up to '
|
|
MSGPI OTXTDSC C'pi('
|
|
MSGPISEP OTXTDSC C'): '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQASMP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=650K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NOLIST,NOXREF,NORLD,NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: soeq_asm.asm 972 2017-12-23 20:55:41Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-11-19 965 1.1 no XR in inner loop, bit reversed prime[]
|
|
* 2017-11-18 963 1.0 Initial version
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Prime number search
|
|
* RC = 0 ok
|
|
* RC = 4 open SYSPRINT failed
|
|
* RC = 8 open SYSIN failed
|
|
* RC = 12 unexpected SYSIN EOF
|
|
* RC = 16 NMAX out of range
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'04'
|
|
B EXIT quit with RC=4
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'08'
|
|
B EXIT quit with RC=8
|
|
IOPENOK EQU *
|
|
*
|
|
* read input parameters, and check range ------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get NMAX
|
|
ST R1,NMAX
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,PRNT
|
|
*
|
|
L R1,NMAX
|
|
C R1,=F'10' is NMAX >= 10
|
|
BL NMAXBAD if < not
|
|
C R1,=F'100000000' is NMAX <= 100000000
|
|
BNH NMAXOK if <= yes
|
|
NMAXBAD L R1,MSGPERR
|
|
BAL R14,OTEXT print error
|
|
BAL R14,OPUTLINE write line
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
NMAXOK EQU *
|
|
*
|
|
* setup phase ---------------------------------------------------------
|
|
*
|
|
* calculate sqrt(nmax) -----------------------------------
|
|
* use simple bi-section method
|
|
* R4 low bound
|
|
* R5 high bound
|
|
* R7 middle (low+high)/2
|
|
*
|
|
LA R4,1 set low bound
|
|
L R5,NMAX set high bound
|
|
LA R6,32 set iteration limit
|
|
NMSQRTLP LR R7,R4 R7:= low
|
|
AR R7,R5 R7:= (low+high)
|
|
SRA R7,1 R7:= (low+high)/2
|
|
LR R3,R7
|
|
MR R2,R7 (R2,R3) := R7*R7
|
|
LTR R2,R2 more than 32 bit ?
|
|
BNE NMSQRTHI if != yes, mid too high
|
|
CL R3,NMAX mid*mid > NMAX
|
|
BH NMSQRTHI if > yes, mid too high
|
|
LR R4,R7 here mid to low: low := mid
|
|
B NMSQRTGO
|
|
NMSQRTHI LR R5,R7 here mid to high: high := mid
|
|
NMSQRTGO LR R8,R5 R8 := high
|
|
SR R8,R4 R8 := high-low
|
|
LR R1,R6
|
|
C R8,=F'1' spread <= 1 ?
|
|
BNH NMSQRTOK if <= yes, quit
|
|
BCT R6,NMSQRTLP
|
|
ABEND 99 abort if doesn't converge
|
|
NMSQRTOK EQU *
|
|
ST R4,NMSQRT
|
|
|
|
* allocate PRIME array -----------------------------------
|
|
L R2,NMAX
|
|
BCTR R2,0 NMAX-1
|
|
SRA R2,1 (NMAX-1)/2
|
|
ST R2,BIMAX
|
|
A R2,=F'7' BIMAX+7
|
|
SRA R2,3 (BIMAX+7)/8
|
|
ST R2,WIMAX
|
|
LR R5,R2
|
|
A R5,=F'1' WIMAX+1
|
|
GETMAIN RU,LV=(5) allocate storage for PRIME
|
|
ST R1,PRIME store sieve base
|
|
LR R9,R1 R9 := PRIME base
|
|
*
|
|
* set each PRIME array byte to X'01' ---------------------
|
|
LR R4,R1 R4 := PRIME
|
|
* R5 := sizeof(PRIME) (still)
|
|
XR R6,R6 R6 := 0
|
|
L R7,=X'FF000000' R7 := padding=0xFF and length=0
|
|
MVCL R4,R6 set all PRIME words to 0xFFFF
|
|
*
|
|
* sieve phase ---------------------------------------------------------
|
|
* outer loop: ind R6 n
|
|
* inc R4 2
|
|
* lim R5 sqrt(NMAX)
|
|
* inner loop: ind R3 i
|
|
* inc R6 n
|
|
* lim R7 bimax
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 0xFF7F
|
|
* R0,R1,R2,R15 temporaries
|
|
*
|
|
*
|
|
* equivalent C code:
|
|
* for (n=3; n<=nmsqrt; n+=2) {
|
|
* i = n/2;
|
|
* if ((prime[i>>3] & (0x80>>(i&0x7))) == 0) continue;
|
|
* for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
* prime[i>>3] &= (0xff7f>>(i&0x7); '!!pseudo code !!'
|
|
* }
|
|
* }
|
|
*
|
|
LA R6,3 outer ind: R6:=3
|
|
LA R4,2 outer inc: R4:=2
|
|
L R5,NMSQRT outer lim: R5:=NMSQRT
|
|
L R7,BIMAX inner lim: R7:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
L R11,=X'FFFFFF7F' R11:=0xffffff7f
|
|
*
|
|
SIEVO LR R2,R6 R2:=n
|
|
SRA R2,1 R2:=n/2
|
|
LR R15,R2 i
|
|
NR R15,R10 i&0x07
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R15) 0x80>>(i&0x7)
|
|
SRL R2,3 i>>3
|
|
IC R2,0(R2,R9) prime[i>>3]
|
|
NR R2,R1 prime[i>>3] & (0x80>>(i&0x7))
|
|
BZ SIEVOC if =0 not, continue outer loop
|
|
*
|
|
LR R1,R6 R1:=n
|
|
MR R0,R6 R1:=n*n (lower half, enough)
|
|
LR R3,R1 R3:=n*n too
|
|
SRA R3,1 R3:=(n*n)/2
|
|
*
|
|
SIEVI LR R2,R3 i
|
|
NR R2,R10 i&0x7
|
|
LR R1,R11 0xff7f
|
|
SRL R1,0(R2) 0xff7f>>(i&0x7)
|
|
LR R2,R3 i
|
|
SRL R2,3 i>>3
|
|
IC R0,0(R2,R9) prime[i>>3]
|
|
NR R0,R1 & 0xff7f>>(i&0x7)
|
|
STC R0,0(R2,R9) prime[i>>3] &= 0xff7f>>(i&0x7)
|
|
BXLE R3,R6,SIEVI
|
|
*
|
|
SIEVOC BXLE R6,R4,SIEVO
|
|
*
|
|
* print primes table --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 1
|
|
PRT EQU *
|
|
CLI PRNT,X'00' primes to be printed ?
|
|
BE NOPRNT if = skip
|
|
L R1,MSGLIST
|
|
BAL R14,OTEXT print heading
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LA R1,2
|
|
BAL R14,OINT10 print "2" (1st prime...)
|
|
LA R2,1 np=1
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,BIMAX lim: R5:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
LA R11,1 R11:=1
|
|
PRTLOOP LR R6,R3 i
|
|
NR R6,R10 i&0x7
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R6) 0x80>>(i&0x7)
|
|
LR R6,R3 i
|
|
SRL R6,3 i>>3
|
|
IC R0,0(R6,R9) prime[i>>3]
|
|
NR R0,R1 prime[i>>3] & (0x80>>(i&0x7))
|
|
BE PRTLOOPC if = not, continue
|
|
LR R1,R3 R1:=i
|
|
SLA R1,1 R1:=2*i
|
|
AR R1,R11 R1:=1+2*i
|
|
BAL R14,OINT10 and print F(10)
|
|
AR R2,R11 np+=1
|
|
C R2,=F'10' check whether = 10
|
|
BNZ PRTLOOPC if != not, continue
|
|
BAL R14,OPUTLINE write line
|
|
XR R2,R2 np=0
|
|
PRTLOOPC EQU *
|
|
BXLE R3,R4,PRTLOOP
|
|
*
|
|
LTR R2,R2 check prime count np
|
|
BZ NOPRNT
|
|
BAL R14,OPUTLINE write line
|
|
NOPRNT EQU *
|
|
*
|
|
* print primes count --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R7 il
|
|
* R6 nl
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 1
|
|
*
|
|
TBL EQU *
|
|
LA R2,1 np=1
|
|
LA R7,4 il=4
|
|
LA R6,10 nl=10
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,BIMAX lim: R5:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
LA R11,1 R11:=1
|
|
TBLLOOP LR R15,R3 i
|
|
NR R15,R10 i&0x7
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R15) 0x80>>(i&0x7)
|
|
LR R15,R3 i
|
|
SRL R15,3 i>>3
|
|
IC R0,0(R15,R9) prime[i>>3]
|
|
NR R0,R1 prime[i>>3] & (1<<(i&0x7))
|
|
BE NOPRIME if = not
|
|
AR R2,R11 np+= 1
|
|
NOPRIME CR R3,R7 test i != il
|
|
BNE TBLLOOPC
|
|
LR R6,R7 nl=il
|
|
SLA R6,1 nl=2*il
|
|
A R6,=F'2' nl=2+2*il
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
LR R1,R6
|
|
BAL R14,OINT10 print nl
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LR R1,R7 R1:=il
|
|
AR R1,R11 R1:=il+1
|
|
M R0,=F'10' R1:=10*(il+1)
|
|
SR R1,R11 R1:=10*(il+1)-1
|
|
LR R7,R1 update il
|
|
*
|
|
TBLLOOPC EQU *
|
|
BXLE R3,R4,TBLLOOP
|
|
*
|
|
C R6,NMAX is nl != nmax ?
|
|
BE TBLNOTR if = not, skip extra summary
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
TBLNOTR EQU *
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R13,SAVE+4 get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT10 ---------------------------------------------------
|
|
* read integer, like PL/I F(10) or C %10d format
|
|
*
|
|
IINT10 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(10,R15) pack next 10 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,10(R15) push pointer by 10 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
SAVE DS 18F local save area
|
|
RC DC F'0' return code
|
|
NMAX DC F'10000000' highest prime to search for
|
|
NMSQRT DS F sqrt(NMAX)
|
|
BIMAX DS F highest prime array bit index
|
|
WIMAX DS F highest prime array word index
|
|
PRIME DS F prime array pointer
|
|
PRNT DC X'00' print enable flag
|
|
*
|
|
* message strings
|
|
*
|
|
MSGPERR OTXTDSC C'NMAX must be >= 10 and <= 100000000, abort'
|
|
MSGLIST OTXTDSC C'List of Primes up to '
|
|
MSGPI OTXTDSC C'pi('
|
|
MSGPISEP OTXTDSC C'): '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQASMT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=128K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: soeq_asm.asm 972 2017-12-23 20:55:41Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2
|
|
* 2017-11-19 965 1.1 no XR in inner loop, bit reversed prime[]
|
|
* 2017-11-18 963 1.0 Initial version
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Prime number search
|
|
* RC = 0 ok
|
|
* RC = 4 open SYSPRINT failed
|
|
* RC = 8 open SYSIN failed
|
|
* RC = 12 unexpected SYSIN EOF
|
|
* RC = 16 NMAX out of range
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'04'
|
|
B EXIT quit with RC=4
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'08'
|
|
B EXIT quit with RC=8
|
|
IOPENOK EQU *
|
|
*
|
|
* read input parameters, and check range ------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get NMAX
|
|
ST R1,NMAX
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,PRNT
|
|
*
|
|
L R1,NMAX
|
|
C R1,=F'10' is NMAX >= 10
|
|
BL NMAXBAD if < not
|
|
C R1,=F'100000000' is NMAX <= 100000000
|
|
BNH NMAXOK if <= yes
|
|
NMAXBAD L R1,MSGPERR
|
|
BAL R14,OTEXT print error
|
|
BAL R14,OPUTLINE write line
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
NMAXOK EQU *
|
|
*
|
|
* setup phase ---------------------------------------------------------
|
|
*
|
|
* calculate sqrt(nmax) -----------------------------------
|
|
* use simple bi-section method
|
|
* R4 low bound
|
|
* R5 high bound
|
|
* R7 middle (low+high)/2
|
|
*
|
|
LA R4,1 set low bound
|
|
L R5,NMAX set high bound
|
|
LA R6,32 set iteration limit
|
|
NMSQRTLP LR R7,R4 R7:= low
|
|
AR R7,R5 R7:= (low+high)
|
|
SRA R7,1 R7:= (low+high)/2
|
|
LR R3,R7
|
|
MR R2,R7 (R2,R3) := R7*R7
|
|
LTR R2,R2 more than 32 bit ?
|
|
BNE NMSQRTHI if != yes, mid too high
|
|
CL R3,NMAX mid*mid > NMAX
|
|
BH NMSQRTHI if > yes, mid too high
|
|
LR R4,R7 here mid to low: low := mid
|
|
B NMSQRTGO
|
|
NMSQRTHI LR R5,R7 here mid to high: high := mid
|
|
NMSQRTGO LR R8,R5 R8 := high
|
|
SR R8,R4 R8 := high-low
|
|
LR R1,R6
|
|
C R8,=F'1' spread <= 1 ?
|
|
BNH NMSQRTOK if <= yes, quit
|
|
BCT R6,NMSQRTLP
|
|
ABEND 99 abort if doesn't converge
|
|
NMSQRTOK EQU *
|
|
ST R4,NMSQRT
|
|
|
|
* allocate PRIME array -----------------------------------
|
|
L R2,NMAX
|
|
BCTR R2,0 NMAX-1
|
|
SRA R2,1 (NMAX-1)/2
|
|
ST R2,BIMAX
|
|
A R2,=F'7' BIMAX+7
|
|
SRA R2,3 (BIMAX+7)/8
|
|
ST R2,WIMAX
|
|
LR R5,R2
|
|
A R5,=F'1' WIMAX+1
|
|
GETMAIN RU,LV=(5) allocate storage for PRIME
|
|
ST R1,PRIME store sieve base
|
|
LR R9,R1 R9 := PRIME base
|
|
*
|
|
* set each PRIME array byte to X'01' ---------------------
|
|
LR R4,R1 R4 := PRIME
|
|
* R5 := sizeof(PRIME) (still)
|
|
XR R6,R6 R6 := 0
|
|
L R7,=X'FF000000' R7 := padding=0xFF and length=0
|
|
MVCL R4,R6 set all PRIME words to 0xFFFF
|
|
*
|
|
* sieve phase ---------------------------------------------------------
|
|
* outer loop: ind R6 n
|
|
* inc R4 2
|
|
* lim R5 sqrt(NMAX)
|
|
* inner loop: ind R3 i
|
|
* inc R6 n
|
|
* lim R7 bimax
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 0xFF7F
|
|
* R0,R1,R2,R15 temporaries
|
|
*
|
|
*
|
|
* equivalent C code:
|
|
* for (n=3; n<=nmsqrt; n+=2) {
|
|
* i = n/2;
|
|
* if ((prime[i>>3] & (0x80>>(i&0x7))) == 0) continue;
|
|
* for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
* prime[i>>3] &= (0xff7f>>(i&0x7); '!!pseudo code !!'
|
|
* }
|
|
* }
|
|
*
|
|
LA R6,3 outer ind: R6:=3
|
|
LA R4,2 outer inc: R4:=2
|
|
L R5,NMSQRT outer lim: R5:=NMSQRT
|
|
L R7,BIMAX inner lim: R7:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
L R11,=X'FFFFFF7F' R11:=0xffffff7f
|
|
*
|
|
SIEVO LR R2,R6 R2:=n
|
|
SRA R2,1 R2:=n/2
|
|
LR R15,R2 i
|
|
NR R15,R10 i&0x07
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R15) 0x80>>(i&0x7)
|
|
SRL R2,3 i>>3
|
|
IC R2,0(R2,R9) prime[i>>3]
|
|
NR R2,R1 prime[i>>3] & (0x80>>(i&0x7))
|
|
BZ SIEVOC if =0 not, continue outer loop
|
|
*
|
|
LR R1,R6 R1:=n
|
|
MR R0,R6 R1:=n*n (lower half, enough)
|
|
LR R3,R1 R3:=n*n too
|
|
SRA R3,1 R3:=(n*n)/2
|
|
*
|
|
SIEVI LR R2,R3 i
|
|
NR R2,R10 i&0x7
|
|
LR R1,R11 0xff7f
|
|
SRL R1,0(R2) 0xff7f>>(i&0x7)
|
|
LR R2,R3 i
|
|
SRL R2,3 i>>3
|
|
IC R0,0(R2,R9) prime[i>>3]
|
|
NR R0,R1 & 0xff7f>>(i&0x7)
|
|
STC R0,0(R2,R9) prime[i>>3] &= 0xff7f>>(i&0x7)
|
|
BXLE R3,R6,SIEVI
|
|
*
|
|
SIEVOC BXLE R6,R4,SIEVO
|
|
*
|
|
* print primes table --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 1
|
|
PRT EQU *
|
|
CLI PRNT,X'00' primes to be printed ?
|
|
BE NOPRNT if = skip
|
|
L R1,MSGLIST
|
|
BAL R14,OTEXT print heading
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LA R1,2
|
|
BAL R14,OINT10 print "2" (1st prime...)
|
|
LA R2,1 np=1
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,BIMAX lim: R5:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
LA R11,1 R11:=1
|
|
PRTLOOP LR R6,R3 i
|
|
NR R6,R10 i&0x7
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R6) 0x80>>(i&0x7)
|
|
LR R6,R3 i
|
|
SRL R6,3 i>>3
|
|
IC R0,0(R6,R9) prime[i>>3]
|
|
NR R0,R1 prime[i>>3] & (0x80>>(i&0x7))
|
|
BE PRTLOOPC if = not, continue
|
|
LR R1,R3 R1:=i
|
|
SLA R1,1 R1:=2*i
|
|
AR R1,R11 R1:=1+2*i
|
|
BAL R14,OINT10 and print F(10)
|
|
AR R2,R11 np+=1
|
|
C R2,=F'10' check whether = 10
|
|
BNZ PRTLOOPC if != not, continue
|
|
BAL R14,OPUTLINE write line
|
|
XR R2,R2 np=0
|
|
PRTLOOPC EQU *
|
|
BXLE R3,R4,PRTLOOP
|
|
*
|
|
LTR R2,R2 check prime count np
|
|
BZ NOPRNT
|
|
BAL R14,OPUTLINE write line
|
|
NOPRNT EQU *
|
|
*
|
|
* print primes count --------------------------------------------------
|
|
* loop: ind R3 i
|
|
* inc R4 1
|
|
* lim R5 imax
|
|
* R2 np
|
|
* R7 il
|
|
* R6 nl
|
|
* R9 &prime
|
|
* R8 0x80
|
|
* R10 0x07
|
|
* R11 1
|
|
*
|
|
TBL EQU *
|
|
LA R2,1 np=1
|
|
LA R7,4 il=4
|
|
LA R6,10 nl=10
|
|
LA R3,1 ind: R3:=1
|
|
LA R4,1 inc: R4:=1
|
|
L R5,BIMAX lim: R5:=BIMAX
|
|
LA R8,X'80' R8:=0x80
|
|
LA R10,X'07' R10:=0x07
|
|
LA R11,1 R11:=1
|
|
TBLLOOP LR R15,R3 i
|
|
NR R15,R10 i&0x7
|
|
LR R1,R8 0x80
|
|
SRL R1,0(R15) 0x80>>(i&0x7)
|
|
LR R15,R3 i
|
|
SRL R15,3 i>>3
|
|
IC R0,0(R15,R9) prime[i>>3]
|
|
NR R0,R1 prime[i>>3] & (1<<(i&0x7))
|
|
BE NOPRIME if = not
|
|
AR R2,R11 np+= 1
|
|
NOPRIME CR R3,R7 test i != il
|
|
BNE TBLLOOPC
|
|
LR R6,R7 nl=il
|
|
SLA R6,1 nl=2*il
|
|
A R6,=F'2' nl=2+2*il
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
LR R1,R6
|
|
BAL R14,OINT10 print nl
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
LR R1,R7 R1:=il
|
|
AR R1,R11 R1:=il+1
|
|
M R0,=F'10' R1:=10*(il+1)
|
|
SR R1,R11 R1:=10*(il+1)-1
|
|
LR R7,R1 update il
|
|
*
|
|
TBLLOOPC EQU *
|
|
BXLE R3,R4,TBLLOOP
|
|
*
|
|
C R6,NMAX is nl != nmax ?
|
|
BE TBLNOTR if = not, skip extra summary
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "pi(...."
|
|
L R1,NMAX
|
|
BAL R14,OINT10 print nmax
|
|
L R1,MSGPISEP
|
|
BAL R14,OTEXT print "):..."
|
|
LR R1,R2
|
|
BAL R14,OINT10 print np
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
TBLNOTR EQU *
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R13,SAVE+4 get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT10 ---------------------------------------------------
|
|
* read integer, like PL/I F(10) or C %10d format
|
|
*
|
|
IINT10 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(10,R15) pack next 10 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,10(R15) push pointer by 10 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
SAVE DS 18F local save area
|
|
RC DC F'0' return code
|
|
NMAX DC F'10000000' highest prime to search for
|
|
NMSQRT DS F sqrt(NMAX)
|
|
BIMAX DS F highest prime array bit index
|
|
WIMAX DS F highest prime array word index
|
|
PRIME DS F prime array pointer
|
|
PRNT DC X'00' print enable flag
|
|
*
|
|
* message strings
|
|
*
|
|
MSGPERR OTXTDSC C'NMAX must be >= 10 and <= 100000000, abort'
|
|
MSGLIST OTXTDSC C'List of Primes up to '
|
|
MSGPI OTXTDSC C'pi('
|
|
MSGPISEP OTXTDSC C'): '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQGCCF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=7000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soeq_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.1.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-11-20 966 1.1 add LOOKUP,STATISTICS ifdefs */
|
|
/* 2017-11-17 962 1.0 Initial version */
|
|
/* 2017-10-15 956 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
/* #define LOOKUP */
|
|
/* #define STATISTICS */
|
|
|
|
#ifdef LOOKUP
|
|
#define TSTMASK(ind) tstmask[ind]
|
|
#define CLRMASK(ind) clrmask[ind]
|
|
const unsigned char tstmask[] = {0x01,0x02,0x04,0x08,
|
|
0x10,0x20,0x40,0x80};
|
|
const unsigned char clrmask[] = {0xfe,0xfd,0xfb,0xf7,
|
|
0xef,0xdf,0xbf,0x7f};
|
|
|
|
#else
|
|
#define TSTMASK(ind) (1<<(ind))
|
|
#define CLRMASK(ind) ~(1<<(ind))
|
|
#endif
|
|
|
|
#ifdef STATISTICS
|
|
#define SCOUNT(var) var += 1;
|
|
double StatOloop = 0.;
|
|
double StatIloop = 0.;
|
|
#else
|
|
#define SCOUNT(var)
|
|
#endif
|
|
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int bimax;
|
|
int wimax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
unsigned char *prime;
|
|
unsigned char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
bimax = (nmax-1)/2;
|
|
wimax = (bimax+7)/8;
|
|
prime = malloc(sizeof(char)*(wimax+1)); /* need [1,...,wimax] */
|
|
pmax = &prime[wimax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 0xff;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
i = n/2;
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
SCOUNT(StatOloop);
|
|
for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
prime[i>>3] &= CLRMASK(i&0x7);
|
|
SCOUNT(StatIloop);
|
|
}
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7))) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
#ifdef STATISTICS
|
|
printf("StatOloop: %20.0f\n",StatOloop);
|
|
printf("StatIloop: %20.0f\n",StatIloop);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQGCCP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soeq_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.1.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-11-20 966 1.1 add LOOKUP,STATISTICS ifdefs */
|
|
/* 2017-11-17 962 1.0 Initial version */
|
|
/* 2017-10-15 956 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
/* #define LOOKUP */
|
|
/* #define STATISTICS */
|
|
|
|
#ifdef LOOKUP
|
|
#define TSTMASK(ind) tstmask[ind]
|
|
#define CLRMASK(ind) clrmask[ind]
|
|
const unsigned char tstmask[] = {0x01,0x02,0x04,0x08,
|
|
0x10,0x20,0x40,0x80};
|
|
const unsigned char clrmask[] = {0xfe,0xfd,0xfb,0xf7,
|
|
0xef,0xdf,0xbf,0x7f};
|
|
|
|
#else
|
|
#define TSTMASK(ind) (1<<(ind))
|
|
#define CLRMASK(ind) ~(1<<(ind))
|
|
#endif
|
|
|
|
#ifdef STATISTICS
|
|
#define SCOUNT(var) var += 1;
|
|
double StatOloop = 0.;
|
|
double StatIloop = 0.;
|
|
#else
|
|
#define SCOUNT(var)
|
|
#endif
|
|
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int bimax;
|
|
int wimax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
unsigned char *prime;
|
|
unsigned char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
bimax = (nmax-1)/2;
|
|
wimax = (bimax+7)/8;
|
|
prime = malloc(sizeof(char)*(wimax+1)); /* need [1,...,wimax] */
|
|
pmax = &prime[wimax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 0xff;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
i = n/2;
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
SCOUNT(StatOloop);
|
|
for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
prime[i>>3] &= CLRMASK(i&0x7);
|
|
SCOUNT(StatIloop);
|
|
}
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7))) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
#ifdef STATISTICS
|
|
printf("StatOloop: %20.0f\n",StatOloop);
|
|
printf("StatIloop: %20.0f\n",StatIloop);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQGCCT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=6000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soeq_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.1.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-11-20 966 1.1 add LOOKUP,STATISTICS ifdefs */
|
|
/* 2017-11-17 962 1.0 Initial version */
|
|
/* 2017-10-15 956 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
/* #define LOOKUP */
|
|
/* #define STATISTICS */
|
|
|
|
#ifdef LOOKUP
|
|
#define TSTMASK(ind) tstmask[ind]
|
|
#define CLRMASK(ind) clrmask[ind]
|
|
const unsigned char tstmask[] = {0x01,0x02,0x04,0x08,
|
|
0x10,0x20,0x40,0x80};
|
|
const unsigned char clrmask[] = {0xfe,0xfd,0xfb,0xf7,
|
|
0xef,0xdf,0xbf,0x7f};
|
|
|
|
#else
|
|
#define TSTMASK(ind) (1<<(ind))
|
|
#define CLRMASK(ind) ~(1<<(ind))
|
|
#endif
|
|
|
|
#ifdef STATISTICS
|
|
#define SCOUNT(var) var += 1;
|
|
double StatOloop = 0.;
|
|
double StatIloop = 0.;
|
|
#else
|
|
#define SCOUNT(var)
|
|
#endif
|
|
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int bimax;
|
|
int wimax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
unsigned char *prime;
|
|
unsigned char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
bimax = (nmax-1)/2;
|
|
wimax = (bimax+7)/8;
|
|
prime = malloc(sizeof(char)*(wimax+1)); /* need [1,...,wimax] */
|
|
pmax = &prime[wimax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 0xff;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
i = n/2;
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
SCOUNT(StatOloop);
|
|
for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
prime[i>>3] &= CLRMASK(i&0x7);
|
|
SCOUNT(StatIloop);
|
|
}
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7))) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
#ifdef STATISTICS
|
|
printf("StatOloop: %20.0f\n",StatOloop);
|
|
printf("StatIloop: %20.0f\n",StatIloop);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQJCCF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=7000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soeq_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.1.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-11-20 966 1.1 add LOOKUP,STATISTICS ifdefs */
|
|
/* 2017-11-17 962 1.0 Initial version */
|
|
/* 2017-10-15 956 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
/* #define LOOKUP */
|
|
/* #define STATISTICS */
|
|
|
|
#ifdef LOOKUP
|
|
#define TSTMASK(ind) tstmask[ind]
|
|
#define CLRMASK(ind) clrmask[ind]
|
|
const unsigned char tstmask[] = {0x01,0x02,0x04,0x08,
|
|
0x10,0x20,0x40,0x80};
|
|
const unsigned char clrmask[] = {0xfe,0xfd,0xfb,0xf7,
|
|
0xef,0xdf,0xbf,0x7f};
|
|
|
|
#else
|
|
#define TSTMASK(ind) (1<<(ind))
|
|
#define CLRMASK(ind) ~(1<<(ind))
|
|
#endif
|
|
|
|
#ifdef STATISTICS
|
|
#define SCOUNT(var) var += 1;
|
|
double StatOloop = 0.;
|
|
double StatIloop = 0.;
|
|
#else
|
|
#define SCOUNT(var)
|
|
#endif
|
|
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int bimax;
|
|
int wimax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
unsigned char *prime;
|
|
unsigned char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
bimax = (nmax-1)/2;
|
|
wimax = (bimax+7)/8;
|
|
prime = malloc(sizeof(char)*(wimax+1)); /* need [1,...,wimax] */
|
|
pmax = &prime[wimax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 0xff;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
i = n/2;
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
SCOUNT(StatOloop);
|
|
for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
prime[i>>3] &= CLRMASK(i&0x7);
|
|
SCOUNT(StatIloop);
|
|
}
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7))) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
#ifdef STATISTICS
|
|
printf("StatOloop: %20.0f\n",StatOloop);
|
|
printf("StatIloop: %20.0f\n",StatIloop);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQJCCP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soeq_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.1.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-11-20 966 1.1 add LOOKUP,STATISTICS ifdefs */
|
|
/* 2017-11-17 962 1.0 Initial version */
|
|
/* 2017-10-15 956 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
/* #define LOOKUP */
|
|
/* #define STATISTICS */
|
|
|
|
#ifdef LOOKUP
|
|
#define TSTMASK(ind) tstmask[ind]
|
|
#define CLRMASK(ind) clrmask[ind]
|
|
const unsigned char tstmask[] = {0x01,0x02,0x04,0x08,
|
|
0x10,0x20,0x40,0x80};
|
|
const unsigned char clrmask[] = {0xfe,0xfd,0xfb,0xf7,
|
|
0xef,0xdf,0xbf,0x7f};
|
|
|
|
#else
|
|
#define TSTMASK(ind) (1<<(ind))
|
|
#define CLRMASK(ind) ~(1<<(ind))
|
|
#endif
|
|
|
|
#ifdef STATISTICS
|
|
#define SCOUNT(var) var += 1;
|
|
double StatOloop = 0.;
|
|
double StatIloop = 0.;
|
|
#else
|
|
#define SCOUNT(var)
|
|
#endif
|
|
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int bimax;
|
|
int wimax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
unsigned char *prime;
|
|
unsigned char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
bimax = (nmax-1)/2;
|
|
wimax = (bimax+7)/8;
|
|
prime = malloc(sizeof(char)*(wimax+1)); /* need [1,...,wimax] */
|
|
pmax = &prime[wimax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 0xff;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
i = n/2;
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
SCOUNT(StatOloop);
|
|
for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
prime[i>>3] &= CLRMASK(i&0x7);
|
|
SCOUNT(StatIloop);
|
|
}
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7))) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
#ifdef STATISTICS
|
|
printf("StatOloop: %20.0f\n",StatOloop);
|
|
printf("StatIloop: %20.0f\n",StatIloop);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQJCCT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: soeq_cc.c 972 2017-12-23 20:55:41Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-23 972 1.1.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-11-20 966 1.1 add LOOKUP,STATISTICS ifdefs */
|
|
/* 2017-11-17 962 1.0 Initial version */
|
|
/* 2017-10-15 956 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
/* #define LOOKUP */
|
|
/* #define STATISTICS */
|
|
|
|
#ifdef LOOKUP
|
|
#define TSTMASK(ind) tstmask[ind]
|
|
#define CLRMASK(ind) clrmask[ind]
|
|
const unsigned char tstmask[] = {0x01,0x02,0x04,0x08,
|
|
0x10,0x20,0x40,0x80};
|
|
const unsigned char clrmask[] = {0xfe,0xfd,0xfb,0xf7,
|
|
0xef,0xdf,0xbf,0x7f};
|
|
|
|
#else
|
|
#define TSTMASK(ind) (1<<(ind))
|
|
#define CLRMASK(ind) ~(1<<(ind))
|
|
#endif
|
|
|
|
#ifdef STATISTICS
|
|
#define SCOUNT(var) var += 1;
|
|
double StatOloop = 0.;
|
|
double StatIloop = 0.;
|
|
#else
|
|
#define SCOUNT(var)
|
|
#endif
|
|
|
|
|
|
int main()
|
|
{
|
|
int nmax;
|
|
int nmsqrt;
|
|
int prnt;
|
|
int bimax;
|
|
int wimax;
|
|
int i,n;
|
|
int np,il,nl;
|
|
unsigned char *prime;
|
|
unsigned char *p,*pmax;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &nmax, &prnt) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
if (nmax < 10) {
|
|
printf("nmax must be >= 10, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* prime: i=(n-1)/2 --> 3->[1], 5->[2]; ... 99-> [49]; ... */
|
|
nmsqrt = sqrt((double)nmax);
|
|
bimax = (nmax-1)/2;
|
|
wimax = (bimax+7)/8;
|
|
prime = malloc(sizeof(char)*(wimax+1)); /* need [1,...,wimax] */
|
|
pmax = &prime[wimax];
|
|
|
|
for (p=prime; p<=pmax;) *p++ = 0xff;
|
|
|
|
for (n=3; n<=nmsqrt; n+=2) {
|
|
i = n/2;
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
SCOUNT(StatOloop);
|
|
for (i=(n*n)/2; i<=bimax ; i+=n) {
|
|
prime[i>>3] &= CLRMASK(i&0x7);
|
|
SCOUNT(StatIloop);
|
|
}
|
|
}
|
|
|
|
if (prnt) {
|
|
printf("List of Primes up to %d\n",nmax);
|
|
printf(" %7d",2);
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7)) == 0) continue;
|
|
printf(" %7d",1+2*i);
|
|
np += 1;
|
|
if (np != 10) continue;
|
|
printf("\n");
|
|
np= 0;
|
|
}
|
|
if (np != 0) printf("\n");
|
|
}
|
|
|
|
il = 4;
|
|
nl = 10;
|
|
np = 1;
|
|
for (i=1;i<=bimax;i++) {
|
|
if ((prime[i>>3] & TSTMASK(i&0x7))) np += 1;
|
|
if (i != il) continue;
|
|
nl = 2*il+2;
|
|
printf("pi(%10d): %10d\n",nl,np);
|
|
il = 10*(il+1)-1;
|
|
}
|
|
if (nl != nmax) printf("pi(%10d): %10d\n",nmax,np);
|
|
|
|
#ifdef STATISTICS
|
|
printf("StatOloop: %20.0f\n",StatOloop);
|
|
printf("StatIloop: %20.0f\n",StatIloop);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQPASF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=7500K,TIME=(5,0),PRTY=2
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=7500K,
|
|
// OPT='M+,D-',
|
|
// GOPARM='/STACK=6500K'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: soeq_pas.pas 977 2017-12-27 12:46:21Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Remarks: *)
|
|
(* - The MVS Compiler uses 8 bytes to represent a set, sets are *)
|
|
(* limited to 64 members. seoq uses therefore sets with 64 members.*)
|
|
(* - the '<=' operator is slightly faster than the 'in' operator. *)
|
|
(* - the set '*' operator is slightly faster than the '-' operator. *)
|
|
(* - all this leads to a slightly different implementation than the *)
|
|
(* one scetched in 'Pascal User Manual and Report. 2nd Edition', *)
|
|
(* published 1975 by Springer. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-12-27 977 1.1 use '<=' and '*' instead of 'in' and '-'*)
|
|
(* 2017-12-26 976 1.0 Initial version (derived from soeq_pas) *)
|
|
|
|
program soep(input,output);
|
|
type
|
|
bits = (b00,b01,b02,b03,b04,b05,b06,b07,
|
|
b08,b09,b10,b11,b12,b13,b14,b15,
|
|
b16,b17,b18,b19,b20,b21,b22,b23,
|
|
b24,b25,b26,b27,b28,b29,b30,b31,
|
|
b32,b33,b34,b35,b36,b37,b38,b39,
|
|
b40,b41,b42,b43,b44,b45,b46,b47,
|
|
b48,b49,b50,b51,b52,b53,b54,b55,
|
|
b56,b57,b58,b59,b60,b61,b62,b63);
|
|
bset = set of bits;
|
|
var
|
|
nmax,prnt,imax : integer;
|
|
nmsqrt : integer;
|
|
wimax,iw : integer;
|
|
i,n,imin : integer;
|
|
np,il,nl : integer;
|
|
rnmax : real;
|
|
sieve : ARRAY[0 .. 781250] of bset;
|
|
btst : ARRAY[0 .. 63 ] of bset;
|
|
bclr : ARRAY[0 .. 63 ] of bset;
|
|
b : bits;
|
|
ball : bset;
|
|
begin
|
|
|
|
ball := [b00 .. b63];
|
|
b := b00;
|
|
btst[0] := [b];
|
|
bclr[0] := ball - [b];
|
|
for i := 1 to 63 do begin
|
|
b := succ(b);
|
|
btst[i] := [b];
|
|
bclr[i] := ball - [b];
|
|
end;
|
|
|
|
read(nmax);
|
|
read(prnt);
|
|
|
|
if (nmax < 10) or (nmax > 100000000) then begin
|
|
writeln(' ', 'nmax out of range (10...100000000), abort');
|
|
exit(8);
|
|
end;
|
|
|
|
rnmax := nmax;
|
|
nmsqrt := trunc(sqrt(nmax));
|
|
imax := (nmax-1) div 2;
|
|
wimax := (imax+63) div 64;
|
|
for i := 0 to wimax do sieve[i] := ball;
|
|
|
|
n := 3;
|
|
while n <= nmsqrt do begin
|
|
i := n div 2;
|
|
if btst[i mod 64] <= sieve[i div 64] then begin
|
|
i := (n*n) div 2;
|
|
while i <= imax do begin
|
|
iw := i div 64;
|
|
sieve[iw] := sieve[iw] * bclr[i mod 64];
|
|
i := i + n;
|
|
end;
|
|
end;
|
|
n := n + 2;
|
|
end;
|
|
|
|
if prnt > 0 then begin
|
|
writeln(' ', 'List of Primes up to ', nmax:9);
|
|
write(2:8);
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if btst[i mod 64] <= sieve[i div 64] then begin
|
|
write(1+2*i:8);
|
|
np := np + 1;
|
|
if np = 10 then begin
|
|
writeln(' ');
|
|
np := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
if np > 0 then writeln();
|
|
end;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if btst[i mod 64] <= sieve[i div 64] then np := np + 1;
|
|
if i = il then begin
|
|
nl := 2*il + 2;
|
|
writeln(' ', 'pi(', nl:9, '): ', np:9);
|
|
il := 10*(il+1)-1;
|
|
end;
|
|
end;
|
|
|
|
if nl < nmax then writeln(' ', 'pi(', nmax:9, '): ', np:9);
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQPASP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=7500K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=7500K,
|
|
// OPT='M+,D-',
|
|
// GOPARM='/STACK=6500K'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: soeq_pas.pas 977 2017-12-27 12:46:21Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Remarks: *)
|
|
(* - The MVS Compiler uses 8 bytes to represent a set, sets are *)
|
|
(* limited to 64 members. seoq uses therefore sets with 64 members.*)
|
|
(* - the '<=' operator is slightly faster than the 'in' operator. *)
|
|
(* - the set '*' operator is slightly faster than the '-' operator. *)
|
|
(* - all this leads to a slightly different implementation than the *)
|
|
(* one scetched in 'Pascal User Manual and Report. 2nd Edition', *)
|
|
(* published 1975 by Springer. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-12-27 977 1.1 use '<=' and '*' instead of 'in' and '-'*)
|
|
(* 2017-12-26 976 1.0 Initial version (derived from soeq_pas) *)
|
|
|
|
program soep(input,output);
|
|
type
|
|
bits = (b00,b01,b02,b03,b04,b05,b06,b07,
|
|
b08,b09,b10,b11,b12,b13,b14,b15,
|
|
b16,b17,b18,b19,b20,b21,b22,b23,
|
|
b24,b25,b26,b27,b28,b29,b30,b31,
|
|
b32,b33,b34,b35,b36,b37,b38,b39,
|
|
b40,b41,b42,b43,b44,b45,b46,b47,
|
|
b48,b49,b50,b51,b52,b53,b54,b55,
|
|
b56,b57,b58,b59,b60,b61,b62,b63);
|
|
bset = set of bits;
|
|
var
|
|
nmax,prnt,imax : integer;
|
|
nmsqrt : integer;
|
|
wimax,iw : integer;
|
|
i,n,imin : integer;
|
|
np,il,nl : integer;
|
|
rnmax : real;
|
|
sieve : ARRAY[0 .. 781250] of bset;
|
|
btst : ARRAY[0 .. 63 ] of bset;
|
|
bclr : ARRAY[0 .. 63 ] of bset;
|
|
b : bits;
|
|
ball : bset;
|
|
begin
|
|
|
|
ball := [b00 .. b63];
|
|
b := b00;
|
|
btst[0] := [b];
|
|
bclr[0] := ball - [b];
|
|
for i := 1 to 63 do begin
|
|
b := succ(b);
|
|
btst[i] := [b];
|
|
bclr[i] := ball - [b];
|
|
end;
|
|
|
|
read(nmax);
|
|
read(prnt);
|
|
|
|
if (nmax < 10) or (nmax > 100000000) then begin
|
|
writeln(' ', 'nmax out of range (10...100000000), abort');
|
|
exit(8);
|
|
end;
|
|
|
|
rnmax := nmax;
|
|
nmsqrt := trunc(sqrt(nmax));
|
|
imax := (nmax-1) div 2;
|
|
wimax := (imax+63) div 64;
|
|
for i := 0 to wimax do sieve[i] := ball;
|
|
|
|
n := 3;
|
|
while n <= nmsqrt do begin
|
|
i := n div 2;
|
|
if btst[i mod 64] <= sieve[i div 64] then begin
|
|
i := (n*n) div 2;
|
|
while i <= imax do begin
|
|
iw := i div 64;
|
|
sieve[iw] := sieve[iw] * bclr[i mod 64];
|
|
i := i + n;
|
|
end;
|
|
end;
|
|
n := n + 2;
|
|
end;
|
|
|
|
if prnt > 0 then begin
|
|
writeln(' ', 'List of Primes up to ', nmax:9);
|
|
write(2:8);
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if btst[i mod 64] <= sieve[i div 64] then begin
|
|
write(1+2*i:8);
|
|
np := np + 1;
|
|
if np = 10 then begin
|
|
writeln(' ');
|
|
np := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
if np > 0 then writeln();
|
|
end;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if btst[i mod 64] <= sieve[i div 64] then np := np + 1;
|
|
if i = il then begin
|
|
nl := 2*il + 2;
|
|
writeln(' ', 'pi(', nl:9, '): ', np:9);
|
|
il := 10*(il+1)-1;
|
|
end;
|
|
end;
|
|
|
|
if nl < nmax then writeln(' ', 'pi(', nmax:9, '): ', np:9);
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=100000
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQPAST,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=7500K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=7500K,
|
|
// OPT='M+',
|
|
// GOPARM='/STACK=6500K'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: soeq_pas.pas 977 2017-12-27 12:46:21Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Remarks: *)
|
|
(* - The MVS Compiler uses 8 bytes to represent a set, sets are *)
|
|
(* limited to 64 members. seoq uses therefore sets with 64 members.*)
|
|
(* - the '<=' operator is slightly faster than the 'in' operator. *)
|
|
(* - the set '*' operator is slightly faster than the '-' operator. *)
|
|
(* - all this leads to a slightly different implementation than the *)
|
|
(* one scetched in 'Pascal User Manual and Report. 2nd Edition', *)
|
|
(* published 1975 by Springer. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-12-27 977 1.1 use '<=' and '*' instead of 'in' and '-'*)
|
|
(* 2017-12-26 976 1.0 Initial version (derived from soeq_pas) *)
|
|
|
|
program soep(input,output);
|
|
type
|
|
bits = (b00,b01,b02,b03,b04,b05,b06,b07,
|
|
b08,b09,b10,b11,b12,b13,b14,b15,
|
|
b16,b17,b18,b19,b20,b21,b22,b23,
|
|
b24,b25,b26,b27,b28,b29,b30,b31,
|
|
b32,b33,b34,b35,b36,b37,b38,b39,
|
|
b40,b41,b42,b43,b44,b45,b46,b47,
|
|
b48,b49,b50,b51,b52,b53,b54,b55,
|
|
b56,b57,b58,b59,b60,b61,b62,b63);
|
|
bset = set of bits;
|
|
var
|
|
nmax,prnt,imax : integer;
|
|
nmsqrt : integer;
|
|
wimax,iw : integer;
|
|
i,n,imin : integer;
|
|
np,il,nl : integer;
|
|
rnmax : real;
|
|
sieve : ARRAY[0 .. 781250] of bset;
|
|
btst : ARRAY[0 .. 63 ] of bset;
|
|
bclr : ARRAY[0 .. 63 ] of bset;
|
|
b : bits;
|
|
ball : bset;
|
|
begin
|
|
|
|
ball := [b00 .. b63];
|
|
b := b00;
|
|
btst[0] := [b];
|
|
bclr[0] := ball - [b];
|
|
for i := 1 to 63 do begin
|
|
b := succ(b);
|
|
btst[i] := [b];
|
|
bclr[i] := ball - [b];
|
|
end;
|
|
|
|
read(nmax);
|
|
read(prnt);
|
|
|
|
if (nmax < 10) or (nmax > 100000000) then begin
|
|
writeln(' ', 'nmax out of range (10...100000000), abort');
|
|
exit(8);
|
|
end;
|
|
|
|
rnmax := nmax;
|
|
nmsqrt := trunc(sqrt(nmax));
|
|
imax := (nmax-1) div 2;
|
|
wimax := (imax+63) div 64;
|
|
for i := 0 to wimax do sieve[i] := ball;
|
|
|
|
n := 3;
|
|
while n <= nmsqrt do begin
|
|
i := n div 2;
|
|
if btst[i mod 64] <= sieve[i div 64] then begin
|
|
i := (n*n) div 2;
|
|
while i <= imax do begin
|
|
iw := i div 64;
|
|
sieve[iw] := sieve[iw] * bclr[i mod 64];
|
|
i := i + n;
|
|
end;
|
|
end;
|
|
n := n + 2;
|
|
end;
|
|
|
|
if prnt > 0 then begin
|
|
writeln(' ', 'List of Primes up to ', nmax:9);
|
|
write(2:8);
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if btst[i mod 64] <= sieve[i div 64] then begin
|
|
write(1+2*i:8);
|
|
np := np + 1;
|
|
if np = 10 then begin
|
|
writeln(' ');
|
|
np := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
if np > 0 then writeln();
|
|
end;
|
|
|
|
il := 4;
|
|
nl := 10;
|
|
np := 1;
|
|
for i := 1 to imax do begin
|
|
if btst[i mod 64] <= sieve[i div 64] then np := np + 1;
|
|
if i = il then begin
|
|
nl := 2*il + 2;
|
|
writeln(' ', 'pi(', nl:9, '): ', np:9);
|
|
il := 10*(il+1)-1;
|
|
end;
|
|
end;
|
|
|
|
if nl < nmax then writeln(' ', 'pi(', nmax:9, '): ', np:9);
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQPLIF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=2200K,TIME=(5,0),PRTY=2
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: soeq_pli.pli 976 2017-12-26 15:35:59Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-26 976 1.3 rename to SOEQ; go for max PRIME size */
|
|
/* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end */
|
|
/* 2017-12-25 974 1.1 use 2-dim PRIME array */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-09-17 951 1.0 Initial version */
|
|
/* 2017-09-01 945 0.1 First draft */
|
|
|
|
SOEQ: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (NMAX,PRNT,IMAX) BIN FIXED(31) INIT(0);
|
|
DCL (NMSQRT) BIN FIXED(31) INIT(0);
|
|
DCL (I,N,IMIN) BIN FIXED(31) INIT(0);
|
|
DCL (NP,IL,NL) BIN FIXED(31) INIT(0);
|
|
/* in PL/I(F) V5.5 array bounds are BIN(15) ! limited to 32k !! */
|
|
/* And the maximal aggregate size is 2 MByte !! BIT arrays are */
|
|
/* bit packed, so maximal total bit array size is 16 M entries. */
|
|
/* So go for a 2-dimensional array; 15626*1024 = 16001024; */
|
|
/* use 0 as lower bound to make index calculations easy: */
|
|
/* PRIME(I) turns into PRIME(I/1024,MOD(I,1024)) */
|
|
DCL PRIME(0:15625,0:1023) BIT(1);
|
|
|
|
ON ENDFILE(SYSIN) BEGIN;
|
|
PUT SKIP EDIT('Unexpected EOF, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
ON CONVERSION BEGIN;
|
|
PUT SKIP EDIT('Conversion error, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
GET EDIT(NMAX,PRNT) (F(10),F(10));
|
|
|
|
/*IF NMAX < 10 | NMAX > 32000000 THEN DO;*/
|
|
IF NMAX > 32000000 THEN DO;
|
|
PUT SKIP EDIT('nmax out of range (10...32000000), abort') (A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
NMSQRT = FLOOR(SQRT(NMAX));
|
|
IMAX = (NMAX-1)/2;
|
|
|
|
DO I=1 TO IMAX;
|
|
PRIME(I/1024,MOD(I,1024)) = '1'B;
|
|
END;
|
|
|
|
DO N=3 TO NMSQRT BY 2;
|
|
I = N/2;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN DO;
|
|
IMIN = N*N/2;
|
|
DO I=IMIN TO IMAX BY N;
|
|
PRIME(I/1024,MOD(I,1024)) = '0'B;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF PRNT > 0 THEN DO;
|
|
PUT SKIP EDIT('List of Primes up to ',NMAX) (A,F(8));
|
|
PUT SKIP EDIT(' ',2) (A,F(7));
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN DO;
|
|
PUT EDIT(' ',1+2*I) (A,F(7));
|
|
NP = NP + 1;
|
|
IF NP = 10 THEN DO;
|
|
PUT SKIP;
|
|
NP = 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF NP > 0 THEN PUT SKIP;
|
|
END;
|
|
|
|
IL = 4;
|
|
NL = 10;
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN NP = NP + 1;
|
|
IF I = IL THEN DO;
|
|
NL = 2*IL + 2;
|
|
PUT SKIP EDIT('pi(',NL,'): ',NP) (A,F(8),A,F(8));
|
|
IL = 10*(IL+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF NL < NMAX THEN PUT SKIP EDIT('pi(',NMAX,'): ',NP)
|
|
(A,F(8),A,F(8));
|
|
|
|
DONE:;
|
|
|
|
END SOEQ;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
32000000 0
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQPLIP,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=2200K,TIME=(2,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: soeq_pli.pli 976 2017-12-26 15:35:59Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-26 976 1.3 rename to SOEQ; go for max PRIME size */
|
|
/* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end */
|
|
/* 2017-12-25 974 1.1 use 2-dim PRIME array */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-09-17 951 1.0 Initial version */
|
|
/* 2017-09-01 945 0.1 First draft */
|
|
|
|
SOEQ: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (NMAX,PRNT,IMAX) BIN FIXED(31) INIT(0);
|
|
DCL (NMSQRT) BIN FIXED(31) INIT(0);
|
|
DCL (I,N,IMIN) BIN FIXED(31) INIT(0);
|
|
DCL (NP,IL,NL) BIN FIXED(31) INIT(0);
|
|
/* in PL/I(F) V5.5 array bounds are BIN(15) ! limited to 32k !! */
|
|
/* And the maximal aggregate size is 2 MByte !! BIT arrays are */
|
|
/* bit packed, so maximal total bit array size is 16 M entries. */
|
|
/* So go for a 2-dimensional array; 15626*1024 = 16001024; */
|
|
/* use 0 as lower bound to make index calculations easy: */
|
|
/* PRIME(I) turns into PRIME(I/1024,MOD(I,1024)) */
|
|
DCL PRIME(0:15625,0:1023) BIT(1);
|
|
|
|
ON ENDFILE(SYSIN) BEGIN;
|
|
PUT SKIP EDIT('Unexpected EOF, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
ON CONVERSION BEGIN;
|
|
PUT SKIP EDIT('Conversion error, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
GET EDIT(NMAX,PRNT) (F(10),F(10));
|
|
|
|
/*IF NMAX < 10 | NMAX > 32000000 THEN DO;*/
|
|
IF NMAX > 32000000 THEN DO;
|
|
PUT SKIP EDIT('nmax out of range (10...32000000), abort') (A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
NMSQRT = FLOOR(SQRT(NMAX));
|
|
IMAX = (NMAX-1)/2;
|
|
|
|
DO I=1 TO IMAX;
|
|
PRIME(I/1024,MOD(I,1024)) = '1'B;
|
|
END;
|
|
|
|
DO N=3 TO NMSQRT BY 2;
|
|
I = N/2;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN DO;
|
|
IMIN = N*N/2;
|
|
DO I=IMIN TO IMAX BY N;
|
|
PRIME(I/1024,MOD(I,1024)) = '0'B;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF PRNT > 0 THEN DO;
|
|
PUT SKIP EDIT('List of Primes up to ',NMAX) (A,F(8));
|
|
PUT SKIP EDIT(' ',2) (A,F(7));
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN DO;
|
|
PUT EDIT(' ',1+2*I) (A,F(7));
|
|
NP = NP + 1;
|
|
IF NP = 10 THEN DO;
|
|
PUT SKIP;
|
|
NP = 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF NP > 0 THEN PUT SKIP;
|
|
END;
|
|
|
|
IL = 4;
|
|
NL = 10;
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN NP = NP + 1;
|
|
IF I = IL THEN DO;
|
|
NL = 2*IL + 2;
|
|
PUT SKIP EDIT('pi(',NL,'): ',NP) (A,F(8),A,F(8));
|
|
IL = 10*(IL+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF NL < NMAX THEN PUT SKIP EDIT('pi(',NMAX,'): ',NP)
|
|
(A,F(8),A,F(8));
|
|
|
|
DONE:;
|
|
|
|
END SOEQ;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
10000000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=SOEQPLIT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//SOEQ#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=2200K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: soeq_pli.pli 976 2017-12-26 15:35:59Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-26 976 1.3 rename to SOEQ; go for max PRIME size */
|
|
/* 2017-12-25 975 1.2 use sqrt(nmax) as outer loop end */
|
|
/* 2017-12-25 974 1.1 use 2-dim PRIME array */
|
|
/* 2017-12-23 972 1.0.1 change (n-1)/2 --> n/2 */
|
|
/* 2017-09-17 951 1.0 Initial version */
|
|
/* 2017-09-01 945 0.1 First draft */
|
|
|
|
SOEQ: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (NMAX,PRNT,IMAX) BIN FIXED(31) INIT(0);
|
|
DCL (NMSQRT) BIN FIXED(31) INIT(0);
|
|
DCL (I,N,IMIN) BIN FIXED(31) INIT(0);
|
|
DCL (NP,IL,NL) BIN FIXED(31) INIT(0);
|
|
/* in PL/I(F) V5.5 array bounds are BIN(15) ! limited to 32k !! */
|
|
/* And the maximal aggregate size is 2 MByte !! BIT arrays are */
|
|
/* bit packed, so maximal total bit array size is 16 M entries. */
|
|
/* So go for a 2-dimensional array; 15626*1024 = 16001024; */
|
|
/* use 0 as lower bound to make index calculations easy: */
|
|
/* PRIME(I) turns into PRIME(I/1024,MOD(I,1024)) */
|
|
DCL PRIME(0:15625,0:1023) BIT(1);
|
|
|
|
ON ENDFILE(SYSIN) BEGIN;
|
|
PUT SKIP EDIT('Unexpected EOF, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
ON CONVERSION BEGIN;
|
|
PUT SKIP EDIT('Conversion error, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
GET EDIT(NMAX,PRNT) (F(10),F(10));
|
|
|
|
/*IF NMAX < 10 | NMAX > 32000000 THEN DO;*/
|
|
IF NMAX > 32000000 THEN DO;
|
|
PUT SKIP EDIT('nmax out of range (10...32000000), abort') (A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
NMSQRT = FLOOR(SQRT(NMAX));
|
|
IMAX = (NMAX-1)/2;
|
|
|
|
DO I=1 TO IMAX;
|
|
PRIME(I/1024,MOD(I,1024)) = '1'B;
|
|
END;
|
|
|
|
DO N=3 TO NMSQRT BY 2;
|
|
I = N/2;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN DO;
|
|
IMIN = N*N/2;
|
|
DO I=IMIN TO IMAX BY N;
|
|
PRIME(I/1024,MOD(I,1024)) = '0'B;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
IF PRNT > 0 THEN DO;
|
|
PUT SKIP EDIT('List of Primes up to ',NMAX) (A,F(8));
|
|
PUT SKIP EDIT(' ',2) (A,F(7));
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN DO;
|
|
PUT EDIT(' ',1+2*I) (A,F(7));
|
|
NP = NP + 1;
|
|
IF NP = 10 THEN DO;
|
|
PUT SKIP;
|
|
NP = 0;
|
|
END;
|
|
END;
|
|
END;
|
|
IF NP > 0 THEN PUT SKIP;
|
|
END;
|
|
|
|
IL = 4;
|
|
NL = 10;
|
|
NP = 1;
|
|
DO I=1 TO IMAX;
|
|
IF PRIME(I/1024,MOD(I,1024)) THEN NP = NP + 1;
|
|
IF I = IL THEN DO;
|
|
NL = 2*IL + 2;
|
|
PUT SKIP EDIT('pi(',NL,'): ',NP) (A,F(8),A,F(8));
|
|
IL = 10*(IL+1)-1;
|
|
END;
|
|
END;
|
|
|
|
IF NL < NMAX THEN PUT SKIP EDIT('pi(',NMAX,'): ',NP)
|
|
(A,F(8),A,F(8));
|
|
|
|
DONE:;
|
|
|
|
END SOEQ;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
100000 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHA60F,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
'COMMENT'
|
|
* $Id: towh_a60.a60 964 2017-11-19 08:47:46Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-09-05 946 1.0 Initial version
|
|
*;
|
|
|
|
'INTEGER' NCALL,NMOVE;
|
|
'INTEGER' CURSTK,MAXSTK;
|
|
'INTEGER' MAXDSK,TRACE;
|
|
'INTEGER' 'ARRAY' TOW[1:3];
|
|
'INTEGER' NDSK;
|
|
|
|
'PROCEDURE' TRC(TXT,N,F,T);
|
|
'STRING' TXT;
|
|
'VALUE' N,F,T;
|
|
'INTEGER' N,F,T;
|
|
'BEGIN'
|
|
OUTSTRING (1, TXT);
|
|
OUTINTEGER(1, NDSK);
|
|
OUTSTRING (1,'(' :')');
|
|
OUTINTEGER(1, N);
|
|
OUTINTEGER(1, F);
|
|
OUTINTEGER(1, T);
|
|
OUTSTRING (1,'(' :')');
|
|
OUTTARRAY (1, TOW);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
'PROCEDURE' MOV(N,F,T);
|
|
'VALUE' N,F,T;
|
|
'INTEGER' N,F,T;
|
|
'BEGIN'
|
|
'INTEGER' O;
|
|
O := 6-(F+T);
|
|
CURSTK := CURSTK + 1;
|
|
NCALL := NCALL + 1;
|
|
'IF' CURSTK > MAXSTK 'THEN' MAXSTK := CURSTK;
|
|
|
|
'IF' N = 1 'THEN' 'BEGIN'
|
|
NMOVE := NMOVE + 1;
|
|
TOW[F] := TOW[F] - 1;
|
|
TOW[T] := TOW[T] + 1;
|
|
'IF' TRACE > 0 'THEN' TRC('('mov-do: ')',N,F,T);
|
|
'END'
|
|
'ELSE' 'BEGIN'
|
|
'IF' TRACE > 0 'THEN' TRC('('mov-go: ')',N,F,T);
|
|
MOV(N-1,F,O);
|
|
MOV(1,F,T);
|
|
MOV(N-1,O,T);
|
|
'END';
|
|
|
|
CURSTK := CURSTK - 1;
|
|
'END';
|
|
|
|
'COMMENT' set record lenth = 132 and page length = 62;
|
|
SYSACT(1,6,132);
|
|
SYSACT(1,8,64);
|
|
|
|
ININTEGER(0,MAXDSK);
|
|
ININTEGER(0,TRACE);
|
|
|
|
'FOR' NDSK := 2 'STEP' 1 'UNTIL' MAXDSK 'DO' 'BEGIN'
|
|
NCALL := 0;
|
|
NMOVE := 0;
|
|
MAXSTK := 0;
|
|
CURSTK := 0;
|
|
TOW[1] := NDSK;
|
|
TOW[2] := 0;
|
|
TOW[3] := 0;
|
|
'IF' TRACE > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('STRT ndsk=')');
|
|
OUTINTEGER(1, NDSK);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
MOV(NDSK,1,3);
|
|
OUTSTRING (1,'('DONE ndsk=')');
|
|
OUTINTEGER(1, NDSK);
|
|
OUTSTRING (1,'(': maxstk=')');
|
|
OUTINTEGER(1, MAXSTK);
|
|
OUTSTRING (1,'(' ncall=')');
|
|
OUTINTEGER(1, NCALL);
|
|
OUTSTRING (1,'(' nmove=')');
|
|
OUTINTEGER(1, NMOVE);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
'END'
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHA60T,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
'COMMENT'
|
|
* $Id: towh_a60.a60 964 2017-11-19 08:47:46Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-09-05 946 1.0 Initial version
|
|
*;
|
|
|
|
'INTEGER' NCALL,NMOVE;
|
|
'INTEGER' CURSTK,MAXSTK;
|
|
'INTEGER' MAXDSK,TRACE;
|
|
'INTEGER' 'ARRAY' TOW[1:3];
|
|
'INTEGER' NDSK;
|
|
|
|
'PROCEDURE' TRC(TXT,N,F,T);
|
|
'STRING' TXT;
|
|
'VALUE' N,F,T;
|
|
'INTEGER' N,F,T;
|
|
'BEGIN'
|
|
OUTSTRING (1, TXT);
|
|
OUTINTEGER(1, NDSK);
|
|
OUTSTRING (1,'(' :')');
|
|
OUTINTEGER(1, N);
|
|
OUTINTEGER(1, F);
|
|
OUTINTEGER(1, T);
|
|
OUTSTRING (1,'(' :')');
|
|
OUTTARRAY (1, TOW);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
'PROCEDURE' MOV(N,F,T);
|
|
'VALUE' N,F,T;
|
|
'INTEGER' N,F,T;
|
|
'BEGIN'
|
|
'INTEGER' O;
|
|
O := 6-(F+T);
|
|
CURSTK := CURSTK + 1;
|
|
NCALL := NCALL + 1;
|
|
'IF' CURSTK > MAXSTK 'THEN' MAXSTK := CURSTK;
|
|
|
|
'IF' N = 1 'THEN' 'BEGIN'
|
|
NMOVE := NMOVE + 1;
|
|
TOW[F] := TOW[F] - 1;
|
|
TOW[T] := TOW[T] + 1;
|
|
'IF' TRACE > 0 'THEN' TRC('('mov-do: ')',N,F,T);
|
|
'END'
|
|
'ELSE' 'BEGIN'
|
|
'IF' TRACE > 0 'THEN' TRC('('mov-go: ')',N,F,T);
|
|
MOV(N-1,F,O);
|
|
MOV(1,F,T);
|
|
MOV(N-1,O,T);
|
|
'END';
|
|
|
|
CURSTK := CURSTK - 1;
|
|
'END';
|
|
|
|
'COMMENT' set record lenth = 132 and page length = 62;
|
|
SYSACT(1,6,132);
|
|
SYSACT(1,8,64);
|
|
|
|
ININTEGER(0,MAXDSK);
|
|
ININTEGER(0,TRACE);
|
|
|
|
'FOR' NDSK := 2 'STEP' 1 'UNTIL' MAXDSK 'DO' 'BEGIN'
|
|
NCALL := 0;
|
|
NMOVE := 0;
|
|
MAXSTK := 0;
|
|
CURSTK := 0;
|
|
TOW[1] := NDSK;
|
|
TOW[2] := 0;
|
|
TOW[3] := 0;
|
|
'IF' TRACE > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('STRT ndsk=')');
|
|
OUTINTEGER(1, NDSK);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
MOV(NDSK,1,3);
|
|
OUTSTRING (1,'('DONE ndsk=')');
|
|
OUTINTEGER(1, NDSK);
|
|
OUTSTRING (1,'(': maxstk=')');
|
|
OUTINTEGER(1, MAXSTK);
|
|
OUTSTRING (1,'(' ncall=')');
|
|
OUTINTEGER(1, NCALL);
|
|
OUTSTRING (1,'(' nmove=')');
|
|
OUTINTEGER(1, NMOVE);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
'END'
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHASMF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=128K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NOLIST,NOXREF,NORLD,NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: towh_asm.asm 968 2017-12-03 16:58:43Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-11-12 961 1.0 Initial version
|
|
* 2017-10-10 955 0.1 First draft
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Tower of Hanoi
|
|
* RC = 0 ok
|
|
* RC = 4 MAXDSK out of range
|
|
* RC = 8 unexpected SYSIN EOF
|
|
* RC = 12 open SYSIN failed
|
|
* RC = 16 open SYSPRINT failed
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
L R15,=A(STACK) R15 := current save area
|
|
ST R13,4(R15) set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LR R13,R15 setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'0C'
|
|
B EXIT quit with RC=12
|
|
IOPENOK EQU *
|
|
*
|
|
* read input parameters, and check range ------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT05 get NMAX
|
|
ST R1,MAXDSK
|
|
BAL R14,IINT05 get PRNT
|
|
STC R1,TRACE
|
|
*
|
|
L R1,MAXDSK
|
|
C R1,=F'2' is MAXDSK >= 2
|
|
BL MAXDBAD if < not
|
|
C R1,=F'30' is MAXDSK <= 30
|
|
BNH MAXDOK if <= yes
|
|
MAXDBAD L R1,MSGPERR
|
|
BAL R14,OTEXT print error
|
|
BAL R14,OPUTLINE write line
|
|
MVI RC+3,X'04'
|
|
B EXIT quit with RC=4
|
|
MAXDOK EQU *
|
|
*
|
|
* outer loop over ndsk cases ------------------------------------------
|
|
*
|
|
DLOOP XR R2,R2 R2 := 0
|
|
ST R2,NCALL ncall = 0
|
|
ST R2,NMOVE nmove = 0
|
|
ST R2,MAXSTK maxstk = 0
|
|
ST R2,CURSTK curstk = 0
|
|
L R3,NDSK
|
|
ST R3,TOW+4 tow[1] = ndsk
|
|
ST R2,TOW+8 tow[2] = 0
|
|
ST R2,TOW+12 tow[3] = 0
|
|
*
|
|
CLI TRACE,X'00' trace enabled ?
|
|
BE NOTRCLP
|
|
L R1,MSGSTRT
|
|
BAL R14,OTEXT print "STRT..."
|
|
LR R1,R3
|
|
BAL R14,OINT04 print ndsk
|
|
BAL R14,OPUTLINE write line
|
|
NOTRCLP EQU *
|
|
*
|
|
LR R0,R3
|
|
LA R1,1
|
|
LA R2,3
|
|
LA R15,MOV
|
|
BALR R14,R15 mov(ndsk,1,3)
|
|
*
|
|
L R1,MSGDONE
|
|
BAL R14,OTEXT print "DONE..."
|
|
L R1,NDSK
|
|
BAL R14,OINT04 print ndsk
|
|
L R1,MSGDOSTK
|
|
BAL R14,OTEXT print " maxstk..."
|
|
L R1,MAXSTK
|
|
BAL R14,OINT04 print maxstk
|
|
L R1,MSGDONCA
|
|
BAL R14,OTEXT print " ncall..."
|
|
L R1,NCALL
|
|
BAL R14,OINT10 print ncall
|
|
L R1,MSGDONMO
|
|
BAL R14,OTEXT print " nmove..."
|
|
L R1,NMOVE
|
|
BAL R14,OINT10 print nmove
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
L R1,NDSK R1 := ndsk
|
|
LA R1,1(R1) R1 := ndsk + 1
|
|
C R1,MAXDSK is ndsk+1 <= maxdsk
|
|
ST R1,NDSK ndsk++
|
|
BNH DLOOP if <= yes, go for next size
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R15,=A(STACK)
|
|
L R13,4(R15) get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* mov function (called recursively) -----------------------------------
|
|
*
|
|
* mov(n,f,t)
|
|
* Register usage
|
|
* R0 n (input)
|
|
* R1 f (input)
|
|
* R2 t (input)
|
|
* R3 copy of n
|
|
* R4 copy of f
|
|
* R5 copy of t
|
|
* R6 work register
|
|
* R7 work register
|
|
* R8 constant 1 (used often)
|
|
* R9 used as linkage for MOVTRC
|
|
* R10 not used
|
|
* R11 not used
|
|
* R12 base (kept from caller !)
|
|
*
|
|
*
|
|
*
|
|
MOV SAVE (14,10) Save input registers (not R11,R12)
|
|
LA R15,(4*18)(R13) R15 := current save area
|
|
ST R13,4(R15) set back pointer in current save area
|
|
LR R3,R13 remember callers save area
|
|
LR R13,R15 setup current save area
|
|
ST R13,8(R3) set forw pointer in callers save area
|
|
*
|
|
LR R3,R0 keep n
|
|
LR R4,R1 keep f
|
|
LR R5,R2 keep t
|
|
LA R8,1 constant 1 (often used below)
|
|
*
|
|
L R6,CURSTK
|
|
AR R6,R8
|
|
ST R6,CURSTK curstk++
|
|
C R6,MAXSTK is curstk > maxstk ?
|
|
BNH MAXSTKOK if <= not, skip maxstk
|
|
ST R6,MAXSTK maxstk = curstk
|
|
MAXSTKOK EQU *
|
|
*
|
|
L R6,NCALL
|
|
AR R6,R8
|
|
ST R6,NCALL ncall++
|
|
*
|
|
CR R3,R8 is n == 1 ?
|
|
BNE MOVGO if != not, mov-go case
|
|
*
|
|
* mov-do case
|
|
*
|
|
L R6,NMOVE
|
|
AR R6,R8
|
|
ST R6,NMOVE nmove++
|
|
LR R7,R4 R7 := f
|
|
SLA R7,2
|
|
L R6,TOW(R7) R6 := tow[f]
|
|
SR R6,R8
|
|
ST R6,TOW(R7) tow[f]--
|
|
LR R7,R5 R7 := t
|
|
SLA R7,2
|
|
L R6,TOW(R7) R6 := tow[t]
|
|
AR R6,R8
|
|
ST R6,TOW(R7) tow[t]++
|
|
*
|
|
CLI TRACE,X'00' trace enabled ?
|
|
BE NOTRCDO
|
|
L R1,MSGTRCDO
|
|
BAL R9,MOVTRC
|
|
NOTRCDO EQU *
|
|
*
|
|
B MOVEND
|
|
*
|
|
* mov-go case
|
|
*
|
|
MOVGO EQU *
|
|
CLI TRACE,X'00' trace enabled ?
|
|
BE NOTRCGO
|
|
L R1,MSGTRCGO
|
|
BAL R9,MOVTRC
|
|
NOTRCGO EQU *
|
|
*
|
|
LR R6,R3
|
|
SR R6,R8 R6 := n-1
|
|
LA R7,6
|
|
SR R7,R4
|
|
SR R7,R5 R7 := 6-(f+t)
|
|
*
|
|
LA R15,MOV
|
|
LR R0,R6 R0 := n-1
|
|
LR R1,R4 R1 := f
|
|
LR R2,R7 R2 := o
|
|
BALR R14,R15 mov(n-1,f,o)
|
|
*
|
|
LA R0,1 R0 := 1
|
|
LR R1,R4 R1 := f
|
|
LR R2,R5 R2 := t
|
|
BALR R14,R15 mov(1,f,t)
|
|
*
|
|
LR R0,R6 R0 := n-1
|
|
LR R1,R7 R0 := o
|
|
LR R2,R5 R0 := t
|
|
BALR R14,R15 mov(n-1,o,t)
|
|
*
|
|
MOVEND EQU *
|
|
L R5,CURSTK
|
|
SR R5,R8
|
|
ST R5,CURSTK curstk--
|
|
L R13,4(R13) get old save area back
|
|
RETURN (14,10),T return to caller
|
|
*
|
|
* local print handler
|
|
* used with BAL 9, no local frame !!
|
|
*
|
|
MOVTRC BAL R14,OTEXT print prefix
|
|
L R1,CURSTK
|
|
BAL R14,OINT04 print curstk
|
|
L R1,MSGCSEP
|
|
BAL R14,OTEXT print " : "
|
|
LR R1,R3
|
|
BAL R14,OINT04 print n
|
|
LR R1,R4
|
|
BAL R14,OINT04 print f
|
|
LR R1,R5
|
|
BAL R14,OINT04 print t
|
|
L R1,MSGCSEP
|
|
BAL R14,OTEXT print " : "
|
|
L R1,TOW+4
|
|
BAL R14,OINT04 print tow[1]
|
|
L R1,TOW+8
|
|
BAL R14,OINT04 print tow[2]
|
|
L R1,TOW+12
|
|
BAL R14,OINT04 print tow[3]
|
|
BAL R14,OPUTLINE write line
|
|
BR R9
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
*
|
|
* OINT04 ---------------------------------------------------
|
|
* print integer, like PL/I F(4) or C %4d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT04 LA R15,999
|
|
CLR R1,R15 too large ?
|
|
BH OINT04F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI04L,R15),OEI04 setup pattern
|
|
ED 0(OEI04L,R15),OCVD+6 and edit
|
|
LA R15,OEI04L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT04F LA R1,4
|
|
B OSFILL
|
|
*
|
|
OEI04 DC C' ',X'20',X'21',X'20' ED pattern: bd(d
|
|
OEI04L EQU *-OEI04
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT05 ---------------------------------------------------
|
|
* read integer, like PL/I F(5) or C %5d format
|
|
*
|
|
IINT05 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(5,R15) pack next 5 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,5(R15) push pointer by 5 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
RC DC F'0' return code
|
|
MAXDSK DC F'10' maximal number of disks
|
|
TRACE DC X'00' trace enable flag
|
|
*
|
|
NDSK DC F'2'
|
|
NCALL DC F'0'
|
|
NMOVE DC F'0'
|
|
MAXSTK DC F'0'
|
|
CURSTK DC F'0'
|
|
TOW DC 4F'0'
|
|
*
|
|
* message strings
|
|
*
|
|
MSGPERR OTXTDSC C'maxdsk out of range (2...30), abort'
|
|
MSGSTRT OTXTDSC C'STRT ndsk='
|
|
MSGDONE OTXTDSC C'DONE ndsk='
|
|
MSGDOSTK OTXTDSC C': maxstk='
|
|
MSGDONCA OTXTDSC C' ncall='
|
|
MSGDONMO OTXTDSC C' nmove='
|
|
MSGTRCDO OTXTDSC C'mov-do: '
|
|
MSGTRCGO OTXTDSC C'mov-go: '
|
|
MSGCSEP OTXTDSC C' : '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* Place the STACK in separate CSECT. Is quite large (~2 kByte)
|
|
*
|
|
DATA CSECT
|
|
STACK DS (32*18)F save area STACK
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHASMT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=128K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: towh_asm.asm 968 2017-12-03 16:58:43Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-11-12 961 1.0 Initial version
|
|
* 2017-10-10 955 0.1 First draft
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Tower of Hanoi
|
|
* RC = 0 ok
|
|
* RC = 4 MAXDSK out of range
|
|
* RC = 8 unexpected SYSIN EOF
|
|
* RC = 12 open SYSIN failed
|
|
* RC = 16 open SYSPRINT failed
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
L R15,=A(STACK) R15 := current save area
|
|
ST R13,4(R15) set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LR R13,R15 setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'0C'
|
|
B EXIT quit with RC=12
|
|
IOPENOK EQU *
|
|
*
|
|
* read input parameters, and check range ------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT05 get NMAX
|
|
ST R1,MAXDSK
|
|
BAL R14,IINT05 get PRNT
|
|
STC R1,TRACE
|
|
*
|
|
L R1,MAXDSK
|
|
C R1,=F'2' is MAXDSK >= 2
|
|
BL MAXDBAD if < not
|
|
C R1,=F'30' is MAXDSK <= 30
|
|
BNH MAXDOK if <= yes
|
|
MAXDBAD L R1,MSGPERR
|
|
BAL R14,OTEXT print error
|
|
BAL R14,OPUTLINE write line
|
|
MVI RC+3,X'04'
|
|
B EXIT quit with RC=4
|
|
MAXDOK EQU *
|
|
*
|
|
* outer loop over ndsk cases ------------------------------------------
|
|
*
|
|
DLOOP XR R2,R2 R2 := 0
|
|
ST R2,NCALL ncall = 0
|
|
ST R2,NMOVE nmove = 0
|
|
ST R2,MAXSTK maxstk = 0
|
|
ST R2,CURSTK curstk = 0
|
|
L R3,NDSK
|
|
ST R3,TOW+4 tow[1] = ndsk
|
|
ST R2,TOW+8 tow[2] = 0
|
|
ST R2,TOW+12 tow[3] = 0
|
|
*
|
|
CLI TRACE,X'00' trace enabled ?
|
|
BE NOTRCLP
|
|
L R1,MSGSTRT
|
|
BAL R14,OTEXT print "STRT..."
|
|
LR R1,R3
|
|
BAL R14,OINT04 print ndsk
|
|
BAL R14,OPUTLINE write line
|
|
NOTRCLP EQU *
|
|
*
|
|
LR R0,R3
|
|
LA R1,1
|
|
LA R2,3
|
|
LA R15,MOV
|
|
BALR R14,R15 mov(ndsk,1,3)
|
|
*
|
|
L R1,MSGDONE
|
|
BAL R14,OTEXT print "DONE..."
|
|
L R1,NDSK
|
|
BAL R14,OINT04 print ndsk
|
|
L R1,MSGDOSTK
|
|
BAL R14,OTEXT print " maxstk..."
|
|
L R1,MAXSTK
|
|
BAL R14,OINT04 print maxstk
|
|
L R1,MSGDONCA
|
|
BAL R14,OTEXT print " ncall..."
|
|
L R1,NCALL
|
|
BAL R14,OINT10 print ncall
|
|
L R1,MSGDONMO
|
|
BAL R14,OTEXT print " nmove..."
|
|
L R1,NMOVE
|
|
BAL R14,OINT10 print nmove
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
L R1,NDSK R1 := ndsk
|
|
LA R1,1(R1) R1 := ndsk + 1
|
|
C R1,MAXDSK is ndsk+1 <= maxdsk
|
|
ST R1,NDSK ndsk++
|
|
BNH DLOOP if <= yes, go for next size
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R15,=A(STACK)
|
|
L R13,4(R15) get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* mov function (called recursively) -----------------------------------
|
|
*
|
|
* mov(n,f,t)
|
|
* Register usage
|
|
* R0 n (input)
|
|
* R1 f (input)
|
|
* R2 t (input)
|
|
* R3 copy of n
|
|
* R4 copy of f
|
|
* R5 copy of t
|
|
* R6 work register
|
|
* R7 work register
|
|
* R8 constant 1 (used often)
|
|
* R9 used as linkage for MOVTRC
|
|
* R10 not used
|
|
* R11 not used
|
|
* R12 base (kept from caller !)
|
|
*
|
|
*
|
|
*
|
|
MOV SAVE (14,10) Save input registers (not R11,R12)
|
|
LA R15,(4*18)(R13) R15 := current save area
|
|
ST R13,4(R15) set back pointer in current save area
|
|
LR R3,R13 remember callers save area
|
|
LR R13,R15 setup current save area
|
|
ST R13,8(R3) set forw pointer in callers save area
|
|
*
|
|
LR R3,R0 keep n
|
|
LR R4,R1 keep f
|
|
LR R5,R2 keep t
|
|
LA R8,1 constant 1 (often used below)
|
|
*
|
|
L R6,CURSTK
|
|
AR R6,R8
|
|
ST R6,CURSTK curstk++
|
|
C R6,MAXSTK is curstk > maxstk ?
|
|
BNH MAXSTKOK if <= not, skip maxstk
|
|
ST R6,MAXSTK maxstk = curstk
|
|
MAXSTKOK EQU *
|
|
*
|
|
L R6,NCALL
|
|
AR R6,R8
|
|
ST R6,NCALL ncall++
|
|
*
|
|
CR R3,R8 is n == 1 ?
|
|
BNE MOVGO if != not, mov-go case
|
|
*
|
|
* mov-do case
|
|
*
|
|
L R6,NMOVE
|
|
AR R6,R8
|
|
ST R6,NMOVE nmove++
|
|
LR R7,R4 R7 := f
|
|
SLA R7,2
|
|
L R6,TOW(R7) R6 := tow[f]
|
|
SR R6,R8
|
|
ST R6,TOW(R7) tow[f]--
|
|
LR R7,R5 R7 := t
|
|
SLA R7,2
|
|
L R6,TOW(R7) R6 := tow[t]
|
|
AR R6,R8
|
|
ST R6,TOW(R7) tow[t]++
|
|
*
|
|
CLI TRACE,X'00' trace enabled ?
|
|
BE NOTRCDO
|
|
L R1,MSGTRCDO
|
|
BAL R9,MOVTRC
|
|
NOTRCDO EQU *
|
|
*
|
|
B MOVEND
|
|
*
|
|
* mov-go case
|
|
*
|
|
MOVGO EQU *
|
|
CLI TRACE,X'00' trace enabled ?
|
|
BE NOTRCGO
|
|
L R1,MSGTRCGO
|
|
BAL R9,MOVTRC
|
|
NOTRCGO EQU *
|
|
*
|
|
LR R6,R3
|
|
SR R6,R8 R6 := n-1
|
|
LA R7,6
|
|
SR R7,R4
|
|
SR R7,R5 R7 := 6-(f+t)
|
|
*
|
|
LA R15,MOV
|
|
LR R0,R6 R0 := n-1
|
|
LR R1,R4 R1 := f
|
|
LR R2,R7 R2 := o
|
|
BALR R14,R15 mov(n-1,f,o)
|
|
*
|
|
LA R0,1 R0 := 1
|
|
LR R1,R4 R1 := f
|
|
LR R2,R5 R2 := t
|
|
BALR R14,R15 mov(1,f,t)
|
|
*
|
|
LR R0,R6 R0 := n-1
|
|
LR R1,R7 R0 := o
|
|
LR R2,R5 R0 := t
|
|
BALR R14,R15 mov(n-1,o,t)
|
|
*
|
|
MOVEND EQU *
|
|
L R5,CURSTK
|
|
SR R5,R8
|
|
ST R5,CURSTK curstk--
|
|
L R13,4(R13) get old save area back
|
|
RETURN (14,10),T return to caller
|
|
*
|
|
* local print handler
|
|
* used with BAL 9, no local frame !!
|
|
*
|
|
MOVTRC BAL R14,OTEXT print prefix
|
|
L R1,CURSTK
|
|
BAL R14,OINT04 print curstk
|
|
L R1,MSGCSEP
|
|
BAL R14,OTEXT print " : "
|
|
LR R1,R3
|
|
BAL R14,OINT04 print n
|
|
LR R1,R4
|
|
BAL R14,OINT04 print f
|
|
LR R1,R5
|
|
BAL R14,OINT04 print t
|
|
L R1,MSGCSEP
|
|
BAL R14,OTEXT print " : "
|
|
L R1,TOW+4
|
|
BAL R14,OINT04 print tow[1]
|
|
L R1,TOW+8
|
|
BAL R14,OINT04 print tow[2]
|
|
L R1,TOW+12
|
|
BAL R14,OINT04 print tow[3]
|
|
BAL R14,OPUTLINE write line
|
|
BR R9
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
*
|
|
* OINT04 ---------------------------------------------------
|
|
* print integer, like PL/I F(4) or C %4d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT04 LA R15,999
|
|
CLR R1,R15 too large ?
|
|
BH OINT04F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI04L,R15),OEI04 setup pattern
|
|
ED 0(OEI04L,R15),OCVD+6 and edit
|
|
LA R15,OEI04L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT04F LA R1,4
|
|
B OSFILL
|
|
*
|
|
OEI04 DC C' ',X'20',X'21',X'20' ED pattern: bd(d
|
|
OEI04L EQU *-OEI04
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT05 ---------------------------------------------------
|
|
* read integer, like PL/I F(5) or C %5d format
|
|
*
|
|
IINT05 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(5,R15) pack next 5 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,5(R15) push pointer by 5 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
RC DC F'0' return code
|
|
MAXDSK DC F'10' maximal number of disks
|
|
TRACE DC X'00' trace enable flag
|
|
*
|
|
NDSK DC F'2'
|
|
NCALL DC F'0'
|
|
NMOVE DC F'0'
|
|
MAXSTK DC F'0'
|
|
CURSTK DC F'0'
|
|
TOW DC 4F'0'
|
|
*
|
|
* message strings
|
|
*
|
|
MSGPERR OTXTDSC C'maxdsk out of range (2...30), abort'
|
|
MSGSTRT OTXTDSC C'STRT ndsk='
|
|
MSGDONE OTXTDSC C'DONE ndsk='
|
|
MSGDOSTK OTXTDSC C': maxstk='
|
|
MSGDONCA OTXTDSC C' ncall='
|
|
MSGDONMO OTXTDSC C' nmove='
|
|
MSGTRCDO OTXTDSC C'mov-do: '
|
|
MSGTRCGO OTXTDSC C'mov-go: '
|
|
MSGCSEP OTXTDSC C' : '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* Place the STACK in separate CSECT. Is quite large (~2 kByte)
|
|
*
|
|
DATA CSECT
|
|
STACK DS (32*18)F save area STACK
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHGCCF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: towh_cc.c 964 2017-11-19 08:47:46Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-08-09 934 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
|
|
void mov(int n, int f, int t);
|
|
|
|
int ncall = 0;
|
|
int nmove = 0;
|
|
int curstk = 0;
|
|
int maxstk = 0;
|
|
int maxdsk = 0;
|
|
int trace = 0;
|
|
int tow[4];
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
int ndsk;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &maxdsk, &trace) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* avoid | here, lots of fun with ASCII -> EBCDIC mapping */
|
|
/* if (maxdsk < 2 || maxdsk > 32) { */
|
|
if ((maxdsk < 2) + (maxdsk > 32)) {
|
|
printf("maxdsk out of range (2...32), abort\n");
|
|
return 1;
|
|
}
|
|
|
|
for (ndsk=2; ndsk<=maxdsk; ndsk++) {
|
|
ncall = 0;
|
|
nmove = 0;
|
|
maxstk = 0;
|
|
curstk = 0;
|
|
tow[1] = ndsk;
|
|
tow[2] = 0;
|
|
tow[3] = 0;
|
|
|
|
if (trace) printf("STRT ndsk=%2d\n", ndsk);
|
|
mov(ndsk,1,3);
|
|
printf("DONE ndsk=%2d: maxstk=%2d ncall=%10d nmove=%10d\n",
|
|
ndsk,maxstk,ncall,nmove);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void mov(int n, int f, int t)
|
|
{
|
|
int o = 6-(f+t);
|
|
curstk++;
|
|
ncall++;
|
|
if (curstk > maxstk) maxstk = curstk;
|
|
if(n == 1) {
|
|
nmove++;
|
|
tow[f]--;
|
|
tow[t]++;
|
|
if (trace) printf("mov-do: %2d : %2d %2d %2d : %2d %2d %2d\n",
|
|
curstk,n,f,t,tow[1],tow[2],tow[3]);
|
|
} else {
|
|
if (trace) printf("mov-go: %2d : %2d %2d %2d : %2d %2d %2d\n",
|
|
curstk,n,f,t,tow[1],tow[2],tow[3]);
|
|
mov(n-1,f,o);
|
|
mov(1,f,t);
|
|
mov(n-1,o,t);
|
|
}
|
|
curstk--;
|
|
return;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHGCCT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: towh_cc.c 964 2017-11-19 08:47:46Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-08-09 934 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
|
|
void mov(int n, int f, int t);
|
|
|
|
int ncall = 0;
|
|
int nmove = 0;
|
|
int curstk = 0;
|
|
int maxstk = 0;
|
|
int maxdsk = 0;
|
|
int trace = 0;
|
|
int tow[4];
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
int ndsk;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &maxdsk, &trace) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* avoid | here, lots of fun with ASCII -> EBCDIC mapping */
|
|
/* if (maxdsk < 2 || maxdsk > 32) { */
|
|
if ((maxdsk < 2) + (maxdsk > 32)) {
|
|
printf("maxdsk out of range (2...32), abort\n");
|
|
return 1;
|
|
}
|
|
|
|
for (ndsk=2; ndsk<=maxdsk; ndsk++) {
|
|
ncall = 0;
|
|
nmove = 0;
|
|
maxstk = 0;
|
|
curstk = 0;
|
|
tow[1] = ndsk;
|
|
tow[2] = 0;
|
|
tow[3] = 0;
|
|
|
|
if (trace) printf("STRT ndsk=%2d\n", ndsk);
|
|
mov(ndsk,1,3);
|
|
printf("DONE ndsk=%2d: maxstk=%2d ncall=%10d nmove=%10d\n",
|
|
ndsk,maxstk,ncall,nmove);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void mov(int n, int f, int t)
|
|
{
|
|
int o = 6-(f+t);
|
|
curstk++;
|
|
ncall++;
|
|
if (curstk > maxstk) maxstk = curstk;
|
|
if(n == 1) {
|
|
nmove++;
|
|
tow[f]--;
|
|
tow[t]++;
|
|
if (trace) printf("mov-do: %2d : %2d %2d %2d : %2d %2d %2d\n",
|
|
curstk,n,f,t,tow[1],tow[2],tow[3]);
|
|
} else {
|
|
if (trace) printf("mov-go: %2d : %2d %2d %2d : %2d %2d %2d\n",
|
|
curstk,n,f,t,tow[1],tow[2],tow[3]);
|
|
mov(n-1,f,o);
|
|
mov(1,f,t);
|
|
mov(n-1,o,t);
|
|
}
|
|
curstk--;
|
|
return;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHJCCF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: towh_cc.c 964 2017-11-19 08:47:46Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-08-09 934 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
|
|
void mov(int n, int f, int t);
|
|
|
|
int ncall = 0;
|
|
int nmove = 0;
|
|
int curstk = 0;
|
|
int maxstk = 0;
|
|
int maxdsk = 0;
|
|
int trace = 0;
|
|
int tow[4];
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
int ndsk;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &maxdsk, &trace) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* avoid | here, lots of fun with ASCII -> EBCDIC mapping */
|
|
/* if (maxdsk < 2 || maxdsk > 32) { */
|
|
if ((maxdsk < 2) + (maxdsk > 32)) {
|
|
printf("maxdsk out of range (2...32), abort\n");
|
|
return 1;
|
|
}
|
|
|
|
for (ndsk=2; ndsk<=maxdsk; ndsk++) {
|
|
ncall = 0;
|
|
nmove = 0;
|
|
maxstk = 0;
|
|
curstk = 0;
|
|
tow[1] = ndsk;
|
|
tow[2] = 0;
|
|
tow[3] = 0;
|
|
|
|
if (trace) printf("STRT ndsk=%2d\n", ndsk);
|
|
mov(ndsk,1,3);
|
|
printf("DONE ndsk=%2d: maxstk=%2d ncall=%10d nmove=%10d\n",
|
|
ndsk,maxstk,ncall,nmove);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void mov(int n, int f, int t)
|
|
{
|
|
int o = 6-(f+t);
|
|
curstk++;
|
|
ncall++;
|
|
if (curstk > maxstk) maxstk = curstk;
|
|
if(n == 1) {
|
|
nmove++;
|
|
tow[f]--;
|
|
tow[t]++;
|
|
if (trace) printf("mov-do: %2d : %2d %2d %2d : %2d %2d %2d\n",
|
|
curstk,n,f,t,tow[1],tow[2],tow[3]);
|
|
} else {
|
|
if (trace) printf("mov-go: %2d : %2d %2d %2d : %2d %2d %2d\n",
|
|
curstk,n,f,t,tow[1],tow[2],tow[3]);
|
|
mov(n-1,f,o);
|
|
mov(1,f,t);
|
|
mov(n-1,o,t);
|
|
}
|
|
curstk--;
|
|
return;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHJCCT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: towh_cc.c 964 2017-11-19 08:47:46Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-08-09 934 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
|
|
void mov(int n, int f, int t);
|
|
|
|
int ncall = 0;
|
|
int nmove = 0;
|
|
int curstk = 0;
|
|
int maxstk = 0;
|
|
int maxdsk = 0;
|
|
int trace = 0;
|
|
int tow[4];
|
|
|
|
int main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
int ndsk;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d", &maxdsk, &trace) != 2) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
/* avoid | here, lots of fun with ASCII -> EBCDIC mapping */
|
|
/* if (maxdsk < 2 || maxdsk > 32) { */
|
|
if ((maxdsk < 2) + (maxdsk > 32)) {
|
|
printf("maxdsk out of range (2...32), abort\n");
|
|
return 1;
|
|
}
|
|
|
|
for (ndsk=2; ndsk<=maxdsk; ndsk++) {
|
|
ncall = 0;
|
|
nmove = 0;
|
|
maxstk = 0;
|
|
curstk = 0;
|
|
tow[1] = ndsk;
|
|
tow[2] = 0;
|
|
tow[3] = 0;
|
|
|
|
if (trace) printf("STRT ndsk=%2d\n", ndsk);
|
|
mov(ndsk,1,3);
|
|
printf("DONE ndsk=%2d: maxstk=%2d ncall=%10d nmove=%10d\n",
|
|
ndsk,maxstk,ncall,nmove);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void mov(int n, int f, int t)
|
|
{
|
|
int o = 6-(f+t);
|
|
curstk++;
|
|
ncall++;
|
|
if (curstk > maxstk) maxstk = curstk;
|
|
if(n == 1) {
|
|
nmove++;
|
|
tow[f]--;
|
|
tow[t]++;
|
|
if (trace) printf("mov-do: %2d : %2d %2d %2d : %2d %2d %2d\n",
|
|
curstk,n,f,t,tow[1],tow[2],tow[3]);
|
|
} else {
|
|
if (trace) printf("mov-go: %2d : %2d %2d %2d : %2d %2d %2d\n",
|
|
curstk,n,f,t,tow[1],tow[2],tow[3]);
|
|
mov(n-1,f,o);
|
|
mov(1,f,t);
|
|
mov(n-1,o,t);
|
|
}
|
|
curstk--;
|
|
return;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHFOGF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: towh_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM TOWH
|
|
C
|
|
IMPLICIT LOGICAL (A-Z)
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
INTEGER NDSK
|
|
C
|
|
READ(5,9000,ERR=910,END=900) MAXDSK,TRACE
|
|
C
|
|
DO 100 NDSK=2,MAXDSK
|
|
NCALL = 0
|
|
NMOVE = 0
|
|
MAXSTK = 0
|
|
TOW(1) = NDSK
|
|
TOW(2) = 0
|
|
TOW(3) = 0
|
|
IF (TRACE .NE. 0) WRITE(6,9010) NDSK
|
|
CALL MOV(NDSK,1,3)
|
|
WRITE(6,9020) NDSK,MAXSTK,NCALL,NMOVE
|
|
100 CONTINUE
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9030)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I5)
|
|
9010 FORMAT(1X,'STRT ndsk=',I2)
|
|
9020 FORMAT(1X,'DONE ndsk=',I2,': maxstk=',I2,' ncall=',I10,
|
|
* ' nmove=',I10)
|
|
9030 FORMAT(1X,'conversion error, abort')
|
|
END
|
|
C
|
|
C --- subroutine mov -------------------------------------------------
|
|
C
|
|
SUBROUTINE MOV(N,F,T)
|
|
IMPLICIT LOGICAL (A-Z)
|
|
INTEGER N,F,T
|
|
INTEGER O,L1,S
|
|
C
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
L = 1
|
|
LN(1) = N
|
|
LF(1) = F
|
|
LT(1) = T
|
|
C
|
|
1000 CONTINUE
|
|
NCALL = NCALL + 1
|
|
IF (L .GT. MAXSTK) MAXSTK = L
|
|
LS(L) = 1
|
|
C
|
|
IF (LN(L) .NE. 1) GOTO 1900
|
|
NMOVE = NMOVE + 1
|
|
TOW(LF(L)) = TOW(LF(L)) - 1
|
|
TOW(LT(L)) = TOW(LT(L)) + 1
|
|
IF (TRACE .NE. 0) WRITE(6,9000) L,LN(L),LF(L),LT(L),TOW
|
|
L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
1900 IF (TRACE .NE. 0) WRITE(6,9010) L,LN(L),LF(L),LT(L),TOW
|
|
C
|
|
2000 CONTINUE
|
|
IF (TRACE .GT. 1) WRITE(6,9020) L,LN(L),LF(L),LT(L),TOW,L,LS(L)
|
|
O = 6-(LF(L)+LT(L))
|
|
L1 = L + 1
|
|
C Fortran IV(1966): computed GOTO selectors must be un-subscripted integers
|
|
S = LS(L)
|
|
GOTO (2100,2200,2300,2400), S
|
|
C
|
|
2100 LN(L1) = LN(L)-1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = O
|
|
LS(L) = 2
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2200 LN(L1) = 1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = LT(L)
|
|
LS(L) = 3
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2300 LN(L1) = LN(L)-1
|
|
LF(L1) = O
|
|
LT(L1) = LT(L)
|
|
LS(L) = 4
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2400 L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
9000 FORMAT(1X,'mov-do: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9010 FORMAT(1X,'mov-go: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9020 FORMAT(1X,'step: ',I2,' :',3(1X,I2),' :',3(1X,I2),
|
|
* ' :',I2,'-',I2)
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHFOGT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: towh_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM TOWH
|
|
C
|
|
IMPLICIT LOGICAL (A-Z)
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
INTEGER NDSK
|
|
C
|
|
READ(5,9000,ERR=910,END=900) MAXDSK,TRACE
|
|
C
|
|
DO 100 NDSK=2,MAXDSK
|
|
NCALL = 0
|
|
NMOVE = 0
|
|
MAXSTK = 0
|
|
TOW(1) = NDSK
|
|
TOW(2) = 0
|
|
TOW(3) = 0
|
|
IF (TRACE .NE. 0) WRITE(6,9010) NDSK
|
|
CALL MOV(NDSK,1,3)
|
|
WRITE(6,9020) NDSK,MAXSTK,NCALL,NMOVE
|
|
100 CONTINUE
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9030)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I5)
|
|
9010 FORMAT(1X,'STRT ndsk=',I2)
|
|
9020 FORMAT(1X,'DONE ndsk=',I2,': maxstk=',I2,' ncall=',I10,
|
|
* ' nmove=',I10)
|
|
9030 FORMAT(1X,'conversion error, abort')
|
|
END
|
|
C
|
|
C --- subroutine mov -------------------------------------------------
|
|
C
|
|
SUBROUTINE MOV(N,F,T)
|
|
IMPLICIT LOGICAL (A-Z)
|
|
INTEGER N,F,T
|
|
INTEGER O,L1,S
|
|
C
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
L = 1
|
|
LN(1) = N
|
|
LF(1) = F
|
|
LT(1) = T
|
|
C
|
|
1000 CONTINUE
|
|
NCALL = NCALL + 1
|
|
IF (L .GT. MAXSTK) MAXSTK = L
|
|
LS(L) = 1
|
|
C
|
|
IF (LN(L) .NE. 1) GOTO 1900
|
|
NMOVE = NMOVE + 1
|
|
TOW(LF(L)) = TOW(LF(L)) - 1
|
|
TOW(LT(L)) = TOW(LT(L)) + 1
|
|
IF (TRACE .NE. 0) WRITE(6,9000) L,LN(L),LF(L),LT(L),TOW
|
|
L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
1900 IF (TRACE .NE. 0) WRITE(6,9010) L,LN(L),LF(L),LT(L),TOW
|
|
C
|
|
2000 CONTINUE
|
|
IF (TRACE .GT. 1) WRITE(6,9020) L,LN(L),LF(L),LT(L),TOW,L,LS(L)
|
|
O = 6-(LF(L)+LT(L))
|
|
L1 = L + 1
|
|
C Fortran IV(1966): computed GOTO selectors must be un-subscripted integers
|
|
S = LS(L)
|
|
GOTO (2100,2200,2300,2400), S
|
|
C
|
|
2100 LN(L1) = LN(L)-1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = O
|
|
LS(L) = 2
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2200 LN(L1) = 1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = LT(L)
|
|
LS(L) = 3
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2300 LN(L1) = LN(L)-1
|
|
LF(L1) = O
|
|
LT(L1) = LT(L)
|
|
LS(L) = 4
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2400 L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
9000 FORMAT(1X,'mov-do: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9010 FORMAT(1X,'mov-go: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9020 FORMAT(1X,'step: ',I2,' :',3(1X,I2),' :',3(1X,I2),
|
|
* ' :',I2,'-',I2)
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHFOHF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: towh_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM TOWH
|
|
C
|
|
IMPLICIT LOGICAL (A-Z)
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
INTEGER NDSK
|
|
C
|
|
READ(5,9000,ERR=910,END=900) MAXDSK,TRACE
|
|
C
|
|
DO 100 NDSK=2,MAXDSK
|
|
NCALL = 0
|
|
NMOVE = 0
|
|
MAXSTK = 0
|
|
TOW(1) = NDSK
|
|
TOW(2) = 0
|
|
TOW(3) = 0
|
|
IF (TRACE .NE. 0) WRITE(6,9010) NDSK
|
|
CALL MOV(NDSK,1,3)
|
|
WRITE(6,9020) NDSK,MAXSTK,NCALL,NMOVE
|
|
100 CONTINUE
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9030)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I5)
|
|
9010 FORMAT(1X,'STRT ndsk=',I2)
|
|
9020 FORMAT(1X,'DONE ndsk=',I2,': maxstk=',I2,' ncall=',I10,
|
|
* ' nmove=',I10)
|
|
9030 FORMAT(1X,'conversion error, abort')
|
|
END
|
|
C
|
|
C --- subroutine mov -------------------------------------------------
|
|
C
|
|
SUBROUTINE MOV(N,F,T)
|
|
IMPLICIT LOGICAL (A-Z)
|
|
INTEGER N,F,T
|
|
INTEGER O,L1,S
|
|
C
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
L = 1
|
|
LN(1) = N
|
|
LF(1) = F
|
|
LT(1) = T
|
|
C
|
|
1000 CONTINUE
|
|
NCALL = NCALL + 1
|
|
IF (L .GT. MAXSTK) MAXSTK = L
|
|
LS(L) = 1
|
|
C
|
|
IF (LN(L) .NE. 1) GOTO 1900
|
|
NMOVE = NMOVE + 1
|
|
TOW(LF(L)) = TOW(LF(L)) - 1
|
|
TOW(LT(L)) = TOW(LT(L)) + 1
|
|
IF (TRACE .NE. 0) WRITE(6,9000) L,LN(L),LF(L),LT(L),TOW
|
|
L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
1900 IF (TRACE .NE. 0) WRITE(6,9010) L,LN(L),LF(L),LT(L),TOW
|
|
C
|
|
2000 CONTINUE
|
|
IF (TRACE .GT. 1) WRITE(6,9020) L,LN(L),LF(L),LT(L),TOW,L,LS(L)
|
|
O = 6-(LF(L)+LT(L))
|
|
L1 = L + 1
|
|
C Fortran IV(1966): computed GOTO selectors must be un-subscripted integers
|
|
S = LS(L)
|
|
GOTO (2100,2200,2300,2400), S
|
|
C
|
|
2100 LN(L1) = LN(L)-1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = O
|
|
LS(L) = 2
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2200 LN(L1) = 1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = LT(L)
|
|
LS(L) = 3
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2300 LN(L1) = LN(L)-1
|
|
LF(L1) = O
|
|
LT(L1) = LT(L)
|
|
LS(L) = 4
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2400 L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
9000 FORMAT(1X,'mov-do: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9010 FORMAT(1X,'mov-go: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9020 FORMAT(1X,'step: ',I2,' :',3(1X,I2),' :',3(1X,I2),
|
|
* ' :',I2,'-',I2)
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHFOHT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: towh_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM TOWH
|
|
C
|
|
IMPLICIT LOGICAL (A-Z)
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
INTEGER NDSK
|
|
C
|
|
READ(5,9000,ERR=910,END=900) MAXDSK,TRACE
|
|
C
|
|
DO 100 NDSK=2,MAXDSK
|
|
NCALL = 0
|
|
NMOVE = 0
|
|
MAXSTK = 0
|
|
TOW(1) = NDSK
|
|
TOW(2) = 0
|
|
TOW(3) = 0
|
|
IF (TRACE .NE. 0) WRITE(6,9010) NDSK
|
|
CALL MOV(NDSK,1,3)
|
|
WRITE(6,9020) NDSK,MAXSTK,NCALL,NMOVE
|
|
100 CONTINUE
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9030)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I5)
|
|
9010 FORMAT(1X,'STRT ndsk=',I2)
|
|
9020 FORMAT(1X,'DONE ndsk=',I2,': maxstk=',I2,' ncall=',I10,
|
|
* ' nmove=',I10)
|
|
9030 FORMAT(1X,'conversion error, abort')
|
|
END
|
|
C
|
|
C --- subroutine mov -------------------------------------------------
|
|
C
|
|
SUBROUTINE MOV(N,F,T)
|
|
IMPLICIT LOGICAL (A-Z)
|
|
INTEGER N,F,T
|
|
INTEGER O,L1,S
|
|
C
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
L = 1
|
|
LN(1) = N
|
|
LF(1) = F
|
|
LT(1) = T
|
|
C
|
|
1000 CONTINUE
|
|
NCALL = NCALL + 1
|
|
IF (L .GT. MAXSTK) MAXSTK = L
|
|
LS(L) = 1
|
|
C
|
|
IF (LN(L) .NE. 1) GOTO 1900
|
|
NMOVE = NMOVE + 1
|
|
TOW(LF(L)) = TOW(LF(L)) - 1
|
|
TOW(LT(L)) = TOW(LT(L)) + 1
|
|
IF (TRACE .NE. 0) WRITE(6,9000) L,LN(L),LF(L),LT(L),TOW
|
|
L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
1900 IF (TRACE .NE. 0) WRITE(6,9010) L,LN(L),LF(L),LT(L),TOW
|
|
C
|
|
2000 CONTINUE
|
|
IF (TRACE .GT. 1) WRITE(6,9020) L,LN(L),LF(L),LT(L),TOW,L,LS(L)
|
|
O = 6-(LF(L)+LT(L))
|
|
L1 = L + 1
|
|
C Fortran IV(1966): computed GOTO selectors must be un-subscripted integers
|
|
S = LS(L)
|
|
GOTO (2100,2200,2300,2400), S
|
|
C
|
|
2100 LN(L1) = LN(L)-1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = O
|
|
LS(L) = 2
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2200 LN(L1) = 1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = LT(L)
|
|
LS(L) = 3
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2300 LN(L1) = LN(L)-1
|
|
LF(L1) = O
|
|
LT(L1) = LT(L)
|
|
LS(L) = 4
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2400 L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
9000 FORMAT(1X,'mov-do: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9010 FORMAT(1X,'mov-go: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9020 FORMAT(1X,'step: ',I2,' :',3(1X,I2),' :',3(1X,I2),
|
|
* ' :',I2,'-',I2)
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHFOWF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(20,0),PRTY=2
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB TOWH#FOW,T=(20,0),P=100,NOCHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: towh_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM TOWH
|
|
C
|
|
IMPLICIT LOGICAL (A-Z)
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
INTEGER NDSK
|
|
C
|
|
READ(5,9000,ERR=910,END=900) MAXDSK,TRACE
|
|
C
|
|
DO 100 NDSK=2,MAXDSK
|
|
NCALL = 0
|
|
NMOVE = 0
|
|
MAXSTK = 0
|
|
TOW(1) = NDSK
|
|
TOW(2) = 0
|
|
TOW(3) = 0
|
|
IF (TRACE .NE. 0) WRITE(6,9010) NDSK
|
|
CALL MOV(NDSK,1,3)
|
|
WRITE(6,9020) NDSK,MAXSTK,NCALL,NMOVE
|
|
100 CONTINUE
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9030)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I5)
|
|
9010 FORMAT(1X,'STRT ndsk=',I2)
|
|
9020 FORMAT(1X,'DONE ndsk=',I2,': maxstk=',I2,' ncall=',I10,
|
|
* ' nmove=',I10)
|
|
9030 FORMAT(1X,'conversion error, abort')
|
|
END
|
|
C
|
|
C --- subroutine mov -------------------------------------------------
|
|
C
|
|
SUBROUTINE MOV(N,F,T)
|
|
IMPLICIT LOGICAL (A-Z)
|
|
INTEGER N,F,T
|
|
INTEGER O,L1,S
|
|
C
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
L = 1
|
|
LN(1) = N
|
|
LF(1) = F
|
|
LT(1) = T
|
|
C
|
|
1000 CONTINUE
|
|
NCALL = NCALL + 1
|
|
IF (L .GT. MAXSTK) MAXSTK = L
|
|
LS(L) = 1
|
|
C
|
|
IF (LN(L) .NE. 1) GOTO 1900
|
|
NMOVE = NMOVE + 1
|
|
TOW(LF(L)) = TOW(LF(L)) - 1
|
|
TOW(LT(L)) = TOW(LT(L)) + 1
|
|
IF (TRACE .NE. 0) WRITE(6,9000) L,LN(L),LF(L),LT(L),TOW
|
|
L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
1900 IF (TRACE .NE. 0) WRITE(6,9010) L,LN(L),LF(L),LT(L),TOW
|
|
C
|
|
2000 CONTINUE
|
|
IF (TRACE .GT. 1) WRITE(6,9020) L,LN(L),LF(L),LT(L),TOW,L,LS(L)
|
|
O = 6-(LF(L)+LT(L))
|
|
L1 = L + 1
|
|
C Fortran IV(1966): computed GOTO selectors must be un-subscripted integers
|
|
S = LS(L)
|
|
GOTO (2100,2200,2300,2400), S
|
|
C
|
|
2100 LN(L1) = LN(L)-1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = O
|
|
LS(L) = 2
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2200 LN(L1) = 1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = LT(L)
|
|
LS(L) = 3
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2300 LN(L1) = LN(L)-1
|
|
LF(L1) = O
|
|
LT(L1) = LT(L)
|
|
LS(L) = 4
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2400 L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
9000 FORMAT(1X,'mov-do: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9010 FORMAT(1X,'mov-go: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9020 FORMAT(1X,'step: ',I2,' :',3(1X,I2),' :',3(1X,I2),
|
|
* ' :',I2,'-',I2)
|
|
C
|
|
END
|
|
$ENTRY
|
|
22 0
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHFOWT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB TOWH#FOW,T=(1,0),P=100,CHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: towh_for.f 964 2017-11-19 08:47:46Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-08-09 934 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM TOWH
|
|
C
|
|
IMPLICIT LOGICAL (A-Z)
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
INTEGER NDSK
|
|
C
|
|
READ(5,9000,ERR=910,END=900) MAXDSK,TRACE
|
|
C
|
|
DO 100 NDSK=2,MAXDSK
|
|
NCALL = 0
|
|
NMOVE = 0
|
|
MAXSTK = 0
|
|
TOW(1) = NDSK
|
|
TOW(2) = 0
|
|
TOW(3) = 0
|
|
IF (TRACE .NE. 0) WRITE(6,9010) NDSK
|
|
CALL MOV(NDSK,1,3)
|
|
WRITE(6,9020) NDSK,MAXSTK,NCALL,NMOVE
|
|
100 CONTINUE
|
|
C
|
|
900 CONTINUE
|
|
STOP
|
|
910 WRITE(6,9030)
|
|
STOP
|
|
C
|
|
9000 FORMAT(2I5)
|
|
9010 FORMAT(1X,'STRT ndsk=',I2)
|
|
9020 FORMAT(1X,'DONE ndsk=',I2,': maxstk=',I2,' ncall=',I10,
|
|
* ' nmove=',I10)
|
|
9030 FORMAT(1X,'conversion error, abort')
|
|
END
|
|
C
|
|
C --- subroutine mov -------------------------------------------------
|
|
C
|
|
SUBROUTINE MOV(N,F,T)
|
|
IMPLICIT LOGICAL (A-Z)
|
|
INTEGER N,F,T
|
|
INTEGER O,L1,S
|
|
C
|
|
COMMON /DAT1/NCALL,NMOVE,MAXSTK,MAXDSK,TRACE,TOW(3)
|
|
INTEGER NCALL,NMOVE,MAXDSK,MAXSTK,TRACE,TOW
|
|
COMMON /DAT2/L,LN(32),LF(32),LT(32),LS(32)
|
|
INTEGER L,LN,LF,LT,LS
|
|
C
|
|
L = 1
|
|
LN(1) = N
|
|
LF(1) = F
|
|
LT(1) = T
|
|
C
|
|
1000 CONTINUE
|
|
NCALL = NCALL + 1
|
|
IF (L .GT. MAXSTK) MAXSTK = L
|
|
LS(L) = 1
|
|
C
|
|
IF (LN(L) .NE. 1) GOTO 1900
|
|
NMOVE = NMOVE + 1
|
|
TOW(LF(L)) = TOW(LF(L)) - 1
|
|
TOW(LT(L)) = TOW(LT(L)) + 1
|
|
IF (TRACE .NE. 0) WRITE(6,9000) L,LN(L),LF(L),LT(L),TOW
|
|
L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
1900 IF (TRACE .NE. 0) WRITE(6,9010) L,LN(L),LF(L),LT(L),TOW
|
|
C
|
|
2000 CONTINUE
|
|
IF (TRACE .GT. 1) WRITE(6,9020) L,LN(L),LF(L),LT(L),TOW,L,LS(L)
|
|
O = 6-(LF(L)+LT(L))
|
|
L1 = L + 1
|
|
C Fortran IV(1966): computed GOTO selectors must be un-subscripted integers
|
|
S = LS(L)
|
|
GOTO (2100,2200,2300,2400), S
|
|
C
|
|
2100 LN(L1) = LN(L)-1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = O
|
|
LS(L) = 2
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2200 LN(L1) = 1
|
|
LF(L1) = LF(L)
|
|
LT(L1) = LT(L)
|
|
LS(L) = 3
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2300 LN(L1) = LN(L)-1
|
|
LF(L1) = O
|
|
LT(L1) = LT(L)
|
|
LS(L) = 4
|
|
L = L1
|
|
GOTO 1000
|
|
C
|
|
2400 L = L - 1
|
|
IF (L .EQ. 0) RETURN
|
|
GOTO 2000
|
|
C
|
|
9000 FORMAT(1X,'mov-do: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9010 FORMAT(1X,'mov-go: ',I2,' :',3(1X,I2),' :',3(1X,I2))
|
|
9020 FORMAT(1X,'step: ',I2,' :',3(1X,I2),' :',3(1X,I2),
|
|
* ' :',I2,'-',I2)
|
|
C
|
|
END
|
|
$ENTRY
|
|
4 1
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHPASF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=1024K,
|
|
// OPT='M+,D-',
|
|
// GOPARM='/STACK=512k'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: towh_pas.pas 964 2017-11-19 08:47:46Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-09-07 948 0.1 Initial version *)
|
|
|
|
program towh(input,output);
|
|
var
|
|
ncall,nmove : integer;
|
|
curstk,maxstk : integer;
|
|
maxdsk,trace : integer;
|
|
ndsk : integer;
|
|
tow : ARRAY[1 .. 3] of integer;
|
|
|
|
procedure mov(n,f,t: integer);
|
|
var
|
|
o : integer;
|
|
begin
|
|
o := 6-(f+t);
|
|
curstk := curstk + 1;
|
|
ncall := ncall + 1;
|
|
if maxstk < curstk then maxstk := curstk;
|
|
if n = 1 then begin
|
|
nmove := nmove + 1;
|
|
tow[f] := tow[f] - 1;
|
|
tow[t] := tow[t] + 1;
|
|
if trace > 0 then writeln(' ','mov-do: ',curstk:2,
|
|
' :',n:3,f:3,t:3,
|
|
' :',tow[1]:3,tow[2]:3,tow[3]:3);
|
|
end else begin
|
|
if trace > 0 then writeln(' ','mov-go: ',curstk:2,
|
|
' :',n:3,f:3,t:3,
|
|
' :',tow[1]:3,tow[2]:3,tow[3]:3);
|
|
mov(n-1,f,o);
|
|
mov(1,f,t);
|
|
mov(n-1,o,t);
|
|
end;
|
|
curstk := curstk - 1;
|
|
end;
|
|
|
|
begin
|
|
|
|
read(maxdsk);
|
|
read(trace);
|
|
|
|
for ndsk := 2 to maxdsk do begin
|
|
ncall := 0;
|
|
nmove := 0;
|
|
maxstk := 0;
|
|
curstk := 0;
|
|
tow[1] := ndsk;
|
|
tow[2] := 0;
|
|
tow[3] := 0;
|
|
if trace > 0 then writeln(' ','STRT ndsk=',ndsk:2);
|
|
mov(ndsk,1,3);
|
|
writeln(' ','DONE ndsk=',ndsk:2,': maxstk=',maxstk:2,
|
|
' ncall=',ncall:10,' nmove=',nmove:10);
|
|
end;
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHPAST,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=1024K,
|
|
// OPT='M+',
|
|
// GOPARM='/STACK=512k'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: towh_pas.pas 964 2017-11-19 08:47:46Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-09-07 948 0.1 Initial version *)
|
|
|
|
program towh(input,output);
|
|
var
|
|
ncall,nmove : integer;
|
|
curstk,maxstk : integer;
|
|
maxdsk,trace : integer;
|
|
ndsk : integer;
|
|
tow : ARRAY[1 .. 3] of integer;
|
|
|
|
procedure mov(n,f,t: integer);
|
|
var
|
|
o : integer;
|
|
begin
|
|
o := 6-(f+t);
|
|
curstk := curstk + 1;
|
|
ncall := ncall + 1;
|
|
if maxstk < curstk then maxstk := curstk;
|
|
if n = 1 then begin
|
|
nmove := nmove + 1;
|
|
tow[f] := tow[f] - 1;
|
|
tow[t] := tow[t] + 1;
|
|
if trace > 0 then writeln(' ','mov-do: ',curstk:2,
|
|
' :',n:3,f:3,t:3,
|
|
' :',tow[1]:3,tow[2]:3,tow[3]:3);
|
|
end else begin
|
|
if trace > 0 then writeln(' ','mov-go: ',curstk:2,
|
|
' :',n:3,f:3,t:3,
|
|
' :',tow[1]:3,tow[2]:3,tow[3]:3);
|
|
mov(n-1,f,o);
|
|
mov(1,f,t);
|
|
mov(n-1,o,t);
|
|
end;
|
|
curstk := curstk - 1;
|
|
end;
|
|
|
|
begin
|
|
|
|
read(maxdsk);
|
|
read(trace);
|
|
|
|
for ndsk := 2 to maxdsk do begin
|
|
ncall := 0;
|
|
nmove := 0;
|
|
maxstk := 0;
|
|
curstk := 0;
|
|
tow[1] := ndsk;
|
|
tow[2] := 0;
|
|
tow[3] := 0;
|
|
if trace > 0 then writeln(' ','STRT ndsk=',ndsk:2);
|
|
mov(ndsk,1,3);
|
|
writeln(' ','DONE ndsk=',ndsk:2,': maxstk=',maxstk:2,
|
|
' ncall=',ncall:10,' nmove=',nmove:10);
|
|
end;
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHPLIF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: towh_pli.pli 981 2018-01-02 13:30:49Z mueller $ */
|
|
/*
|
|
/* Copyright 2017-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2018-01-02 981 1.0 add ON units for ENDFILE and CONVERSION */
|
|
/* 2017-09-07 947 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
TOWH: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (NCALL,NMOVE) BIN FIXED(31) INIT(0);
|
|
DCL (CURSTK,MAXSTK) BIN FIXED(31) INIT(0);
|
|
DCL (MAXDSK,TRACE) BIN FIXED(31) INIT(0);
|
|
DCL TOW(3) BIN FIXED(31) INIT((3)0);
|
|
DCL NDSK BIN FIXED(31);
|
|
|
|
DCL MOV ENTRY(BIN FIXED(31),BIN FIXED(31),BIN FIXED(31));
|
|
|
|
ON ENDFILE(SYSIN) BEGIN;
|
|
PUT SKIP EDIT('Unexpected EOF, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
ON CONVERSION BEGIN;
|
|
PUT SKIP EDIT('Conversion error, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
GET EDIT(MAXDSK,TRACE) (F(5),F(5));
|
|
|
|
DO NDSK=2 TO MAXDSK;
|
|
NCALL = 0;
|
|
NMOVE = 0;
|
|
MAXSTK = 0;
|
|
CURSTK = 0;
|
|
TOW(1) = NDSK;
|
|
TOW(2) = 0;
|
|
TOW(3) = 0;
|
|
IF TRACE > 0 THEN PUT SKIP EDIT('STRT ndsk=',NDSK) (A,F(2));
|
|
CALL MOV(NDSK,1,3);
|
|
PUT SKIP EDIT('DONE ndsk=',NDSK, ': maxstk=',MAXSTK,
|
|
' ncall=',NCALL, ' nmove=',NMOVE)
|
|
(2(A,F(2)),2(A,F(10)));
|
|
END;
|
|
DONE:;
|
|
|
|
/* procedure MOV -----------------------------------------------*/
|
|
MOV: PROC(N,F,T) RECURSIVE;
|
|
DCL (N,F,T) BIN FIXED(31);
|
|
DCL O BIN FIXED(31);
|
|
O = 6-(F+T);
|
|
CURSTK = CURSTK + 1;
|
|
NCALL = NCALL + 1;
|
|
MAXSTK = MAX(MAXSTK,CURSTK);
|
|
IF N = 1 THEN DO;
|
|
NMOVE = NMOVE + 1;
|
|
TOW(F) = TOW(F) - 1;
|
|
TOW(T) = TOW(T) + 1;
|
|
IF TRACE > 0 THEN PUT SKIP EDIT('mov-do: ',CURSTK,
|
|
' :',N,F,T, ' :',TOW)
|
|
(A,F(2),2(A,3(X(1),F(2))));
|
|
END;
|
|
ELSE DO;
|
|
IF TRACE > 0 THEN PUT SKIP EDIT('mov-go: ',CURSTK,
|
|
' :',N,F,T, ' :',TOW)
|
|
(A,F(2),2(A,3(X(1),F(2))));
|
|
CALL MOV(N-1,F,O);
|
|
CALL MOV(1,F,T);
|
|
CALL MOV(N-1,O,T);
|
|
END;
|
|
CURSTK = CURSTK - 1;
|
|
END MOV;
|
|
|
|
END TOWH;
|
|
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHPLIT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: towh_pli.pli 981 2018-01-02 13:30:49Z mueller $ */
|
|
/*
|
|
/* Copyright 2017-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2018-01-02 981 1.0 add ON units for ENDFILE and CONVERSION */
|
|
/* 2017-09-07 947 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
TOWH: PROC OPTIONS(MAIN) REORDER;
|
|
DCL (NCALL,NMOVE) BIN FIXED(31) INIT(0);
|
|
DCL (CURSTK,MAXSTK) BIN FIXED(31) INIT(0);
|
|
DCL (MAXDSK,TRACE) BIN FIXED(31) INIT(0);
|
|
DCL TOW(3) BIN FIXED(31) INIT((3)0);
|
|
DCL NDSK BIN FIXED(31);
|
|
|
|
DCL MOV ENTRY(BIN FIXED(31),BIN FIXED(31),BIN FIXED(31));
|
|
|
|
ON ENDFILE(SYSIN) BEGIN;
|
|
PUT SKIP EDIT('Unexpected EOF, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
ON CONVERSION BEGIN;
|
|
PUT SKIP EDIT('Conversion error, abort')(A);
|
|
GOTO DONE;
|
|
END;
|
|
|
|
GET EDIT(MAXDSK,TRACE) (F(5),F(5));
|
|
|
|
DO NDSK=2 TO MAXDSK;
|
|
NCALL = 0;
|
|
NMOVE = 0;
|
|
MAXSTK = 0;
|
|
CURSTK = 0;
|
|
TOW(1) = NDSK;
|
|
TOW(2) = 0;
|
|
TOW(3) = 0;
|
|
IF TRACE > 0 THEN PUT SKIP EDIT('STRT ndsk=',NDSK) (A,F(2));
|
|
CALL MOV(NDSK,1,3);
|
|
PUT SKIP EDIT('DONE ndsk=',NDSK, ': maxstk=',MAXSTK,
|
|
' ncall=',NCALL, ' nmove=',NMOVE)
|
|
(2(A,F(2)),2(A,F(10)));
|
|
END;
|
|
DONE:;
|
|
|
|
/* procedure MOV -----------------------------------------------*/
|
|
MOV: PROC(N,F,T) RECURSIVE;
|
|
DCL (N,F,T) BIN FIXED(31);
|
|
DCL O BIN FIXED(31);
|
|
O = 6-(F+T);
|
|
CURSTK = CURSTK + 1;
|
|
NCALL = NCALL + 1;
|
|
MAXSTK = MAX(MAXSTK,CURSTK);
|
|
IF N = 1 THEN DO;
|
|
NMOVE = NMOVE + 1;
|
|
TOW(F) = TOW(F) - 1;
|
|
TOW(T) = TOW(T) + 1;
|
|
IF TRACE > 0 THEN PUT SKIP EDIT('mov-do: ',CURSTK,
|
|
' :',N,F,T, ' :',TOW)
|
|
(A,F(2),2(A,3(X(1),F(2))));
|
|
END;
|
|
ELSE DO;
|
|
IF TRACE > 0 THEN PUT SKIP EDIT('mov-go: ',CURSTK,
|
|
' :',N,F,T, ' :',TOW)
|
|
(A,F(2),2(A,3(X(1),F(2))));
|
|
CALL MOV(N-1,F,O);
|
|
CALL MOV(1,F,T);
|
|
CALL MOV(N-1,O,T);
|
|
END;
|
|
CURSTK = CURSTK - 1;
|
|
END MOV;
|
|
|
|
END TOWH;
|
|
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHSIMF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1000K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM=NOSUBCHK,
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
COMMENT
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-09-08 950 1.0 Initial version
|
|
*;
|
|
|
|
BEGIN
|
|
INTEGER ncall,nmove;
|
|
INTEGER curstk,maxstk;
|
|
INTEGER maxdsk,trace;
|
|
INTEGER ndsk;
|
|
INTEGER ARRAY tow(1:4);
|
|
|
|
PROCEDURE trc(txt,n,f,t);
|
|
VALUE txt;
|
|
TEXT txt;
|
|
INTEGER n,f,t;
|
|
BEGIN
|
|
OutText(txt);
|
|
OutInt(curstk,2);
|
|
OutText(" :");
|
|
OutInt(n,3);
|
|
OutInt(f,3);
|
|
OutInt(t,3);
|
|
OutText(" :");
|
|
OutInt(tow(1),3);
|
|
OutInt(tow(2),3);
|
|
OutInt(tow(3),3);
|
|
OutImage;
|
|
END;
|
|
|
|
PROCEDURE mov(n,f,t);
|
|
INTEGER n,f,t;
|
|
BEGIN
|
|
INTEGER o;
|
|
o := 6-(f+t);
|
|
curstk := curstk + 1;
|
|
ncall := ncall + 1;
|
|
IF maxstk < curstk THEN maxstk := curstk;
|
|
IF n = 1 THEN BEGIN
|
|
nmove := nmove + 1;
|
|
tow(f) := tow(f) - 1;
|
|
tow(t) := tow(t) + 1;
|
|
IF trace > 0 THEN trc("mov-do: ",n,f,t);
|
|
END ELSE BEGIN;
|
|
IF trace > 0 THEN trc("mov-go: ",n,f,t);
|
|
mov(n-1,f,o);
|
|
mov(1,f,t);
|
|
mov(n-1,o,t);
|
|
END;
|
|
curstk := curstk - 1;
|
|
END;
|
|
|
|
maxdsk := InInt;
|
|
trace := InInt;
|
|
|
|
FOR ndsk := 2 STEP 1 UNTIL maxdsk DO BEGIN
|
|
ncall := 0;
|
|
nmove := 0;
|
|
maxstk := 0;
|
|
curstk := 0;
|
|
tow(1) := ndsk;
|
|
tow(2) := 0;
|
|
tow(3) := 0;
|
|
IF trace > 0 THEN BEGIN
|
|
OutText("STRT ndsk=");
|
|
OutInt(ndsk,2);
|
|
OutImage;
|
|
END;
|
|
mov(ndsk,1,3);
|
|
OutText("DONE ndsk=");
|
|
OutInt(ndsk,2);
|
|
OutText(": maxstk=");
|
|
OutInt(ndsk,2);
|
|
OutText(" ncall=");
|
|
OutInt(ncall,10);
|
|
OutText(" nmove=");
|
|
OutInt(nmove,10);
|
|
OutImage;
|
|
END;
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
22 0
|
|
/*
|
|
//
|
|
./ ADD NAME=TOWHSIMT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//TOWH#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
COMMENT
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-09-08 950 1.0 Initial version
|
|
*;
|
|
|
|
BEGIN
|
|
INTEGER ncall,nmove;
|
|
INTEGER curstk,maxstk;
|
|
INTEGER maxdsk,trace;
|
|
INTEGER ndsk;
|
|
INTEGER ARRAY tow(1:4);
|
|
|
|
PROCEDURE trc(txt,n,f,t);
|
|
VALUE txt;
|
|
TEXT txt;
|
|
INTEGER n,f,t;
|
|
BEGIN
|
|
OutText(txt);
|
|
OutInt(curstk,2);
|
|
OutText(" :");
|
|
OutInt(n,3);
|
|
OutInt(f,3);
|
|
OutInt(t,3);
|
|
OutText(" :");
|
|
OutInt(tow(1),3);
|
|
OutInt(tow(2),3);
|
|
OutInt(tow(3),3);
|
|
OutImage;
|
|
END;
|
|
|
|
PROCEDURE mov(n,f,t);
|
|
INTEGER n,f,t;
|
|
BEGIN
|
|
INTEGER o;
|
|
o := 6-(f+t);
|
|
curstk := curstk + 1;
|
|
ncall := ncall + 1;
|
|
IF maxstk < curstk THEN maxstk := curstk;
|
|
IF n = 1 THEN BEGIN
|
|
nmove := nmove + 1;
|
|
tow(f) := tow(f) - 1;
|
|
tow(t) := tow(t) + 1;
|
|
IF trace > 0 THEN trc("mov-do: ",n,f,t);
|
|
END ELSE BEGIN;
|
|
IF trace > 0 THEN trc("mov-go: ",n,f,t);
|
|
mov(n-1,f,o);
|
|
mov(1,f,t);
|
|
mov(n-1,o,t);
|
|
END;
|
|
curstk := curstk - 1;
|
|
END;
|
|
|
|
maxdsk := InInt;
|
|
trace := InInt;
|
|
|
|
FOR ndsk := 2 STEP 1 UNTIL maxdsk DO BEGIN
|
|
ncall := 0;
|
|
nmove := 0;
|
|
maxstk := 0;
|
|
curstk := 0;
|
|
tow(1) := ndsk;
|
|
tow(2) := 0;
|
|
tow(3) := 0;
|
|
IF trace > 0 THEN BEGIN
|
|
OutText("STRT ndsk=");
|
|
OutInt(ndsk,2);
|
|
OutImage;
|
|
END;
|
|
mov(ndsk,1,3);
|
|
OutText("DONE ndsk=");
|
|
OutInt(ndsk,2);
|
|
OutText(": maxstk=");
|
|
OutInt(ndsk,2);
|
|
OutText(" ncall=");
|
|
OutInt(ncall,10);
|
|
OutText(" nmove=");
|
|
OutInt(nmove,10);
|
|
OutImage;
|
|
END;
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
4 1
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIA60F,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='LONG',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
'COMMENT'
|
|
* $Id: mcpi_a60.a60 978 2017-12-28 21:32:18Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
* 2017-09-17 951 1.0 Initial version
|
|
*;
|
|
|
|
'REAL' RR32,RDIV,PI,RR32I,RDIVI;
|
|
'REAL' RSEED,RLAST;
|
|
'BOOLEAN' RANINI;
|
|
'INTEGER' IDBGRR,IDBGRN,IDBGMC;
|
|
'INTEGER' I,NTRY,NHIT,NGO;
|
|
'REAL' PIEST,PIERR;
|
|
'REAL' RHIT,RTRY;
|
|
'REAL' X,Y,R;
|
|
'REAL' 'ARRAY' RSHUF[0:127];
|
|
|
|
'REAL' 'PROCEDURE' RANRAW;
|
|
'BEGIN'
|
|
'REAL' RFAC,RNEW;
|
|
RNEW := RSEED * 69069.0;
|
|
RFAC := RNEW * RR32I;
|
|
RFAC := ENTIER(RFAC);
|
|
RNEW := RNEW - RFAC * RR32;
|
|
'IF' IDBGRR > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('RR:')');
|
|
OUTREAL(1, RSEED);
|
|
OUTREAL(1, RNEW);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
RSEED := RNEW;
|
|
RANRAW := RNEW;
|
|
'END';
|
|
|
|
'REAL' 'PROCEDURE' RANNUM;
|
|
'BEGIN'
|
|
'REAL' RNEW;
|
|
'INTEGER' I;
|
|
'IF' 'NOT' RANINI 'THEN' 'BEGIN'
|
|
'FOR' I := 0 'STEP' 1 'UNTIL' 127 'DO' RSHUF[I] := RANRAW;
|
|
RANINI := 'TRUE';
|
|
'END';
|
|
|
|
I := ENTIER(RLAST*RDIVI);
|
|
RLAST := RSHUF[I];
|
|
RSHUF[I] := RANRAW;
|
|
RNEW := RLAST * RR32I;
|
|
'IF' IDBGRN > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('RN:')');
|
|
OUTINTEGER(1, I);
|
|
OUTREAL(1, RLAST);
|
|
OUTREAL(1, RNEW);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
RANNUM := RNEW;
|
|
'END';
|
|
|
|
'COMMENT' setup constants;
|
|
RR32 := 4294967296.0;
|
|
RDIV := 33554432.0;
|
|
PI := 3.141592653589793;
|
|
RR32I := 1.0/RR32;
|
|
RDIVI := 1.0/RDIV;
|
|
RSEED := 12345.0;
|
|
RANINI := 'FALSE';
|
|
|
|
'COMMENT' set record lenth = 132 and page length = 64;
|
|
SYSACT(1,6,132);
|
|
SYSACT(1,8,64);
|
|
|
|
ININTEGER(0,IDBGRR);
|
|
ININTEGER(0,IDBGRN);
|
|
ININTEGER(0,IDBGMC);
|
|
|
|
'IF' IDBGRR = 0 'AND' IDBGRN = 0 'AND' IDBGMC = 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'(' ntry nhit')');
|
|
OUTSTRING (1,'(' pi-est pi-err')');
|
|
OUTSTRING (1,'(' seed')');
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
LOOP:
|
|
ININTEGER(0,NGO);
|
|
'IF' NGO = 0 'THEN' 'GOTO' DONE;
|
|
'FOR' I := 1 'STEP' 1 'UNTIL' NGO 'DO' 'BEGIN'
|
|
X := 2.0 * RANNUM - 1.0;
|
|
Y := 2.0 * RANNUM - 1.0;
|
|
R := X*X + Y*Y;
|
|
NTRY := NTRY + 1;
|
|
'IF' R <= 1.0 'THEN' NHIT := NHIT + 1;
|
|
'IF' IDBGMC > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('MC:')');
|
|
OUTREAL(1, X);
|
|
OUTREAL(1, Y);
|
|
OUTREAL(1, R);
|
|
OUTINTEGER(1, NHIT);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
'END';
|
|
|
|
RTRY := NTRY;
|
|
RHIT := NHIT;
|
|
PIEST := 4.0 * (RHIT / RTRY);
|
|
PIERR := PIEST - PI;
|
|
OUTSTRING (1,'('PI:')');
|
|
OUTINTEGER(1, NTRY);
|
|
OUTINTEGER(1, NHIT);
|
|
OUTREAL(1, PIEST);
|
|
OUTREAL(1, PIERR);
|
|
OUTREAL(1, RLAST);
|
|
SYSACT(1,14,1);
|
|
'GOTO' LOOP;
|
|
|
|
DONE:
|
|
'END';
|
|
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIA60T,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#A60 JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ALGOFCLG,
|
|
// PARM.ALGOL='LONG',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO=''
|
|
//ALGOL.SYSIN DD *
|
|
'BEGIN'
|
|
'COMMENT'
|
|
* $Id: mcpi_a60.a60 978 2017-12-28 21:32:18Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
* 2017-09-17 951 1.0 Initial version
|
|
*;
|
|
|
|
'REAL' RR32,RDIV,PI,RR32I,RDIVI;
|
|
'REAL' RSEED,RLAST;
|
|
'BOOLEAN' RANINI;
|
|
'INTEGER' IDBGRR,IDBGRN,IDBGMC;
|
|
'INTEGER' I,NTRY,NHIT,NGO;
|
|
'REAL' PIEST,PIERR;
|
|
'REAL' RHIT,RTRY;
|
|
'REAL' X,Y,R;
|
|
'REAL' 'ARRAY' RSHUF[0:127];
|
|
|
|
'REAL' 'PROCEDURE' RANRAW;
|
|
'BEGIN'
|
|
'REAL' RFAC,RNEW;
|
|
RNEW := RSEED * 69069.0;
|
|
RFAC := RNEW * RR32I;
|
|
RFAC := ENTIER(RFAC);
|
|
RNEW := RNEW - RFAC * RR32;
|
|
'IF' IDBGRR > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('RR:')');
|
|
OUTREAL(1, RSEED);
|
|
OUTREAL(1, RNEW);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
RSEED := RNEW;
|
|
RANRAW := RNEW;
|
|
'END';
|
|
|
|
'REAL' 'PROCEDURE' RANNUM;
|
|
'BEGIN'
|
|
'REAL' RNEW;
|
|
'INTEGER' I;
|
|
'IF' 'NOT' RANINI 'THEN' 'BEGIN'
|
|
'FOR' I := 0 'STEP' 1 'UNTIL' 127 'DO' RSHUF[I] := RANRAW;
|
|
RANINI := 'TRUE';
|
|
'END';
|
|
|
|
I := ENTIER(RLAST*RDIVI);
|
|
RLAST := RSHUF[I];
|
|
RSHUF[I] := RANRAW;
|
|
RNEW := RLAST * RR32I;
|
|
'IF' IDBGRN > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('RN:')');
|
|
OUTINTEGER(1, I);
|
|
OUTREAL(1, RLAST);
|
|
OUTREAL(1, RNEW);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
RANNUM := RNEW;
|
|
'END';
|
|
|
|
'COMMENT' setup constants;
|
|
RR32 := 4294967296.0;
|
|
RDIV := 33554432.0;
|
|
PI := 3.141592653589793;
|
|
RR32I := 1.0/RR32;
|
|
RDIVI := 1.0/RDIV;
|
|
RSEED := 12345.0;
|
|
RANINI := 'FALSE';
|
|
|
|
'COMMENT' set record lenth = 132 and page length = 64;
|
|
SYSACT(1,6,132);
|
|
SYSACT(1,8,64);
|
|
|
|
ININTEGER(0,IDBGRR);
|
|
ININTEGER(0,IDBGRN);
|
|
ININTEGER(0,IDBGMC);
|
|
|
|
'IF' IDBGRR = 0 'AND' IDBGRN = 0 'AND' IDBGMC = 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'(' ntry nhit')');
|
|
OUTSTRING (1,'(' pi-est pi-err')');
|
|
OUTSTRING (1,'(' seed')');
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
|
|
LOOP:
|
|
ININTEGER(0,NGO);
|
|
'IF' NGO = 0 'THEN' 'GOTO' DONE;
|
|
'FOR' I := 1 'STEP' 1 'UNTIL' NGO 'DO' 'BEGIN'
|
|
X := 2.0 * RANNUM - 1.0;
|
|
Y := 2.0 * RANNUM - 1.0;
|
|
R := X*X + Y*Y;
|
|
NTRY := NTRY + 1;
|
|
'IF' R <= 1.0 'THEN' NHIT := NHIT + 1;
|
|
'IF' IDBGMC > 0 'THEN' 'BEGIN'
|
|
OUTSTRING (1,'('MC:')');
|
|
OUTREAL(1, X);
|
|
OUTREAL(1, Y);
|
|
OUTREAL(1, R);
|
|
OUTINTEGER(1, NHIT);
|
|
SYSACT(1,14,1);
|
|
'END';
|
|
'END';
|
|
|
|
RTRY := NTRY;
|
|
RHIT := NHIT;
|
|
PIEST := 4.0 * (RHIT / RTRY);
|
|
PIERR := PIEST - PI;
|
|
OUTSTRING (1,'('PI:')');
|
|
OUTINTEGER(1, NTRY);
|
|
OUTINTEGER(1, NHIT);
|
|
OUTREAL(1, PIEST);
|
|
OUTREAL(1, PIERR);
|
|
OUTREAL(1, RLAST);
|
|
SYSACT(1,14,1);
|
|
'GOTO' LOOP;
|
|
|
|
DONE:
|
|
'END';
|
|
|
|
/*
|
|
//GO.ALGLDD01 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIASMF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=128K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NOLIST,NOXREF,NORLD,NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: mcpi_asm.asm 979 2017-12-29 18:40:40Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-29 979 1.2 some more code optimizations
|
|
* 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
* 2017-11-12 961 1.0 Initial version
|
|
* 2017-10-10 955 0.1 First draft
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Prime number search
|
|
* RC = 0 ok
|
|
* RC = 8 unexpected SYSIN EOF
|
|
* RC = 12 open SYSIN failed
|
|
* RC = 16 open SYSPRINT failed
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'0C'
|
|
B EXIT quit with RC=12
|
|
IOPENOK EQU *
|
|
*
|
|
LD FR0,=D'1.'
|
|
LDR FR2,FR0
|
|
DD FR0,RR32
|
|
STD FR0,RR32I RR32I = 1./RR32
|
|
*
|
|
* read debug flags ----------------------------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,IDBGRR
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,IDBGRN
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,IDBGMC
|
|
MVI IEOFOK,X'01' expect EOF from now on
|
|
*
|
|
CLI IDBGRR,X'00' if any trace skip header print
|
|
BNE NOHDPRT
|
|
CLI IDBGRN,X'00'
|
|
BNE NOHDPRT
|
|
CLI IDBGMC,X'00'
|
|
BNE NOHDPRT
|
|
L R1,MSGHD1
|
|
BAL R14,OTEXT
|
|
L R1,MSGHD2
|
|
BAL R14,OTEXT
|
|
BAL R14,OPUTLINE write header
|
|
NOHDPRT EQU *
|
|
*
|
|
* main body -----------------------------------------------------------
|
|
*
|
|
* outer loop
|
|
*
|
|
XR R3,R3 ntry = 0
|
|
XR R4,R4 nhit = 0
|
|
*
|
|
OLOOP BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get PRNT
|
|
LTR R1,R1 is ngo == 0
|
|
BE OLOOPE if = yes, quit outer loop
|
|
*
|
|
* inner loop
|
|
*
|
|
LR R2,R1 loop counter
|
|
*
|
|
ILOOP EQU *
|
|
BAL R8,RANNUM
|
|
MD FR0,=D'2.'
|
|
SD FR0,=D'1.'
|
|
STD FR0,X
|
|
BAL R8,RANNUM
|
|
MD FR0,=D'2.'
|
|
SD FR0,=D'1.'
|
|
STD FR0,Y
|
|
MDR FR0,FR0
|
|
LD FR2,X
|
|
MDR FR2,FR2
|
|
ADR FR0,FR2
|
|
STD FR0,R
|
|
A R3,=F'1'
|
|
CD FR0,=D'1.'
|
|
BH CMISS
|
|
A R4,=F'1'
|
|
CMISS EQU *
|
|
CLI IDBGMC,X'00'
|
|
BE NODBGMC
|
|
L R1,MSGMC
|
|
BAL R14,OTEXT print "MC: "
|
|
LD FR0,X
|
|
BAL R14,OFIX1308 print x
|
|
LD FR0,Y
|
|
BAL R14,OFIX1308 print y
|
|
LD FR0,R
|
|
BAL R14,OFIX1308 print r
|
|
LR R1,R4
|
|
BAL R14,OINT10 print nhit
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
NODBGMC EQU *
|
|
BCT R2,ILOOP
|
|
*
|
|
L R0,ODNZERO
|
|
ST R0,ODTEMP
|
|
ST R4,ODTEMP+4 nhit as denorm float
|
|
SDR FR0,FR0 FR0 := 0.
|
|
AD FR0,ODTEMP add to re-normalize, FR0:=nhit
|
|
ST R3,ODTEMP+4 ntry as denorm float
|
|
SDR FR2,FR2 FR2 := 0.
|
|
AD FR2,ODTEMP add to re-normalize, FR2:=ntry
|
|
DDR FR0,FR2 nhit/ntry
|
|
MD FR0,=D'4.' piest = 4.*nhit/ntry
|
|
STD FR0,PIEST
|
|
SD FR0,PI piest - pi
|
|
LPDR FR0,FR0 pierr = abs(piest - pi)
|
|
STD FR0,PIERR
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "PI: "
|
|
LR R1,R3
|
|
BAL R14,OINT10 print ntry
|
|
LR R1,R4
|
|
BAL R14,OINT10 print nhit
|
|
LD FR0,PIEST
|
|
BAL R14,OFIX1308 print piest
|
|
LD R0,PIERR
|
|
BAL R14,OFIX1308 print pierr
|
|
LD FR0,RLAST
|
|
BAL R14,OFIX1200 print rlast
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
B OLOOP
|
|
OLOOPE EQU *
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R13,SAVE+4 get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* RANNUM --------------------------------------------------------------
|
|
* uses all float regs
|
|
* uses R0,R1,R6,R7,R8,R9,R14,R15
|
|
* keeps R2-R5,R10-R11
|
|
*
|
|
RANNUM CLI RANINI,X'00' init done ?
|
|
BNE RANNUMGO if != yes
|
|
*
|
|
L R6,=A(RSHUF) pointer to rshuf
|
|
LA R7,128 loop count
|
|
RANNUML BAL R9,RANRAW get raw
|
|
STD FR0,0(R6) store
|
|
LA R6,8(R6) push pointer
|
|
BCT R7,RANNUML and loop
|
|
MVI RANINI,X'01' ranini = true
|
|
*
|
|
RANNUMGO L R6,=A(RSHUF) pointer to rshuf
|
|
LD FR0,RLAST
|
|
AW FR0,ODNZERO denormalize
|
|
STD FR0,RFAC1
|
|
L R7,RFAC1+4 int(rlast)
|
|
SRL R7,25 int(rlast/rdiv)
|
|
SLA R7,3 convert index to offset
|
|
LD FR0,0(R7,R6) rshuf[i]
|
|
STD FR0,RLAST rlast = rshuf[i]
|
|
BAL R9,RANRAW get new random number
|
|
STD FR0,0(R7,R6) rshuf[i] = ranraw()
|
|
LD FR0,RLAST
|
|
MD FR0,RR32I rlast*rr32i
|
|
CLI IDBGRN,X'00' RN trace ?
|
|
BE RANNUMNT
|
|
*
|
|
STD FR0,RNEW save rnew
|
|
L R1,MSGRN
|
|
BAL R14,OTEXT print "RN: "
|
|
LR R1,R7
|
|
SRA R1,3 convert back to index
|
|
BAL R14,OINT10 print i
|
|
LD FR0,RLAST
|
|
BAL R14,OFIX1200 print rlast
|
|
LD FR0,RNEW
|
|
BAL R14,OFIX1308 print rnew
|
|
BAL R14,OPUTLINE write line
|
|
LD FR0,RNEW restore rnew
|
|
*
|
|
RANNUMNT EQU *
|
|
*
|
|
BR R8
|
|
*
|
|
* RANRAW --------------------------------------------------------------
|
|
* uses all float regs
|
|
* uses R0,R1,R14,R15
|
|
* keeps R2-R11
|
|
|
|
RANRAW LD FR0,RSEED
|
|
MD FR0,RFACTOR rnew1 = rseed * 69069.
|
|
LDR FR6,FR0 save rnew1
|
|
LDR FR2,FR0 rmsb = rnew1
|
|
AW FR2,ODNZERO denormalize
|
|
STD FR2,RFAC1 save
|
|
XR R1,R1 R1:=0
|
|
ST R1,RFAC1+4 clear lower 32 bits of rmsb
|
|
SD FR0,RFAC1 rnew = rnew1 modulo 2^32 !!
|
|
STD FR0,RNEW
|
|
CLI IDBGRR,X'00' RR trace ?
|
|
BE RANRAWNT
|
|
*
|
|
STD FR4,RFAC really save rfac
|
|
STD FR6,RNEW1 really save rnew1
|
|
L R1,MSGRR
|
|
BAL R14,OTEXT print "RR: "
|
|
LD FR0,RSEED
|
|
BAL R14,OFIX1200 print rseed
|
|
LD FR0,RNEW
|
|
BAL R14,OFIX1200 print rnew
|
|
L R1,MSGCSEP
|
|
BAL R14,OTEXT print " : "
|
|
L R1,RFAC+4
|
|
BAL R14,OINT10 print ifac
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
RANRAWNT LD FR0,RNEW
|
|
STD FR0,RSEED
|
|
BR R9
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
*
|
|
* OHEX10 ---------------------------------------------------
|
|
* print integer, like C " %8.8x" format
|
|
*
|
|
OHEX10 ST R14,OHEX10L save R14
|
|
L R15,OLPTR R15 points to edit position
|
|
LA R15,2(R15) add two blanks
|
|
LA R14,8(R15) end of buffer
|
|
*
|
|
OHEX10NL XR R0,R0 R0 := 0
|
|
SLDA R0,4 get next 4 bits into R0
|
|
AH R0,=X'00F0' add '0'
|
|
CH R0,=X'00F9' above 9 ?
|
|
BNH OHEX10OK if <= no, skip A-F correction
|
|
SH R0,=X'0039' sub (0xF0('0')+10)-0xC1('A')=0x39
|
|
OHEX10OK STC R0,0(R15) store hex digit
|
|
LA R15,1(R15) push pointer
|
|
CR R15,R14 beyond end ?
|
|
BL OHEX10NL if < not, do next nibble
|
|
*
|
|
ST R15,OLPTR store pointer
|
|
L R14,OHEX10L restore R14 linkage
|
|
BR R14
|
|
*
|
|
OHEX10L DS F save area for R14 (return linkage)
|
|
*
|
|
* OHEX210 --------------------------------------------------
|
|
* print 64 field as two 32 bit hex numbers
|
|
* R1 points to memory location of 64 bit value
|
|
* rendered as " %8.8x %8.8x"
|
|
*
|
|
OHEX210 ST R14,OHEX210L save R14
|
|
ST R1,OHEX210V save R1
|
|
L R1,0(R1) get high part
|
|
BAL R14,OHEX10 convert
|
|
L R1,OHEX210V
|
|
L R1,4(R1) get low part
|
|
BAL R14,OHEX10 convert
|
|
L R14,OHEX210L restore R14 linkage
|
|
BR R14 and return
|
|
*
|
|
OHEX210L DS F save area for R14 (return linkage)
|
|
OHEX210V DS F save area for R1 (value ptr)
|
|
*
|
|
* OFIX1308, OFIX1306 - -------------------------------------
|
|
* print double, like
|
|
* OFIX1308: PL/I F(13,8) or C %13.8f format
|
|
* OFIX1306: PL/I F(13,6) or C %13.6f format
|
|
* input value in floating reg FR0
|
|
* handles signed numbers
|
|
*
|
|
OFIX1308 MD FR0,=D'1.E8' 'shift' 8 digits left
|
|
LA R1,OEF1308 pointer to edit pattern
|
|
LA R0,3 offset to one behind X'21' position
|
|
B OFIX13XX
|
|
*
|
|
OFIX1306 MD FR0,=D'1.E6' 'shift' 6 digits left
|
|
LA R1,OEF1306 pointer to edit pattern
|
|
LA R0,5 offset to one behind X'21' position
|
|
*
|
|
OFIX13XX LPDR FR2,FR0 get abbs() value
|
|
CD FR2,=D'2.E9' too large ?
|
|
BNL OFX13XXF if >= yes, do OSFILL
|
|
*
|
|
LDR FR4,FR2
|
|
AW FR4,ODNZERO FR4 := de-normalized FR2
|
|
SDR FR6,FR6 FR6 := 0.
|
|
ADR FR6,FR4 get integer part
|
|
SDR FR2,FR4 get fractional part
|
|
CD FR2,=D'0.5' check if >= 0.5
|
|
BL OFX13XXR if < no need to round up
|
|
AW FR4,ODNONE otherwise add LSB DENORM
|
|
OFX13XXR STD FR4,ODTEMP roll-out to memory
|
|
L R15,ODTEMP+4 get integer part
|
|
CVD R15,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEF13XXL,R15),0(R1) setup pattern
|
|
LR R1,R15 setup R1 in case of miss
|
|
AR R1,R0 to one behind X'21' position
|
|
EDMK 0(OEF13XXL,R15),OCVD+2 and edit (and set R1)
|
|
LTDR FR0,FR0 negative number ?
|
|
BNM OFX13XXP if >= not
|
|
BCTR R1,0 decrement pointer
|
|
MVI 0(R1),C'-' write '-' sign
|
|
OFX13XXP LA R15,OEF13XXL(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OFX13XXF LA R1,OEF13XXL
|
|
B OSFILL
|
|
*
|
|
OEF1306 DC C' ',3X'20',X'21',X'20',C'.',6X'20' pat: bddd(d.dddddd
|
|
OEF1308 DC C' ',1X'20',X'21',X'20',C'.',8X'20' pat: bd(d.dddddddd
|
|
OEF13XXL EQU *-OEF1308
|
|
|
|
*
|
|
* OFIX1200 -------------------------------------------------
|
|
* print double, like PL/I F(12,0) or C %12.0f format
|
|
* input value in floating reg FR0
|
|
* only for non-negatve numbers
|
|
*
|
|
OFIX1200 LTDR FR0,FR0 check whether negative
|
|
BL OFX1200F if < yes, do OSFILL
|
|
CD FR0,=D'99999999999.' too large ?
|
|
BH OFX1200F if > yes, do OSFILL
|
|
AW FR0,ODNZERO de-normalize
|
|
STD FR0,ODTEMP roll-out to memory
|
|
L R1,ODTEMP+4
|
|
L R0,ODTEMP
|
|
N R0,=X'00FFFFFF'
|
|
D R0,=F'100000000' now R0 lower 9, R1 upper digits
|
|
CVD R0,OCVD BCD convert lower part
|
|
L R15,OLPTR R15 points to edit position
|
|
LA R15,2(R15) add two blanks
|
|
LTR R1,R1 upper != 0
|
|
BNZ OFX1200B if != yes, handle large number
|
|
*
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern (from OINT10)
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OFX1200B EQU *
|
|
MVC 0(OEF10LL,R15),OEF10L setup pattern
|
|
ED 0(OEF10LL,R15),OCVD+3 and edit
|
|
CVD R1,OCVD BCD convert upper part
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEF10UL,R15),OEF10U setup pattern
|
|
ED 0(OEF10UL,R15),OCVD+6 and edit
|
|
LA R15,12(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OFX1200F LA R1,12
|
|
B OSFILL
|
|
*
|
|
OEF10L DC C' ',X'21',8X'20' pat: b(dddddddd
|
|
OEF10LL EQU *-OEF10L
|
|
OEF10U DC C' ',X'20',X'21',X'20' pat: bd(d
|
|
OEF10UL EQU *-OEF10U
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT10 ---------------------------------------------------
|
|
* read integer, like PL/I F(10) or C %10d format
|
|
*
|
|
IINT10 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(10,R15) pack next 10 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,10(R15) push pointer by 10 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
SAVE DS 18F local save area
|
|
RC DC F'0' return code
|
|
IDBGRR DC X'00' trace RR enable
|
|
IDBGRN DC X'00' trace RN enable
|
|
IDBGMC DC X'00' trace MC enable
|
|
RANINI DC X'00' init RSHUF done flag
|
|
DS 0D
|
|
RFACTOR DC D'69069.'
|
|
RSEED DC D'12345.'
|
|
RLAST DC D'0.'
|
|
RR32 DC D'4294967296.' is 4*1024*1024*1024
|
|
RR32I DS D
|
|
RNEW DS D
|
|
RNEW1 DS D
|
|
RFAC DS D
|
|
RFAC1 DS D
|
|
*
|
|
PI DC D'3.141592653589793'
|
|
PIEST DS D
|
|
PIERR DS D
|
|
*
|
|
X DS D
|
|
Y DS D
|
|
R DS D
|
|
*
|
|
* message strings
|
|
*
|
|
MSGHD1 OTXTDSC C' ntry nhit pi-est'
|
|
MSGHD2 OTXTDSC C' pi-err seed'
|
|
MSGMC OTXTDSC C'MC: '
|
|
MSGPI OTXTDSC C'PI: '
|
|
MSGRR OTXTDSC C'RR: '
|
|
MSGRN OTXTDSC C'RN: '
|
|
MSGCSEP OTXTDSC C' : '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* data section
|
|
*
|
|
DATA CSECT
|
|
RSHUF DS 128D
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
FR0 EQU 0
|
|
FR2 EQU 2
|
|
FR4 EQU 4
|
|
FR6 EQU 6
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIASMT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#ASM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=128K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC ASMFCLG,
|
|
// MAC1='SYS2.MACLIB',
|
|
// PARM.ASM='NODECK,LOAD',
|
|
// PARM.LKED='MAP,LIST,LET,NCAL',
|
|
// COND.LKED=(8,LE,ASM),
|
|
// PARM.GO='',
|
|
// COND.GO=((8,LE,ASM),(4,LT,LKED))
|
|
//ASM.SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(1700,(600,100))
|
|
//ASM.SYSUT2 DD DSN=&&SYSUT2,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSUT3 DD DSN=&&SYSUT3,UNIT=SYSDA,SPACE=(1700,(300,50))
|
|
//ASM.SYSGO DD DSN=&&OBJSET,UNIT=SYSDA,SPACE=(80,(2000,500))
|
|
//ASM.SYSIN DD *
|
|
* 1 2 3 4 5 6 71
|
|
*23456789*12345*789012345678901234*678901234567890123456789012345678901
|
|
* $Id: mcpi_asm.asm 979 2017-12-29 18:40:40Z mueller $
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software; you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-29 979 1.2 some more code optimizations
|
|
* 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
* 2017-11-12 961 1.0 Initial version
|
|
* 2017-10-10 955 0.1 First draft
|
|
*
|
|
PRINT NOGEN don't show macro expansions
|
|
*
|
|
* Prime number search
|
|
* RC = 0 ok
|
|
* RC = 8 unexpected SYSIN EOF
|
|
* RC = 12 open SYSIN failed
|
|
* RC = 16 open SYSPRINT failed
|
|
*
|
|
* local macros --------------------------------------------------------
|
|
*
|
|
*
|
|
* OTXTDSC - setup text descriptor for simple output system -
|
|
*
|
|
MACRO
|
|
&LABEL OTXTDSC &TEXT
|
|
TEXT CSECT
|
|
SPTR&SYSNDX DC &TEXT
|
|
&SYSECT CSECT
|
|
DS 0F
|
|
&LABEL DC AL1(L'SPTR&SYSNDX),AL3(SPTR&SYSNDX)
|
|
MEND
|
|
*
|
|
* main preamble -------------------------------------------------------
|
|
*
|
|
MAIN START 0 start main code csect at base 0
|
|
SAVE (14,12) Save input registers
|
|
LR R12,R15 base register := entry address
|
|
USING MAIN,R12 declare base register
|
|
ST R13,SAVE+4 set back pointer in current save area
|
|
LR R2,R13 remember callers save area
|
|
LA R13,SAVE setup current save area
|
|
ST R13,8(R2) set forw pointer in callers save area
|
|
*
|
|
* open datasets -------------------------------------------------------
|
|
*
|
|
OPEN (SYSPRINT,OUTPUT) open SYSPRINT
|
|
LTR R15,R15 test return code
|
|
BE OOPENOK
|
|
MVI RC+3,X'10'
|
|
B EXIT quit with RC=16
|
|
OOPENOK OPEN (SYSIN,INPUT) open SYSIN
|
|
LTR R15,R15 test return code
|
|
BE IOPENOK
|
|
MVI RC+3,X'0C'
|
|
B EXIT quit with RC=12
|
|
IOPENOK EQU *
|
|
*
|
|
LD FR0,=D'1.'
|
|
LDR FR2,FR0
|
|
DD FR0,RR32
|
|
STD FR0,RR32I RR32I = 1./RR32
|
|
*
|
|
* read debug flags ----------------------------------------------------
|
|
*
|
|
BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,IDBGRR
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,IDBGRN
|
|
BAL R14,IINT10 get PRNT
|
|
STC R1,IDBGMC
|
|
MVI IEOFOK,X'01' expect EOF from now on
|
|
*
|
|
CLI IDBGRR,X'00' if any trace skip header print
|
|
BNE NOHDPRT
|
|
CLI IDBGRN,X'00'
|
|
BNE NOHDPRT
|
|
CLI IDBGMC,X'00'
|
|
BNE NOHDPRT
|
|
L R1,MSGHD1
|
|
BAL R14,OTEXT
|
|
L R1,MSGHD2
|
|
BAL R14,OTEXT
|
|
BAL R14,OPUTLINE write header
|
|
NOHDPRT EQU *
|
|
*
|
|
* main body -----------------------------------------------------------
|
|
*
|
|
* outer loop
|
|
*
|
|
XR R3,R3 ntry = 0
|
|
XR R4,R4 nhit = 0
|
|
*
|
|
OLOOP BAL R14,IGETLINE read input line
|
|
BAL R14,IINT10 get PRNT
|
|
LTR R1,R1 is ngo == 0
|
|
BE OLOOPE if = yes, quit outer loop
|
|
*
|
|
* inner loop
|
|
*
|
|
LR R2,R1 loop counter
|
|
*
|
|
ILOOP EQU *
|
|
BAL R8,RANNUM
|
|
MD FR0,=D'2.'
|
|
SD FR0,=D'1.'
|
|
STD FR0,X
|
|
BAL R8,RANNUM
|
|
MD FR0,=D'2.'
|
|
SD FR0,=D'1.'
|
|
STD FR0,Y
|
|
MDR FR0,FR0
|
|
LD FR2,X
|
|
MDR FR2,FR2
|
|
ADR FR0,FR2
|
|
STD FR0,R
|
|
A R3,=F'1'
|
|
CD FR0,=D'1.'
|
|
BH CMISS
|
|
A R4,=F'1'
|
|
CMISS EQU *
|
|
CLI IDBGMC,X'00'
|
|
BE NODBGMC
|
|
L R1,MSGMC
|
|
BAL R14,OTEXT print "MC: "
|
|
LD FR0,X
|
|
BAL R14,OFIX1308 print x
|
|
LD FR0,Y
|
|
BAL R14,OFIX1308 print y
|
|
LD FR0,R
|
|
BAL R14,OFIX1308 print r
|
|
LR R1,R4
|
|
BAL R14,OINT10 print nhit
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
NODBGMC EQU *
|
|
BCT R2,ILOOP
|
|
*
|
|
L R0,ODNZERO
|
|
ST R0,ODTEMP
|
|
ST R4,ODTEMP+4 nhit as denorm float
|
|
SDR FR0,FR0 FR0 := 0.
|
|
AD FR0,ODTEMP add to re-normalize, FR0:=nhit
|
|
ST R3,ODTEMP+4 ntry as denorm float
|
|
SDR FR2,FR2 FR2 := 0.
|
|
AD FR2,ODTEMP add to re-normalize, FR2:=ntry
|
|
DDR FR0,FR2 nhit/ntry
|
|
MD FR0,=D'4.' piest = 4.*nhit/ntry
|
|
STD FR0,PIEST
|
|
SD FR0,PI piest - pi
|
|
LPDR FR0,FR0 pierr = abs(piest - pi)
|
|
STD FR0,PIERR
|
|
*
|
|
L R1,MSGPI
|
|
BAL R14,OTEXT print "PI: "
|
|
LR R1,R3
|
|
BAL R14,OINT10 print ntry
|
|
LR R1,R4
|
|
BAL R14,OINT10 print nhit
|
|
LD FR0,PIEST
|
|
BAL R14,OFIX1308 print piest
|
|
LD R0,PIERR
|
|
BAL R14,OFIX1308 print pierr
|
|
LD FR0,RLAST
|
|
BAL R14,OFIX1200 print rlast
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
B OLOOP
|
|
OLOOPE EQU *
|
|
*
|
|
* close datasets and return to OS -------------------------------------
|
|
*
|
|
EXIT CLOSE SYSPRINT close SYSPRINT
|
|
CLOSE SYSIN close SYSIN
|
|
L R13,SAVE+4 get old save area back
|
|
L R0,RC get return code
|
|
ST R0,16(R13) store in old save R15
|
|
RETURN (14,12) return to OS (will setup RC)
|
|
*
|
|
* RANNUM --------------------------------------------------------------
|
|
* uses all float regs
|
|
* uses R0,R1,R6,R7,R8,R9,R14,R15
|
|
* keeps R2-R5,R10-R11
|
|
*
|
|
RANNUM CLI RANINI,X'00' init done ?
|
|
BNE RANNUMGO if != yes
|
|
*
|
|
L R6,=A(RSHUF) pointer to rshuf
|
|
LA R7,128 loop count
|
|
RANNUML BAL R9,RANRAW get raw
|
|
STD FR0,0(R6) store
|
|
LA R6,8(R6) push pointer
|
|
BCT R7,RANNUML and loop
|
|
MVI RANINI,X'01' ranini = true
|
|
*
|
|
RANNUMGO L R6,=A(RSHUF) pointer to rshuf
|
|
LD FR0,RLAST
|
|
AW FR0,ODNZERO denormalize
|
|
STD FR0,RFAC1
|
|
L R7,RFAC1+4 int(rlast)
|
|
SRL R7,25 int(rlast/rdiv)
|
|
SLA R7,3 convert index to offset
|
|
LD FR0,0(R7,R6) rshuf[i]
|
|
STD FR0,RLAST rlast = rshuf[i]
|
|
BAL R9,RANRAW get new random number
|
|
STD FR0,0(R7,R6) rshuf[i] = ranraw()
|
|
LD FR0,RLAST
|
|
MD FR0,RR32I rlast*rr32i
|
|
CLI IDBGRN,X'00' RN trace ?
|
|
BE RANNUMNT
|
|
*
|
|
STD FR0,RNEW save rnew
|
|
L R1,MSGRN
|
|
BAL R14,OTEXT print "RN: "
|
|
LR R1,R7
|
|
SRA R1,3 convert back to index
|
|
BAL R14,OINT10 print i
|
|
LD FR0,RLAST
|
|
BAL R14,OFIX1200 print rlast
|
|
LD FR0,RNEW
|
|
BAL R14,OFIX1308 print rnew
|
|
BAL R14,OPUTLINE write line
|
|
LD FR0,RNEW restore rnew
|
|
*
|
|
RANNUMNT EQU *
|
|
*
|
|
BR R8
|
|
*
|
|
* RANRAW --------------------------------------------------------------
|
|
* uses all float regs
|
|
* uses R0,R1,R14,R15
|
|
* keeps R2-R11
|
|
|
|
RANRAW LD FR0,RSEED
|
|
MD FR0,RFACTOR rnew1 = rseed * 69069.
|
|
LDR FR6,FR0 save rnew1
|
|
LDR FR2,FR0 rmsb = rnew1
|
|
AW FR2,ODNZERO denormalize
|
|
STD FR2,RFAC1 save
|
|
XR R1,R1 R1:=0
|
|
ST R1,RFAC1+4 clear lower 32 bits of rmsb
|
|
SD FR0,RFAC1 rnew = rnew1 modulo 2^32 !!
|
|
STD FR0,RNEW
|
|
CLI IDBGRR,X'00' RR trace ?
|
|
BE RANRAWNT
|
|
*
|
|
STD FR4,RFAC really save rfac
|
|
STD FR6,RNEW1 really save rnew1
|
|
L R1,MSGRR
|
|
BAL R14,OTEXT print "RR: "
|
|
LD FR0,RSEED
|
|
BAL R14,OFIX1200 print rseed
|
|
LD FR0,RNEW
|
|
BAL R14,OFIX1200 print rnew
|
|
L R1,MSGCSEP
|
|
BAL R14,OTEXT print " : "
|
|
L R1,RFAC+4
|
|
BAL R14,OINT10 print ifac
|
|
BAL R14,OPUTLINE write line
|
|
*
|
|
RANRAWNT LD FR0,RNEW
|
|
STD FR0,RSEED
|
|
BR R9
|
|
*
|
|
* include simple output system ----------------------------------------
|
|
*
|
|
* simple output system procedures -------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* OSKIP02 --------------------------------------------------
|
|
* add 2 blanks
|
|
*
|
|
OSKIP02 LA R1,2
|
|
*
|
|
* OSKIP ----------------------------------------------------
|
|
* add blanks, count in R1
|
|
*
|
|
OSKIP A R1,OLPTR new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTAB ----------------------------------------------------
|
|
* set output column, position in R1
|
|
*
|
|
OTAB A R1,=A(OLBUF+1) new edit position
|
|
ST R1,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OSFILL ---------------------------------------------------
|
|
* add " ***" pattern, total length in R1
|
|
*
|
|
OSFILL L R15,OLPTR R15 points to edit position
|
|
MVI 0(R15),C' ' initial blank
|
|
B OSFILLN
|
|
OSFILLL MVI 0(R15),C'*' further '*'
|
|
OSFILLN LA R15,1(R15)
|
|
BCT R1,OSFILLL
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
* OTEXT ----------------------------------------------------
|
|
* print text, R1 hold descriptor address
|
|
* descriptor format
|
|
* DC AL1(<length of string>)
|
|
* DC AL2(<address of string>)
|
|
*
|
|
OTEXT ST R14,OTEXTL save R14
|
|
LR R14,R1
|
|
SRL R14,24 R14 now string length
|
|
L R15,OLPTR R15 points to edit position
|
|
LR R0,R15 R0 too
|
|
AR R0,R14 push pointer, add length
|
|
ST R0,OLPTR store pointer
|
|
BCTR R14,0 decrement length for EX
|
|
EX R14,OTEXTMVC copy string via EX:MVC
|
|
L R14,OTEXTL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OTEXTMVC MVC 0(1,R15),0(R1) length via EX, dst R15, src R1
|
|
OTEXTL DS F save area for R14 (return linkage)
|
|
*
|
|
* OPUTLINE -------------------------------------------------
|
|
* write line to SYSPRINT
|
|
*
|
|
OPUTLINE ST R14,OPUTLNEL save R14
|
|
L R15,=A(OLBUF)
|
|
CLI 133(R15),X'00' check fence byte
|
|
BNE OPUTLNEA crash if fence blown
|
|
L R1,=A(SYSPRINT) R1 point to DCB
|
|
LR R0,R15 R1 point to buffer
|
|
PUT (1),(0) write line
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
MVI 0(R15),C' ' blank OLBUF(0)
|
|
MVC 1(L'OLBUF-1,R15),0(R15) propagate blank
|
|
LA R15,1(R15) point to 1st print char in OLBUF
|
|
ST R15,OLPTR reset current position pointer
|
|
LA R15,1
|
|
AH R15,OLCNT increment line counter
|
|
STH R15,OLCNT
|
|
SH R15,OLMAX R15 := OLCNT-OLMAX
|
|
BL OPUTLNES if < no new page
|
|
XR R15,R15 R15 := 0
|
|
SH R15,OLCNT clear line counter
|
|
L R15,=A(OLBUF) point to CC of OLBUF
|
|
* MVI 0(R15),C'1' set new page CC in OLBUF
|
|
OPUTLNES L R14,OPUTLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
OPUTLNEA ABEND 255 abend in case of errors
|
|
*
|
|
OPUTLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
OLPTR DC A(OLBUF+1) current output line position
|
|
OLCNT DC H'0' line counter
|
|
OLMAX DC H'60' lines per page
|
|
OCVD DS D buffer for CVD (8 byte, DW aligned)
|
|
*
|
|
ODTEMP DS D double buffer for conversions
|
|
ODNZERO DC X'4E000000',X'00000000' denormalized double zero
|
|
ODNONE DC X'4E000000',X'00000001' denormalized double one
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSPRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT, X
|
|
RECFM=FBA,LRECL=133,BLKSIZE=0
|
|
OLBUF DC CL133' ',X'00' output line buffer and fence byte
|
|
*
|
|
MAIN CSECT
|
|
*
|
|
* OINT10 ---------------------------------------------------
|
|
* print integer, like PL/I F(10) or C %10d format
|
|
* very fast, for non-negative numbers only !
|
|
*
|
|
OINT10 CL R1,=F'999999999' too large ?
|
|
BH OINT10F if > yes, do OSFILL
|
|
CVD R1,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OINT10F LA R1,10
|
|
B OSFILL
|
|
*
|
|
OEI10 DC C' ',7X'20',X'21',X'20' pat: bddddddd(d
|
|
OEI10L EQU *-OEI10
|
|
*
|
|
* OHEX10 ---------------------------------------------------
|
|
* print integer, like C " %8.8x" format
|
|
*
|
|
OHEX10 ST R14,OHEX10L save R14
|
|
L R15,OLPTR R15 points to edit position
|
|
LA R15,2(R15) add two blanks
|
|
LA R14,8(R15) end of buffer
|
|
*
|
|
OHEX10NL XR R0,R0 R0 := 0
|
|
SLDA R0,4 get next 4 bits into R0
|
|
AH R0,=X'00F0' add '0'
|
|
CH R0,=X'00F9' above 9 ?
|
|
BNH OHEX10OK if <= no, skip A-F correction
|
|
SH R0,=X'0039' sub (0xF0('0')+10)-0xC1('A')=0x39
|
|
OHEX10OK STC R0,0(R15) store hex digit
|
|
LA R15,1(R15) push pointer
|
|
CR R15,R14 beyond end ?
|
|
BL OHEX10NL if < not, do next nibble
|
|
*
|
|
ST R15,OLPTR store pointer
|
|
L R14,OHEX10L restore R14 linkage
|
|
BR R14
|
|
*
|
|
OHEX10L DS F save area for R14 (return linkage)
|
|
*
|
|
* OHEX210 --------------------------------------------------
|
|
* print 64 field as two 32 bit hex numbers
|
|
* R1 points to memory location of 64 bit value
|
|
* rendered as " %8.8x %8.8x"
|
|
*
|
|
OHEX210 ST R14,OHEX210L save R14
|
|
ST R1,OHEX210V save R1
|
|
L R1,0(R1) get high part
|
|
BAL R14,OHEX10 convert
|
|
L R1,OHEX210V
|
|
L R1,4(R1) get low part
|
|
BAL R14,OHEX10 convert
|
|
L R14,OHEX210L restore R14 linkage
|
|
BR R14 and return
|
|
*
|
|
OHEX210L DS F save area for R14 (return linkage)
|
|
OHEX210V DS F save area for R1 (value ptr)
|
|
*
|
|
* OFIX1308, OFIX1306 - -------------------------------------
|
|
* print double, like
|
|
* OFIX1308: PL/I F(13,8) or C %13.8f format
|
|
* OFIX1306: PL/I F(13,6) or C %13.6f format
|
|
* input value in floating reg FR0
|
|
* handles signed numbers
|
|
*
|
|
OFIX1308 MD FR0,=D'1.E8' 'shift' 8 digits left
|
|
LA R1,OEF1308 pointer to edit pattern
|
|
LA R0,3 offset to one behind X'21' position
|
|
B OFIX13XX
|
|
*
|
|
OFIX1306 MD FR0,=D'1.E6' 'shift' 6 digits left
|
|
LA R1,OEF1306 pointer to edit pattern
|
|
LA R0,5 offset to one behind X'21' position
|
|
*
|
|
OFIX13XX LPDR FR2,FR0 get abbs() value
|
|
CD FR2,=D'2.E9' too large ?
|
|
BNL OFX13XXF if >= yes, do OSFILL
|
|
*
|
|
LDR FR4,FR2
|
|
AW FR4,ODNZERO FR4 := de-normalized FR2
|
|
SDR FR6,FR6 FR6 := 0.
|
|
ADR FR6,FR4 get integer part
|
|
SDR FR2,FR4 get fractional part
|
|
CD FR2,=D'0.5' check if >= 0.5
|
|
BL OFX13XXR if < no need to round up
|
|
AW FR4,ODNONE otherwise add LSB DENORM
|
|
OFX13XXR STD FR4,ODTEMP roll-out to memory
|
|
L R15,ODTEMP+4 get integer part
|
|
CVD R15,OCVD convert
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEF13XXL,R15),0(R1) setup pattern
|
|
LR R1,R15 setup R1 in case of miss
|
|
AR R1,R0 to one behind X'21' position
|
|
EDMK 0(OEF13XXL,R15),OCVD+2 and edit (and set R1)
|
|
LTDR FR0,FR0 negative number ?
|
|
BNM OFX13XXP if >= not
|
|
BCTR R1,0 decrement pointer
|
|
MVI 0(R1),C'-' write '-' sign
|
|
OFX13XXP LA R15,OEF13XXL(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OFX13XXF LA R1,OEF13XXL
|
|
B OSFILL
|
|
*
|
|
OEF1306 DC C' ',3X'20',X'21',X'20',C'.',6X'20' pat: bddd(d.dddddd
|
|
OEF1308 DC C' ',1X'20',X'21',X'20',C'.',8X'20' pat: bd(d.dddddddd
|
|
OEF13XXL EQU *-OEF1308
|
|
|
|
*
|
|
* OFIX1200 -------------------------------------------------
|
|
* print double, like PL/I F(12,0) or C %12.0f format
|
|
* input value in floating reg FR0
|
|
* only for non-negatve numbers
|
|
*
|
|
OFIX1200 LTDR FR0,FR0 check whether negative
|
|
BL OFX1200F if < yes, do OSFILL
|
|
CD FR0,=D'99999999999.' too large ?
|
|
BH OFX1200F if > yes, do OSFILL
|
|
AW FR0,ODNZERO de-normalize
|
|
STD FR0,ODTEMP roll-out to memory
|
|
L R1,ODTEMP+4
|
|
L R0,ODTEMP
|
|
N R0,=X'00FFFFFF'
|
|
D R0,=F'100000000' now R0 lower 9, R1 upper digits
|
|
CVD R0,OCVD BCD convert lower part
|
|
L R15,OLPTR R15 points to edit position
|
|
LA R15,2(R15) add two blanks
|
|
LTR R1,R1 upper != 0
|
|
BNZ OFX1200B if != yes, handle large number
|
|
*
|
|
MVC 0(OEI10L,R15),OEI10 setup pattern (from OINT10)
|
|
ED 0(OEI10L,R15),OCVD+3 and edit
|
|
LA R15,OEI10L(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OFX1200B EQU *
|
|
MVC 0(OEF10LL,R15),OEF10L setup pattern
|
|
ED 0(OEF10LL,R15),OCVD+3 and edit
|
|
CVD R1,OCVD BCD convert upper part
|
|
L R15,OLPTR R15 points to edit position
|
|
MVC 0(OEF10UL,R15),OEF10U setup pattern
|
|
ED 0(OEF10UL,R15),OCVD+6 and edit
|
|
LA R15,12(R15) push pointer
|
|
ST R15,OLPTR store pointer
|
|
BR R14
|
|
*
|
|
OFX1200F LA R1,12
|
|
B OSFILL
|
|
*
|
|
OEF10L DC C' ',X'21',8X'20' pat: b(dddddddd
|
|
OEF10LL EQU *-OEF10L
|
|
OEF10U DC C' ',X'20',X'21',X'20' pat: bd(d
|
|
OEF10UL EQU *-OEF10U
|
|
* include simple input system -----------------------------------------
|
|
*
|
|
* simple input system procedures --------------------------------------
|
|
* calling and register convention:
|
|
* R1 holds value (or descriptor pointer)
|
|
* R0,R1 may be modified
|
|
* R14,R15 may be modified
|
|
* R2-R11 are not changed
|
|
*
|
|
* in short
|
|
* R1 holds input or output value (or pointer)
|
|
* call with BAL R14,<routine>
|
|
*
|
|
* IGETLINE -------------------------------------------------
|
|
* read line from SYSIN
|
|
* EOF handling:
|
|
* - IEOFOK holds the 'EOF OK' flag
|
|
* - if EOF seen and IEOFOK = X'00', program ends with RC=8
|
|
* - if EOF seen and IEOFOK != X'00', program ends with RC=0
|
|
*
|
|
IGETLINE ST R14,IGETLNEL save R14
|
|
L R1,=A(SYSIN)
|
|
L R0,=A(ILBUF)
|
|
GET (1),(0) read line
|
|
L R0,=A(ILBUF)
|
|
ST R0,ILPTR set input ptr to begin of line
|
|
L R14,IGETLNEL restore R14 linkage
|
|
BR R14
|
|
*
|
|
IGETLNEL DS F save area for R14 (return linkage)
|
|
*
|
|
* IEOFHDL --------------------------------------------------
|
|
*
|
|
IEOFHDL BALR R12,R0 where are we ?
|
|
LA R15,*-MAIN offset from MAIN to here
|
|
SR R12,R15 base reg now points to MAIN
|
|
LA R14,EXIT
|
|
CLI IEOFOK,X'00' is EOF ok ?
|
|
BNER R14 if != yes, jump to EXIT
|
|
MVI RC+3,X'08' otherwise set RC=8
|
|
BR R14 and jump to EXIT
|
|
*
|
|
* Work area for simple output system ------------------------
|
|
*
|
|
ILPTR DC A(ILBUF) current input line position
|
|
IEOFOK DS X'00' EOF ok flag
|
|
ICVB DS D buffer for CVB (8 byte, DW aligned)
|
|
*
|
|
* DCB and OLBUF in separate CSECT
|
|
*
|
|
SIOSDATA CSECT
|
|
DS 0F
|
|
SYSIN DCB DSORG=PS,MACRF=GM,DDNAME=SYSIN,EODAD=IEOFHDL X
|
|
RECFM=FB,LRECL=80,BLKSIZE=0
|
|
ILBUF DC CL80' ' input line buffer
|
|
MAIN CSECT
|
|
*
|
|
* IINT10 ---------------------------------------------------
|
|
* read integer, like PL/I F(10) or C %10d format
|
|
*
|
|
IINT10 L R15,ILPTR get input pointer
|
|
PACK ICVB(8),0(10,R15) pack next 10 char
|
|
CVB R1,ICVB and convert
|
|
LA R15,10(R15) push pointer by 10 char
|
|
ST R15,ILPTR and update
|
|
BR R14
|
|
*
|
|
* Work area definitions -----------------------------------------------
|
|
*
|
|
SAVE DS 18F local save area
|
|
RC DC F'0' return code
|
|
IDBGRR DC X'00' trace RR enable
|
|
IDBGRN DC X'00' trace RN enable
|
|
IDBGMC DC X'00' trace MC enable
|
|
RANINI DC X'00' init RSHUF done flag
|
|
DS 0D
|
|
RFACTOR DC D'69069.'
|
|
RSEED DC D'12345.'
|
|
RLAST DC D'0.'
|
|
RR32 DC D'4294967296.' is 4*1024*1024*1024
|
|
RR32I DS D
|
|
RNEW DS D
|
|
RNEW1 DS D
|
|
RFAC DS D
|
|
RFAC1 DS D
|
|
*
|
|
PI DC D'3.141592653589793'
|
|
PIEST DS D
|
|
PIERR DS D
|
|
*
|
|
X DS D
|
|
Y DS D
|
|
R DS D
|
|
*
|
|
* message strings
|
|
*
|
|
MSGHD1 OTXTDSC C' ntry nhit pi-est'
|
|
MSGHD2 OTXTDSC C' pi-err seed'
|
|
MSGMC OTXTDSC C'MC: '
|
|
MSGPI OTXTDSC C'PI: '
|
|
MSGRR OTXTDSC C'RR: '
|
|
MSGRN OTXTDSC C'RN: '
|
|
MSGCSEP OTXTDSC C' : '
|
|
*
|
|
* spill literal pool
|
|
*
|
|
LTORG
|
|
*
|
|
* data section
|
|
*
|
|
DATA CSECT
|
|
RSHUF DS 128D
|
|
*
|
|
* other defs and end
|
|
*
|
|
YREGS ,
|
|
FR0 EQU 0
|
|
FR2 EQU 2
|
|
FR4 EQU 4
|
|
FR6 EQU 6
|
|
END MAIN define main entry point
|
|
/*
|
|
//GO.SYSUDUMP DD SYSOUT=*,OUTLIM=2000
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIGCCF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: mcpi_cc.c 978 2017-12-28 21:32:18Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-28 978 1.1 use inverse to avoid divide by constant */
|
|
/* 2017-08-12 938 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
double rseed = 12345.;
|
|
double rlast = 0.;
|
|
double rshuf[128];
|
|
double rr32 = 4294967296.; /* 4*1024*1024*1024 */
|
|
double rdiv = 33554432.; /* rr32 / 128 */
|
|
double rr32i; /* setup in main() */
|
|
double rdivi; /* setup in main() */
|
|
int ranini = 0;
|
|
int idbgrr = 0;
|
|
int idbgrn = 0;
|
|
int idbgmc = 0;
|
|
|
|
double ranraw()
|
|
{
|
|
double rnew,rnew1;
|
|
double rfac;
|
|
int ifac;
|
|
|
|
rnew1 = rseed * 69069.;
|
|
rfac = rnew1 * rr32i;
|
|
ifac = rfac;
|
|
rfac = ifac;
|
|
rnew = rnew1 - rfac * rr32;
|
|
if (idbgrr) printf("RR: %12.0f %12.0f : %16.0f %9d\n",
|
|
rseed,rnew, rnew1,ifac);
|
|
rseed = rnew;
|
|
return rnew;
|
|
}
|
|
|
|
double rannum()
|
|
{
|
|
int i;
|
|
double rnew;
|
|
|
|
if (ranini == 0) {
|
|
for (i=0; i<128; i++) rshuf[i] = ranraw();
|
|
ranini = 1;
|
|
}
|
|
|
|
i = rlast * rdivi;
|
|
rlast = rshuf[i];
|
|
rshuf[i] = ranraw();
|
|
rnew = rlast * rr32i;
|
|
if (idbgrn) printf("RN: %12d %12.0f %12.8f\n", i,rlast,rnew);
|
|
return rnew;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int i;
|
|
int ntry = 0;
|
|
int nhit = 0;
|
|
int ngo;
|
|
double pi = 3.141592653589793;
|
|
double piest;
|
|
double pierr;
|
|
|
|
/* setup global constants */
|
|
rr32i = 1./rr32;
|
|
rdivi = 1./rdiv;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d %d", &idbgrr, &idbgrn, &idbgmc) != 3) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
if (idbgrr == 0 && idbgrn == 0 && idbgmc == 0)
|
|
printf(" ntry nhit pi-est"
|
|
" pi-err seed\n");
|
|
|
|
while (scanf(" %d", &ngo) == 1 && ngo > 0) {
|
|
for (i=0; i<ngo; i++) {
|
|
double x,y,r;
|
|
x = 2.*rannum() - 1.;
|
|
y = 2.*rannum() - 1.;
|
|
r = x*x + y*y;
|
|
ntry += 1;
|
|
if (r <= 1.) nhit += 1;
|
|
if (idbgmc) printf("MC: %12.8f %12.8f %12.8f %12d\n", x,y,r,nhit);
|
|
}
|
|
|
|
piest = 4. * ((double)nhit / (double)ntry);
|
|
pierr = piest - pi;
|
|
if (pierr < 0.) pierr = -pierr;
|
|
printf("PI: %12d %12d %12.8f %12.8f %12.0f\n",
|
|
ntry, nhit, piest, pierr, rlast);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIGCCT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#GCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC GCCCLG,COPTS='-O3',
|
|
// PARM.LKED='MAP,LIST'
|
|
//COMP.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: mcpi_cc.c 978 2017-12-28 21:32:18Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-28 978 1.1 use inverse to avoid divide by constant */
|
|
/* 2017-08-12 938 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
double rseed = 12345.;
|
|
double rlast = 0.;
|
|
double rshuf[128];
|
|
double rr32 = 4294967296.; /* 4*1024*1024*1024 */
|
|
double rdiv = 33554432.; /* rr32 / 128 */
|
|
double rr32i; /* setup in main() */
|
|
double rdivi; /* setup in main() */
|
|
int ranini = 0;
|
|
int idbgrr = 0;
|
|
int idbgrn = 0;
|
|
int idbgmc = 0;
|
|
|
|
double ranraw()
|
|
{
|
|
double rnew,rnew1;
|
|
double rfac;
|
|
int ifac;
|
|
|
|
rnew1 = rseed * 69069.;
|
|
rfac = rnew1 * rr32i;
|
|
ifac = rfac;
|
|
rfac = ifac;
|
|
rnew = rnew1 - rfac * rr32;
|
|
if (idbgrr) printf("RR: %12.0f %12.0f : %16.0f %9d\n",
|
|
rseed,rnew, rnew1,ifac);
|
|
rseed = rnew;
|
|
return rnew;
|
|
}
|
|
|
|
double rannum()
|
|
{
|
|
int i;
|
|
double rnew;
|
|
|
|
if (ranini == 0) {
|
|
for (i=0; i<128; i++) rshuf[i] = ranraw();
|
|
ranini = 1;
|
|
}
|
|
|
|
i = rlast * rdivi;
|
|
rlast = rshuf[i];
|
|
rshuf[i] = ranraw();
|
|
rnew = rlast * rr32i;
|
|
if (idbgrn) printf("RN: %12d %12.0f %12.8f\n", i,rlast,rnew);
|
|
return rnew;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int i;
|
|
int ntry = 0;
|
|
int nhit = 0;
|
|
int ngo;
|
|
double pi = 3.141592653589793;
|
|
double piest;
|
|
double pierr;
|
|
|
|
/* setup global constants */
|
|
rr32i = 1./rr32;
|
|
rdivi = 1./rdiv;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d %d", &idbgrr, &idbgrn, &idbgmc) != 3) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
if (idbgrr == 0 && idbgrn == 0 && idbgmc == 0)
|
|
printf(" ntry nhit pi-est"
|
|
" pi-err seed\n");
|
|
|
|
while (scanf(" %d", &ngo) == 1 && ngo > 0) {
|
|
for (i=0; i<ngo; i++) {
|
|
double x,y,r;
|
|
x = 2.*rannum() - 1.;
|
|
y = 2.*rannum() - 1.;
|
|
r = x*x + y*y;
|
|
ntry += 1;
|
|
if (r <= 1.) nhit += 1;
|
|
if (idbgmc) printf("MC: %12.8f %12.8f %12.8f %12d\n", x,y,r,nhit);
|
|
}
|
|
|
|
piest = 4. * ((double)nhit / (double)ntry);
|
|
pierr = piest - pi;
|
|
if (pierr < 0.) pierr = -pierr;
|
|
printf("PI: %12d %12d %12.8f %12.8f %12.0f\n",
|
|
ntry, nhit, piest, pierr, rlast);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.SYSPRINT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIJCCF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: mcpi_cc.c 978 2017-12-28 21:32:18Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-28 978 1.1 use inverse to avoid divide by constant */
|
|
/* 2017-08-12 938 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
double rseed = 12345.;
|
|
double rlast = 0.;
|
|
double rshuf[128];
|
|
double rr32 = 4294967296.; /* 4*1024*1024*1024 */
|
|
double rdiv = 33554432.; /* rr32 / 128 */
|
|
double rr32i; /* setup in main() */
|
|
double rdivi; /* setup in main() */
|
|
int ranini = 0;
|
|
int idbgrr = 0;
|
|
int idbgrn = 0;
|
|
int idbgmc = 0;
|
|
|
|
double ranraw()
|
|
{
|
|
double rnew,rnew1;
|
|
double rfac;
|
|
int ifac;
|
|
|
|
rnew1 = rseed * 69069.;
|
|
rfac = rnew1 * rr32i;
|
|
ifac = rfac;
|
|
rfac = ifac;
|
|
rnew = rnew1 - rfac * rr32;
|
|
if (idbgrr) printf("RR: %12.0f %12.0f : %16.0f %9d\n",
|
|
rseed,rnew, rnew1,ifac);
|
|
rseed = rnew;
|
|
return rnew;
|
|
}
|
|
|
|
double rannum()
|
|
{
|
|
int i;
|
|
double rnew;
|
|
|
|
if (ranini == 0) {
|
|
for (i=0; i<128; i++) rshuf[i] = ranraw();
|
|
ranini = 1;
|
|
}
|
|
|
|
i = rlast * rdivi;
|
|
rlast = rshuf[i];
|
|
rshuf[i] = ranraw();
|
|
rnew = rlast * rr32i;
|
|
if (idbgrn) printf("RN: %12d %12.0f %12.8f\n", i,rlast,rnew);
|
|
return rnew;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int i;
|
|
int ntry = 0;
|
|
int nhit = 0;
|
|
int ngo;
|
|
double pi = 3.141592653589793;
|
|
double piest;
|
|
double pierr;
|
|
|
|
/* setup global constants */
|
|
rr32i = 1./rr32;
|
|
rdivi = 1./rdiv;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d %d", &idbgrr, &idbgrn, &idbgmc) != 3) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
if (idbgrr == 0 && idbgrn == 0 && idbgmc == 0)
|
|
printf(" ntry nhit pi-est"
|
|
" pi-err seed\n");
|
|
|
|
while (scanf(" %d", &ngo) == 1 && ngo > 0) {
|
|
for (i=0; i<ngo; i++) {
|
|
double x,y,r;
|
|
x = 2.*rannum() - 1.;
|
|
y = 2.*rannum() - 1.;
|
|
r = x*x + y*y;
|
|
ntry += 1;
|
|
if (r <= 1.) nhit += 1;
|
|
if (idbgmc) printf("MC: %12.8f %12.8f %12.8f %12d\n", x,y,r,nhit);
|
|
}
|
|
|
|
piest = 4. * ((double)nhit / (double)ntry);
|
|
pierr = piest - pi;
|
|
if (pierr < 0.) pierr = -pierr;
|
|
printf("PI: %12d %12d %12.8f %12.8f %12.0f\n",
|
|
ntry, nhit, piest, pierr, rlast);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIJCCT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#JCC JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=8192K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC JCCCLG,
|
|
// JOPTS='-o',
|
|
// PARM.LKED='NCAL,MAP,LIST,NORENT'
|
|
//COMPILE.SYSIN DD DATA,DLM='/@'
|
|
/* $Id: mcpi_cc.c 978 2017-12-28 21:32:18Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-28 978 1.1 use inverse to avoid divide by constant */
|
|
/* 2017-08-12 938 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
double rseed = 12345.;
|
|
double rlast = 0.;
|
|
double rshuf[128];
|
|
double rr32 = 4294967296.; /* 4*1024*1024*1024 */
|
|
double rdiv = 33554432.; /* rr32 / 128 */
|
|
double rr32i; /* setup in main() */
|
|
double rdivi; /* setup in main() */
|
|
int ranini = 0;
|
|
int idbgrr = 0;
|
|
int idbgrn = 0;
|
|
int idbgmc = 0;
|
|
|
|
double ranraw()
|
|
{
|
|
double rnew,rnew1;
|
|
double rfac;
|
|
int ifac;
|
|
|
|
rnew1 = rseed * 69069.;
|
|
rfac = rnew1 * rr32i;
|
|
ifac = rfac;
|
|
rfac = ifac;
|
|
rnew = rnew1 - rfac * rr32;
|
|
if (idbgrr) printf("RR: %12.0f %12.0f : %16.0f %9d\n",
|
|
rseed,rnew, rnew1,ifac);
|
|
rseed = rnew;
|
|
return rnew;
|
|
}
|
|
|
|
double rannum()
|
|
{
|
|
int i;
|
|
double rnew;
|
|
|
|
if (ranini == 0) {
|
|
for (i=0; i<128; i++) rshuf[i] = ranraw();
|
|
ranini = 1;
|
|
}
|
|
|
|
i = rlast * rdivi;
|
|
rlast = rshuf[i];
|
|
rshuf[i] = ranraw();
|
|
rnew = rlast * rr32i;
|
|
if (idbgrn) printf("RN: %12d %12.0f %12.8f\n", i,rlast,rnew);
|
|
return rnew;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int i;
|
|
int ntry = 0;
|
|
int nhit = 0;
|
|
int ngo;
|
|
double pi = 3.141592653589793;
|
|
double piest;
|
|
double pierr;
|
|
|
|
/* setup global constants */
|
|
rr32i = 1./rr32;
|
|
rdivi = 1./rdiv;
|
|
|
|
/* JCC on MVS doesn't skip initial white space, add leading ' ' to force */
|
|
if (scanf(" %d %d %d", &idbgrr, &idbgrn, &idbgmc) != 3) {
|
|
printf("conversion error, abort\n");
|
|
return 1;
|
|
}
|
|
|
|
if (idbgrr == 0 && idbgrn == 0 && idbgmc == 0)
|
|
printf(" ntry nhit pi-est"
|
|
" pi-err seed\n");
|
|
|
|
while (scanf(" %d", &ngo) == 1 && ngo > 0) {
|
|
for (i=0; i<ngo; i++) {
|
|
double x,y,r;
|
|
x = 2.*rannum() - 1.;
|
|
y = 2.*rannum() - 1.;
|
|
r = x*x + y*y;
|
|
ntry += 1;
|
|
if (r <= 1.) nhit += 1;
|
|
if (idbgmc) printf("MC: %12.8f %12.8f %12.8f %12d\n", x,y,r,nhit);
|
|
}
|
|
|
|
piest = 4. * ((double)nhit / (double)ntry);
|
|
pierr = piest - pi;
|
|
if (pierr < 0.) pierr = -pierr;
|
|
printf("PI: %12d %12d %12.8f %12.8f %12.0f\n",
|
|
ntry, nhit, piest, pierr, rlast);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
/@
|
|
//GO.STDOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.STDERR DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIFOGF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: mcpi_for.f 978 2017-12-28 21:32:18Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
C 2017-08-12 938 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- function ranraw ------------------------------------------------
|
|
C
|
|
C Fortran IV(1966): function syntax is: 'type FUNCTION name*precision (args)
|
|
C however gfortran -std=legacy wants: 'type*precision FUNCTION name (args)
|
|
REAL FUNCTION RANRAW*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RFAC,RNEW
|
|
INTEGER IFAC
|
|
C
|
|
RNEW = RSEED * 69069.D0
|
|
RFAC = RNEW * RR32I
|
|
IFAC = RFAC
|
|
RFAC = IFAC
|
|
RNEW = RNEW - RFAC * RR32
|
|
IF (IDBGRR .NE. 0) WRITE(6,9000) RSEED,RNEW
|
|
RSEED = RNEW
|
|
RANRAW = RNEW
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RR: ',F12.0,1X,F12.0)
|
|
END
|
|
C
|
|
C --- function rannum ------------------------------------------------
|
|
C
|
|
REAL FUNCTION RANNUM*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RANRAW
|
|
INTEGER I
|
|
C
|
|
IF (RANINI) GOTO 1000
|
|
DO 100 I=1,128
|
|
RSHUF(I) = RANRAW(DUMMY)
|
|
100 CONTINUE
|
|
RANINI = .TRUE.
|
|
1000 CONTINUE
|
|
C
|
|
I = RLAST * RDIVI
|
|
RLAST = RSHUF(I+1)
|
|
RSHUF(I+1) = RANRAW(DUMMY)
|
|
RANNUM = RLAST * RR32I
|
|
IF (IDBGRN .NE. 0) WRITE(6,9000) I,RLAST,RANNUM
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RN: ',I12,1X,F12.0,1X,F12.8)
|
|
END
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM MCPI
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
INTEGER I
|
|
INTEGER NTRY,NHIT,NGO
|
|
REAL*8 PI,PIEST,PIERR
|
|
REAL*8 X,Y,R
|
|
REAL*8 DUMMY
|
|
REAL*8 RANNUM
|
|
REAL*8 RTRY,RHIT
|
|
DATA PI /3.141592653589793D0/
|
|
DATA NTRY /0/
|
|
DATA NHIT /0/
|
|
C
|
|
RR32 = 4294967296.D0
|
|
RR32I = 1./RR32
|
|
RDIV = 33554432.D0
|
|
RDIVI = 1./RDIV
|
|
C
|
|
RSEED = 12345.D0
|
|
RLAST = 0.D0
|
|
RANINI = .FALSE.
|
|
C
|
|
READ(5,9000,ERR=910,END=900) IDBGRR,IDBGRN,IDBGMC
|
|
C
|
|
IF (IDBGRR.EQ.0 .AND. IDBGRN.EQ.0 .AND. IDBGMC.EQ.0)
|
|
X WRITE(6,9005)
|
|
C
|
|
100 READ(5,9010,ERR=910,END=900) NGO
|
|
IF (NGO .LE. 0) GOTO 900
|
|
C
|
|
DO 200 I=1,NGO
|
|
X = 2.*RANNUM(DUMMY) - 1.
|
|
Y = 2.*RANNUM(DUMMY) - 1.
|
|
R = X*X + Y*Y
|
|
NTRY = NTRY + 1
|
|
IF (R .LE. 1.) NHIT = NHIT + 1
|
|
IF (IDBGMC .NE. 0) WRITE(6,9030) X,Y,R,NHIT
|
|
200 CONTINUE
|
|
C
|
|
RTRY = NTRY
|
|
RHIT = NHIT
|
|
PIEST = 4.* RHIT / RTRY
|
|
PIERR = PIEST - PI
|
|
IF (PIERR .LT. 0.) PIERR = -PIERR
|
|
WRITE(6,9020) NTRY, NHIT,PIEST,PIERR,RLAST
|
|
GOTO 100
|
|
C
|
|
900 CONTINUE
|
|
C
|
|
STOP
|
|
C
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
C
|
|
9000 FORMAT(3I10)
|
|
9005 FORMAT(1X,' ntry nhit pi-est',
|
|
X ' pi-err seed')
|
|
9010 FORMAT(I10)
|
|
9020 FORMAT(1X,'PI: ',I12,1X,I12,1X,F12.8,1X,F12.8,1X,F12.0)
|
|
9030 FORMAT(1X,'MC: ',F12.8,1X,F12.8,1X,F12.8,1X,I12)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIFOGT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#FOG JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTGCLG,
|
|
// PARM.FORT='',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: mcpi_for.f 978 2017-12-28 21:32:18Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
C 2017-08-12 938 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- function ranraw ------------------------------------------------
|
|
C
|
|
C Fortran IV(1966): function syntax is: 'type FUNCTION name*precision (args)
|
|
C however gfortran -std=legacy wants: 'type*precision FUNCTION name (args)
|
|
REAL FUNCTION RANRAW*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RFAC,RNEW
|
|
INTEGER IFAC
|
|
C
|
|
RNEW = RSEED * 69069.D0
|
|
RFAC = RNEW * RR32I
|
|
IFAC = RFAC
|
|
RFAC = IFAC
|
|
RNEW = RNEW - RFAC * RR32
|
|
IF (IDBGRR .NE. 0) WRITE(6,9000) RSEED,RNEW
|
|
RSEED = RNEW
|
|
RANRAW = RNEW
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RR: ',F12.0,1X,F12.0)
|
|
END
|
|
C
|
|
C --- function rannum ------------------------------------------------
|
|
C
|
|
REAL FUNCTION RANNUM*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RANRAW
|
|
INTEGER I
|
|
C
|
|
IF (RANINI) GOTO 1000
|
|
DO 100 I=1,128
|
|
RSHUF(I) = RANRAW(DUMMY)
|
|
100 CONTINUE
|
|
RANINI = .TRUE.
|
|
1000 CONTINUE
|
|
C
|
|
I = RLAST * RDIVI
|
|
RLAST = RSHUF(I+1)
|
|
RSHUF(I+1) = RANRAW(DUMMY)
|
|
RANNUM = RLAST * RR32I
|
|
IF (IDBGRN .NE. 0) WRITE(6,9000) I,RLAST,RANNUM
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RN: ',I12,1X,F12.0,1X,F12.8)
|
|
END
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM MCPI
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
INTEGER I
|
|
INTEGER NTRY,NHIT,NGO
|
|
REAL*8 PI,PIEST,PIERR
|
|
REAL*8 X,Y,R
|
|
REAL*8 DUMMY
|
|
REAL*8 RANNUM
|
|
REAL*8 RTRY,RHIT
|
|
DATA PI /3.141592653589793D0/
|
|
DATA NTRY /0/
|
|
DATA NHIT /0/
|
|
C
|
|
RR32 = 4294967296.D0
|
|
RR32I = 1./RR32
|
|
RDIV = 33554432.D0
|
|
RDIVI = 1./RDIV
|
|
C
|
|
RSEED = 12345.D0
|
|
RLAST = 0.D0
|
|
RANINI = .FALSE.
|
|
C
|
|
READ(5,9000,ERR=910,END=900) IDBGRR,IDBGRN,IDBGMC
|
|
C
|
|
IF (IDBGRR.EQ.0 .AND. IDBGRN.EQ.0 .AND. IDBGMC.EQ.0)
|
|
X WRITE(6,9005)
|
|
C
|
|
100 READ(5,9010,ERR=910,END=900) NGO
|
|
IF (NGO .LE. 0) GOTO 900
|
|
C
|
|
DO 200 I=1,NGO
|
|
X = 2.*RANNUM(DUMMY) - 1.
|
|
Y = 2.*RANNUM(DUMMY) - 1.
|
|
R = X*X + Y*Y
|
|
NTRY = NTRY + 1
|
|
IF (R .LE. 1.) NHIT = NHIT + 1
|
|
IF (IDBGMC .NE. 0) WRITE(6,9030) X,Y,R,NHIT
|
|
200 CONTINUE
|
|
C
|
|
RTRY = NTRY
|
|
RHIT = NHIT
|
|
PIEST = 4.* RHIT / RTRY
|
|
PIERR = PIEST - PI
|
|
IF (PIERR .LT. 0.) PIERR = -PIERR
|
|
WRITE(6,9020) NTRY, NHIT,PIEST,PIERR,RLAST
|
|
GOTO 100
|
|
C
|
|
900 CONTINUE
|
|
C
|
|
STOP
|
|
C
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
C
|
|
9000 FORMAT(3I10)
|
|
9005 FORMAT(1X,' ntry nhit pi-est',
|
|
X ' pi-err seed')
|
|
9010 FORMAT(I10)
|
|
9020 FORMAT(1X,'PI: ',I12,1X,I12,1X,F12.8,1X,F12.8,1X,F12.0)
|
|
9030 FORMAT(1X,'MC: ',F12.8,1X,F12.8,1X,F12.8,1X,I12)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIFOHF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1440),PRTY=2
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: mcpi_for.f 978 2017-12-28 21:32:18Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
C 2017-08-12 938 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- function ranraw ------------------------------------------------
|
|
C
|
|
C Fortran IV(1966): function syntax is: 'type FUNCTION name*precision (args)
|
|
C however gfortran -std=legacy wants: 'type*precision FUNCTION name (args)
|
|
REAL FUNCTION RANRAW*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RFAC,RNEW
|
|
INTEGER IFAC
|
|
C
|
|
RNEW = RSEED * 69069.D0
|
|
RFAC = RNEW * RR32I
|
|
IFAC = RFAC
|
|
RFAC = IFAC
|
|
RNEW = RNEW - RFAC * RR32
|
|
IF (IDBGRR .NE. 0) WRITE(6,9000) RSEED,RNEW
|
|
RSEED = RNEW
|
|
RANRAW = RNEW
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RR: ',F12.0,1X,F12.0)
|
|
END
|
|
C
|
|
C --- function rannum ------------------------------------------------
|
|
C
|
|
REAL FUNCTION RANNUM*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RANRAW
|
|
INTEGER I
|
|
C
|
|
IF (RANINI) GOTO 1000
|
|
DO 100 I=1,128
|
|
RSHUF(I) = RANRAW(DUMMY)
|
|
100 CONTINUE
|
|
RANINI = .TRUE.
|
|
1000 CONTINUE
|
|
C
|
|
I = RLAST * RDIVI
|
|
RLAST = RSHUF(I+1)
|
|
RSHUF(I+1) = RANRAW(DUMMY)
|
|
RANNUM = RLAST * RR32I
|
|
IF (IDBGRN .NE. 0) WRITE(6,9000) I,RLAST,RANNUM
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RN: ',I12,1X,F12.0,1X,F12.8)
|
|
END
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM MCPI
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
INTEGER I
|
|
INTEGER NTRY,NHIT,NGO
|
|
REAL*8 PI,PIEST,PIERR
|
|
REAL*8 X,Y,R
|
|
REAL*8 DUMMY
|
|
REAL*8 RANNUM
|
|
REAL*8 RTRY,RHIT
|
|
DATA PI /3.141592653589793D0/
|
|
DATA NTRY /0/
|
|
DATA NHIT /0/
|
|
C
|
|
RR32 = 4294967296.D0
|
|
RR32I = 1./RR32
|
|
RDIV = 33554432.D0
|
|
RDIVI = 1./RDIV
|
|
C
|
|
RSEED = 12345.D0
|
|
RLAST = 0.D0
|
|
RANINI = .FALSE.
|
|
C
|
|
READ(5,9000,ERR=910,END=900) IDBGRR,IDBGRN,IDBGMC
|
|
C
|
|
IF (IDBGRR.EQ.0 .AND. IDBGRN.EQ.0 .AND. IDBGMC.EQ.0)
|
|
X WRITE(6,9005)
|
|
C
|
|
100 READ(5,9010,ERR=910,END=900) NGO
|
|
IF (NGO .LE. 0) GOTO 900
|
|
C
|
|
DO 200 I=1,NGO
|
|
X = 2.*RANNUM(DUMMY) - 1.
|
|
Y = 2.*RANNUM(DUMMY) - 1.
|
|
R = X*X + Y*Y
|
|
NTRY = NTRY + 1
|
|
IF (R .LE. 1.) NHIT = NHIT + 1
|
|
IF (IDBGMC .NE. 0) WRITE(6,9030) X,Y,R,NHIT
|
|
200 CONTINUE
|
|
C
|
|
RTRY = NTRY
|
|
RHIT = NHIT
|
|
PIEST = 4.* RHIT / RTRY
|
|
PIERR = PIEST - PI
|
|
IF (PIERR .LT. 0.) PIERR = -PIERR
|
|
WRITE(6,9020) NTRY, NHIT,PIEST,PIERR,RLAST
|
|
GOTO 100
|
|
C
|
|
900 CONTINUE
|
|
C
|
|
STOP
|
|
C
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
C
|
|
9000 FORMAT(3I10)
|
|
9005 FORMAT(1X,' ntry nhit pi-est',
|
|
X ' pi-err seed')
|
|
9010 FORMAT(I10)
|
|
9020 FORMAT(1X,'PI: ',I12,1X,I12,1X,F12.8,1X,F12.8,1X,F12.0)
|
|
9030 FORMAT(1X,'MC: ',F12.8,1X,F12.8,1X,F12.8,1X,I12)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIFOHT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#FOH JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC FORTHCLG,
|
|
// PARM.FORT='OPT=2',
|
|
// PARM.LKED='MAP,LIST,LET'
|
|
//FORT.SYSIN DD *
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: mcpi_for.f 978 2017-12-28 21:32:18Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
C 2017-08-12 938 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- function ranraw ------------------------------------------------
|
|
C
|
|
C Fortran IV(1966): function syntax is: 'type FUNCTION name*precision (args)
|
|
C however gfortran -std=legacy wants: 'type*precision FUNCTION name (args)
|
|
REAL FUNCTION RANRAW*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RFAC,RNEW
|
|
INTEGER IFAC
|
|
C
|
|
RNEW = RSEED * 69069.D0
|
|
RFAC = RNEW * RR32I
|
|
IFAC = RFAC
|
|
RFAC = IFAC
|
|
RNEW = RNEW - RFAC * RR32
|
|
IF (IDBGRR .NE. 0) WRITE(6,9000) RSEED,RNEW
|
|
RSEED = RNEW
|
|
RANRAW = RNEW
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RR: ',F12.0,1X,F12.0)
|
|
END
|
|
C
|
|
C --- function rannum ------------------------------------------------
|
|
C
|
|
REAL FUNCTION RANNUM*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RANRAW
|
|
INTEGER I
|
|
C
|
|
IF (RANINI) GOTO 1000
|
|
DO 100 I=1,128
|
|
RSHUF(I) = RANRAW(DUMMY)
|
|
100 CONTINUE
|
|
RANINI = .TRUE.
|
|
1000 CONTINUE
|
|
C
|
|
I = RLAST * RDIVI
|
|
RLAST = RSHUF(I+1)
|
|
RSHUF(I+1) = RANRAW(DUMMY)
|
|
RANNUM = RLAST * RR32I
|
|
IF (IDBGRN .NE. 0) WRITE(6,9000) I,RLAST,RANNUM
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RN: ',I12,1X,F12.0,1X,F12.8)
|
|
END
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM MCPI
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
INTEGER I
|
|
INTEGER NTRY,NHIT,NGO
|
|
REAL*8 PI,PIEST,PIERR
|
|
REAL*8 X,Y,R
|
|
REAL*8 DUMMY
|
|
REAL*8 RANNUM
|
|
REAL*8 RTRY,RHIT
|
|
DATA PI /3.141592653589793D0/
|
|
DATA NTRY /0/
|
|
DATA NHIT /0/
|
|
C
|
|
RR32 = 4294967296.D0
|
|
RR32I = 1./RR32
|
|
RDIV = 33554432.D0
|
|
RDIVI = 1./RDIV
|
|
C
|
|
RSEED = 12345.D0
|
|
RLAST = 0.D0
|
|
RANINI = .FALSE.
|
|
C
|
|
READ(5,9000,ERR=910,END=900) IDBGRR,IDBGRN,IDBGMC
|
|
C
|
|
IF (IDBGRR.EQ.0 .AND. IDBGRN.EQ.0 .AND. IDBGMC.EQ.0)
|
|
X WRITE(6,9005)
|
|
C
|
|
100 READ(5,9010,ERR=910,END=900) NGO
|
|
IF (NGO .LE. 0) GOTO 900
|
|
C
|
|
DO 200 I=1,NGO
|
|
X = 2.*RANNUM(DUMMY) - 1.
|
|
Y = 2.*RANNUM(DUMMY) - 1.
|
|
R = X*X + Y*Y
|
|
NTRY = NTRY + 1
|
|
IF (R .LE. 1.) NHIT = NHIT + 1
|
|
IF (IDBGMC .NE. 0) WRITE(6,9030) X,Y,R,NHIT
|
|
200 CONTINUE
|
|
C
|
|
RTRY = NTRY
|
|
RHIT = NHIT
|
|
PIEST = 4.* RHIT / RTRY
|
|
PIERR = PIEST - PI
|
|
IF (PIERR .LT. 0.) PIERR = -PIERR
|
|
WRITE(6,9020) NTRY, NHIT,PIEST,PIERR,RLAST
|
|
GOTO 100
|
|
C
|
|
900 CONTINUE
|
|
C
|
|
STOP
|
|
C
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
C
|
|
9000 FORMAT(3I10)
|
|
9005 FORMAT(1X,' ntry nhit pi-est',
|
|
X ' pi-err seed')
|
|
9010 FORMAT(I10)
|
|
9020 FORMAT(1X,'PI: ',I12,1X,I12,1X,F12.8,1X,F12.8,1X,F12.0)
|
|
9030 FORMAT(1X,'MC: ',F12.8,1X,F12.8,1X,F12.8,1X,I12)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
C
|
|
END
|
|
/*
|
|
//GO.FT06F001 DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIFOWF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(20,0),PRTY=2
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB MCPI#FOW,T=(20,0),P=100,NOCHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: mcpi_for.f 978 2017-12-28 21:32:18Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
C 2017-08-12 938 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- function ranraw ------------------------------------------------
|
|
C
|
|
C Fortran IV(1966): function syntax is: 'type FUNCTION name*precision (args)
|
|
C however gfortran -std=legacy wants: 'type*precision FUNCTION name (args)
|
|
REAL FUNCTION RANRAW*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RFAC,RNEW
|
|
INTEGER IFAC
|
|
C
|
|
RNEW = RSEED * 69069.D0
|
|
RFAC = RNEW * RR32I
|
|
IFAC = RFAC
|
|
RFAC = IFAC
|
|
RNEW = RNEW - RFAC * RR32
|
|
IF (IDBGRR .NE. 0) WRITE(6,9000) RSEED,RNEW
|
|
RSEED = RNEW
|
|
RANRAW = RNEW
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RR: ',F12.0,1X,F12.0)
|
|
END
|
|
C
|
|
C --- function rannum ------------------------------------------------
|
|
C
|
|
REAL FUNCTION RANNUM*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RANRAW
|
|
INTEGER I
|
|
C
|
|
IF (RANINI) GOTO 1000
|
|
DO 100 I=1,128
|
|
RSHUF(I) = RANRAW(DUMMY)
|
|
100 CONTINUE
|
|
RANINI = .TRUE.
|
|
1000 CONTINUE
|
|
C
|
|
I = RLAST * RDIVI
|
|
RLAST = RSHUF(I+1)
|
|
RSHUF(I+1) = RANRAW(DUMMY)
|
|
RANNUM = RLAST * RR32I
|
|
IF (IDBGRN .NE. 0) WRITE(6,9000) I,RLAST,RANNUM
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RN: ',I12,1X,F12.0,1X,F12.8)
|
|
END
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM MCPI
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
INTEGER I
|
|
INTEGER NTRY,NHIT,NGO
|
|
REAL*8 PI,PIEST,PIERR
|
|
REAL*8 X,Y,R
|
|
REAL*8 DUMMY
|
|
REAL*8 RANNUM
|
|
REAL*8 RTRY,RHIT
|
|
DATA PI /3.141592653589793D0/
|
|
DATA NTRY /0/
|
|
DATA NHIT /0/
|
|
C
|
|
RR32 = 4294967296.D0
|
|
RR32I = 1./RR32
|
|
RDIV = 33554432.D0
|
|
RDIVI = 1./RDIV
|
|
C
|
|
RSEED = 12345.D0
|
|
RLAST = 0.D0
|
|
RANINI = .FALSE.
|
|
C
|
|
READ(5,9000,ERR=910,END=900) IDBGRR,IDBGRN,IDBGMC
|
|
C
|
|
IF (IDBGRR.EQ.0 .AND. IDBGRN.EQ.0 .AND. IDBGMC.EQ.0)
|
|
X WRITE(6,9005)
|
|
C
|
|
100 READ(5,9010,ERR=910,END=900) NGO
|
|
IF (NGO .LE. 0) GOTO 900
|
|
C
|
|
DO 200 I=1,NGO
|
|
X = 2.*RANNUM(DUMMY) - 1.
|
|
Y = 2.*RANNUM(DUMMY) - 1.
|
|
R = X*X + Y*Y
|
|
NTRY = NTRY + 1
|
|
IF (R .LE. 1.) NHIT = NHIT + 1
|
|
IF (IDBGMC .NE. 0) WRITE(6,9030) X,Y,R,NHIT
|
|
200 CONTINUE
|
|
C
|
|
RTRY = NTRY
|
|
RHIT = NHIT
|
|
PIEST = 4.* RHIT / RTRY
|
|
PIERR = PIEST - PI
|
|
IF (PIERR .LT. 0.) PIERR = -PIERR
|
|
WRITE(6,9020) NTRY, NHIT,PIEST,PIERR,RLAST
|
|
GOTO 100
|
|
C
|
|
900 CONTINUE
|
|
C
|
|
STOP
|
|
C
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
C
|
|
9000 FORMAT(3I10)
|
|
9005 FORMAT(1X,' ntry nhit pi-est',
|
|
X ' pi-err seed')
|
|
9010 FORMAT(I10)
|
|
9020 FORMAT(1X,'PI: ',I12,1X,I12,1X,F12.8,1X,F12.8,1X,F12.0)
|
|
9030 FORMAT(1X,'MC: ',F12.8,1X,F12.8,1X,F12.8,1X,I12)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
C
|
|
END
|
|
$ENTRY
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIFOWT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#FOW JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC WATFIV
|
|
//SYSIN DD *
|
|
$JOB MCPI#FOW,T=(1,0),P=100,CHECK
|
|
C 1 2 3 4 5 6 712--------
|
|
C2345*78901234567890123456789012345678901234567890123456789012345678901234567890
|
|
C $Id: mcpi_for.f 978 2017-12-28 21:32:18Z mueller $
|
|
C
|
|
C Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
C
|
|
C This program is free software; you may redistribute and/or modify
|
|
C it under the terms of the GNU General Public License version 3.
|
|
C See Licence.txt in distribition directory for further details.
|
|
C
|
|
C Revision History:
|
|
C Date Rev Version Comment
|
|
C 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
C 2017-08-12 938 1.0 Initial version
|
|
C 2017-07-30 931 0.1 First draft
|
|
C
|
|
C --- function ranraw ------------------------------------------------
|
|
C
|
|
C Fortran IV(1966): function syntax is: 'type FUNCTION name*precision (args)
|
|
C however gfortran -std=legacy wants: 'type*precision FUNCTION name (args)
|
|
REAL FUNCTION RANRAW*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RFAC,RNEW
|
|
INTEGER IFAC
|
|
C
|
|
RNEW = RSEED * 69069.D0
|
|
RFAC = RNEW * RR32I
|
|
IFAC = RFAC
|
|
RFAC = IFAC
|
|
RNEW = RNEW - RFAC * RR32
|
|
IF (IDBGRR .NE. 0) WRITE(6,9000) RSEED,RNEW
|
|
RSEED = RNEW
|
|
RANRAW = RNEW
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RR: ',F12.0,1X,F12.0)
|
|
END
|
|
C
|
|
C --- function rannum ------------------------------------------------
|
|
C
|
|
REAL FUNCTION RANNUM*8 (DUMMY)
|
|
C
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
REAL*8 DUMMY
|
|
REAL*8 RANRAW
|
|
INTEGER I
|
|
C
|
|
IF (RANINI) GOTO 1000
|
|
DO 100 I=1,128
|
|
RSHUF(I) = RANRAW(DUMMY)
|
|
100 CONTINUE
|
|
RANINI = .TRUE.
|
|
1000 CONTINUE
|
|
C
|
|
I = RLAST * RDIVI
|
|
RLAST = RSHUF(I+1)
|
|
RSHUF(I+1) = RANRAW(DUMMY)
|
|
RANNUM = RLAST * RR32I
|
|
IF (IDBGRN .NE. 0) WRITE(6,9000) I,RLAST,RANNUM
|
|
RETURN
|
|
C
|
|
9000 FORMAT(1X,'RN: ',I12,1X,F12.0,1X,F12.8)
|
|
END
|
|
C
|
|
C --- main program ---------------------------------------------------
|
|
C PROGRAM MCPI
|
|
COMMON /DBG/IDBGRR,IDBGRN,IDBGMC
|
|
COMMON /RANFAC/RR32,RR32I,RDIV,RDIVI
|
|
COMMON /RAN/RLAST,RSEED,RSHUF(128),RANINI
|
|
REAL*8 RR32,RR32I,RDIV,RDIVI
|
|
REAL*8 RLAST,RSEED,RSHUF
|
|
LOGICAL RANINI
|
|
C
|
|
INTEGER I
|
|
INTEGER NTRY,NHIT,NGO
|
|
REAL*8 PI,PIEST,PIERR
|
|
REAL*8 X,Y,R
|
|
REAL*8 DUMMY
|
|
REAL*8 RANNUM
|
|
REAL*8 RTRY,RHIT
|
|
DATA PI /3.141592653589793D0/
|
|
DATA NTRY /0/
|
|
DATA NHIT /0/
|
|
C
|
|
RR32 = 4294967296.D0
|
|
RR32I = 1./RR32
|
|
RDIV = 33554432.D0
|
|
RDIVI = 1./RDIV
|
|
C
|
|
RSEED = 12345.D0
|
|
RLAST = 0.D0
|
|
RANINI = .FALSE.
|
|
C
|
|
READ(5,9000,ERR=910,END=900) IDBGRR,IDBGRN,IDBGMC
|
|
C
|
|
IF (IDBGRR.EQ.0 .AND. IDBGRN.EQ.0 .AND. IDBGMC.EQ.0)
|
|
X WRITE(6,9005)
|
|
C
|
|
100 READ(5,9010,ERR=910,END=900) NGO
|
|
IF (NGO .LE. 0) GOTO 900
|
|
C
|
|
DO 200 I=1,NGO
|
|
X = 2.*RANNUM(DUMMY) - 1.
|
|
Y = 2.*RANNUM(DUMMY) - 1.
|
|
R = X*X + Y*Y
|
|
NTRY = NTRY + 1
|
|
IF (R .LE. 1.) NHIT = NHIT + 1
|
|
IF (IDBGMC .NE. 0) WRITE(6,9030) X,Y,R,NHIT
|
|
200 CONTINUE
|
|
C
|
|
RTRY = NTRY
|
|
RHIT = NHIT
|
|
PIEST = 4.* RHIT / RTRY
|
|
PIERR = PIEST - PI
|
|
IF (PIERR .LT. 0.) PIERR = -PIERR
|
|
WRITE(6,9020) NTRY, NHIT,PIEST,PIERR,RLAST
|
|
GOTO 100
|
|
C
|
|
900 CONTINUE
|
|
C
|
|
STOP
|
|
C
|
|
910 WRITE(6,9040)
|
|
STOP
|
|
C
|
|
9000 FORMAT(3I10)
|
|
9005 FORMAT(1X,' ntry nhit pi-est',
|
|
X ' pi-err seed')
|
|
9010 FORMAT(I10)
|
|
9020 FORMAT(1X,'PI: ',I12,1X,I12,1X,F12.8,1X,F12.8,1X,F12.0)
|
|
9030 FORMAT(1X,'MC: ',F12.8,1X,F12.8,1X,F12.8,1X,I12)
|
|
9040 FORMAT(1X,'conversion error, abort')
|
|
C
|
|
END
|
|
$ENTRY
|
|
1 1 1
|
|
10
|
|
0
|
|
$STOP
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIPASF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=1024K,
|
|
// OPT='M+,D-',
|
|
// GOPARM='/STACK=512k'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: mcpi_pas.pas 978 2017-12-28 21:32:18Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-12-28 978 1.1 use inverse to avoid divide by constant *)
|
|
(* 2017-09-17 951 1.0 Initial version *)
|
|
(* 2017-09-07 948 0.1 First draft *)
|
|
|
|
program mcpi(input,output);
|
|
const
|
|
rr32 = 4294967296.0;
|
|
rdiv = 33554432.0;
|
|
pi = 3.141592653589793;
|
|
var
|
|
rseed,rlast : real;
|
|
ranini : boolean;
|
|
idbgrr,idbgrn,idbgmc : integer;
|
|
i,ntry,nhit,ngo : integer;
|
|
piest,pierr : real;
|
|
rhit,rtry : real;
|
|
x,y,r : real;
|
|
rr32i,rdivi : real;
|
|
rshuf : ARRAY[0 .. 127] of real;
|
|
|
|
function ranraw(dummy :real) : real;
|
|
var
|
|
rfac,rnew : real;
|
|
begin
|
|
rnew := rseed * 69069.0;
|
|
rfac := rnew * rr32i;
|
|
rfac := trunc(rfac);
|
|
rnew := rnew - rfac * rr32;
|
|
if idbgrr > 0 then writeln(' ','RR: ',rseed:14:1,rnew:14:1);
|
|
rseed := rnew;
|
|
ranraw := rnew;
|
|
end;
|
|
|
|
function rannum(dummy :real) : real;
|
|
var
|
|
rnew : real;
|
|
i : integer;
|
|
begin
|
|
if not ranini then begin
|
|
for i := 0 to 127 do rshuf[i] := ranraw(0.0);
|
|
ranini := TRUE;
|
|
end;
|
|
|
|
i := trunc(rlast*rdivi);
|
|
rlast := rshuf[i];
|
|
rshuf[i] := ranraw(0.0);
|
|
rnew := rlast * rr32i;
|
|
if idbgrn > 0 then writeln(' ','RN: ',i:12,rlast:14:1,rnew:14:8);
|
|
rannum := rnew;
|
|
end;
|
|
|
|
begin
|
|
rseed := 12345.0;
|
|
ranini := FALSE;
|
|
|
|
rr32i := 1.0/rr32;
|
|
rdivi := 1.0/rdiv;
|
|
|
|
read(idbgrr);
|
|
read(idbgrn);
|
|
read(idbgmc);
|
|
|
|
if (idbgrr=0) and (idbgrn=0) and (idbgmc=0) then
|
|
writeln(' ',' ntry nhit pi-est',
|
|
' pi-err seed');
|
|
|
|
while TRUE do begin
|
|
read(ngo);
|
|
if ngo = 0 then exit(0);
|
|
for i := 1 to ngo do begin
|
|
x := 2.0 * rannum(0.0) - 1.0;
|
|
y := 2.0 * rannum(0.0) - 1.0;
|
|
r := x*x + y*y;
|
|
ntry := ntry + 1;
|
|
if r <= 1.0 then nhit := nhit + 1;
|
|
if idbgmc > 0 then writeln(' ','MC: ',
|
|
x:12:8,y:12:8,r:12:8,nhit:12);
|
|
end;
|
|
|
|
rtry := ntry;
|
|
rhit := nhit;
|
|
|
|
piest := 4.0 * (rhit / rtry);
|
|
pierr := piest - pi;
|
|
writeln(' ','PI: ',ntry:12,nhit:12,piest:12:8,pierr:12:8,
|
|
rlast:14:1);
|
|
end;
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIPAST,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#PAS JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1024K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PASCLG,GOTIME=3600,GOREG=1024K,
|
|
// OPT='M+',
|
|
// GOPARM='/STACK=512k'
|
|
//COMPILE.SYSIN DD *
|
|
(* $Id: mcpi_pas.pas 978 2017-12-28 21:32:18Z mueller $ *)
|
|
(*
|
|
(* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> *)
|
|
(*
|
|
(* This program is free software; you may redistribute and/or modify *)
|
|
(* it under the terms of the GNU General Public License version 3. *)
|
|
(* See Licence.txt in distribition directory for further details. *)
|
|
(* *)
|
|
(* Revision History: *)
|
|
(* Date Rev Version Comment *)
|
|
(* 2017-12-28 978 1.1 use inverse to avoid divide by constant *)
|
|
(* 2017-09-17 951 1.0 Initial version *)
|
|
(* 2017-09-07 948 0.1 First draft *)
|
|
|
|
program mcpi(input,output);
|
|
const
|
|
rr32 = 4294967296.0;
|
|
rdiv = 33554432.0;
|
|
pi = 3.141592653589793;
|
|
var
|
|
rseed,rlast : real;
|
|
ranini : boolean;
|
|
idbgrr,idbgrn,idbgmc : integer;
|
|
i,ntry,nhit,ngo : integer;
|
|
piest,pierr : real;
|
|
rhit,rtry : real;
|
|
x,y,r : real;
|
|
rr32i,rdivi : real;
|
|
rshuf : ARRAY[0 .. 127] of real;
|
|
|
|
function ranraw(dummy :real) : real;
|
|
var
|
|
rfac,rnew : real;
|
|
begin
|
|
rnew := rseed * 69069.0;
|
|
rfac := rnew * rr32i;
|
|
rfac := trunc(rfac);
|
|
rnew := rnew - rfac * rr32;
|
|
if idbgrr > 0 then writeln(' ','RR: ',rseed:14:1,rnew:14:1);
|
|
rseed := rnew;
|
|
ranraw := rnew;
|
|
end;
|
|
|
|
function rannum(dummy :real) : real;
|
|
var
|
|
rnew : real;
|
|
i : integer;
|
|
begin
|
|
if not ranini then begin
|
|
for i := 0 to 127 do rshuf[i] := ranraw(0.0);
|
|
ranini := TRUE;
|
|
end;
|
|
|
|
i := trunc(rlast*rdivi);
|
|
rlast := rshuf[i];
|
|
rshuf[i] := ranraw(0.0);
|
|
rnew := rlast * rr32i;
|
|
if idbgrn > 0 then writeln(' ','RN: ',i:12,rlast:14:1,rnew:14:8);
|
|
rannum := rnew;
|
|
end;
|
|
|
|
begin
|
|
rseed := 12345.0;
|
|
ranini := FALSE;
|
|
|
|
rr32i := 1.0/rr32;
|
|
rdivi := 1.0/rdiv;
|
|
|
|
read(idbgrr);
|
|
read(idbgrn);
|
|
read(idbgmc);
|
|
|
|
if (idbgrr=0) and (idbgrn=0) and (idbgmc=0) then
|
|
writeln(' ',' ntry nhit pi-est',
|
|
' pi-err seed');
|
|
|
|
while TRUE do begin
|
|
read(ngo);
|
|
if ngo = 0 then exit(0);
|
|
for i := 1 to ngo do begin
|
|
x := 2.0 * rannum(0.0) - 1.0;
|
|
y := 2.0 * rannum(0.0) - 1.0;
|
|
r := x*x + y*y;
|
|
ntry := ntry + 1;
|
|
if r <= 1.0 then nhit := nhit + 1;
|
|
if idbgmc > 0 then writeln(' ','MC: ',
|
|
x:12:8,y:12:8,r:12:8,nhit:12);
|
|
end;
|
|
|
|
rtry := ntry;
|
|
rhit := nhit;
|
|
|
|
piest := 4.0 * (rhit / rtry);
|
|
pierr := piest - pi;
|
|
writeln(' ','PI: ',ntry:12,nhit:12,piest:12:8,pierr:12:8,
|
|
rlast:14:1);
|
|
end;
|
|
|
|
end.
|
|
/*
|
|
//GO.OUTPUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIPLIF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: mcpi_pli.pli 978 2017-12-28 21:32:18Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-28 978 1.1 use inverse to avoid divide by constant */
|
|
/* 2017-09-07 947 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
MCPI: PROC OPTIONS(MAIN) REORDER;
|
|
DCL RSEED DEC FLOAT(16) INIT(12345.);
|
|
DCL RLAST DEC FLOAT(16) INIT(0.);
|
|
DCL RSHUF(0:127) DEC FLOAT(16) INIT((128)0.);
|
|
DCL RR32 DEC FLOAT(16) INIT(4294967296.);
|
|
DCL RDIV DEC FLOAT(16) INIT(33554432.);
|
|
DCL RANINI BIN FIXED(31) INIT(0);
|
|
DCL (IDBGRR,IDBGRN,IDBGMC) BIN FIXED(31) INIT(0);
|
|
|
|
DCL RANRAW ENTRY RETURNS(DEC FLOAT(16));
|
|
DCL RANNUM ENTRY RETURNS(DEC FLOAT(16));
|
|
|
|
DCL (I,NTRY,NHIT,NGO) BIN FIXED(31) INIT(0);
|
|
DCL (PIEST,PIERR) DEC FLOAT(16);
|
|
DCL (RHIT,RTRY) DEC FLOAT(16);
|
|
DCL (RR32I,RDIVI) DEC FLOAT(16);
|
|
DCL (X,Y,R) DEC FLOAT(16);
|
|
DCL PI DEC FLOAT(16) INIT(3.141592653589793E0);
|
|
|
|
ON ENDFILE(SYSIN) GOTO DONE;
|
|
ON CONVERSION GOTO ABORT;
|
|
|
|
RR32I = 1./RR32;
|
|
RDIVI = 1./RDIV;
|
|
|
|
GET EDIT(IDBGRR,IDBGRN,IDBGMC) (3(F(10)));
|
|
|
|
IF IDBGRR=0 & IDBGRN=0 & IDBGMC=0 THEN
|
|
PUT SKIP EDIT(' ntry nhit pi-est',
|
|
' pi-err seed')(A,A);
|
|
|
|
DO WHILE('1'B);
|
|
GET SKIP EDIT(NGO) (F(10));
|
|
IF NGO = 0 THEN GOTO DONE;
|
|
|
|
DO I=1 TO NGO;
|
|
X = 2.*RANNUM - 1.;
|
|
Y = 2.*RANNUM - 1.;
|
|
R = X*X + Y*Y;
|
|
NTRY = NTRY + 1;
|
|
IF R <= 1. THEN NHIT = NHIT + 1;
|
|
IF IDBGMC > 0 THEN PUT SKIP EDIT('MC: ',X,Y,R,NHIT)
|
|
(A,3(F(12,8),X(1)),F(12));
|
|
END;
|
|
|
|
RTRY = NTRY;
|
|
RHIT = NHIT;
|
|
|
|
PIEST = 4.E0 * (RHIT / RTRY);
|
|
PIERR = PIEST - PI;
|
|
IF PIERR < 0. THEN PIERR = -PIERR;
|
|
PUT SKIP EDIT('PI: ',NTRY,NHIT,PIEST,PIERR,RLAST)
|
|
(A,2(F(12),X(1)),2(F(12,8),X(1)),F(12));
|
|
END;
|
|
GOTO DONE;
|
|
|
|
ABORT: PUT SKIP EDIT('Conversion error, abort')(A);
|
|
DONE:;
|
|
|
|
/* procedure RANRAW --------------------------------------------*/
|
|
RANRAW: PROC RETURNS(DEC FLOAT(16));
|
|
|
|
DCL (RFAC,RNEW) DEC FLOAT(16);
|
|
DCL IFAC BIN FIXED(31);
|
|
|
|
RNEW = RSEED * 69069.;
|
|
RFAC = RNEW * RR32I;
|
|
IFAC = RFAC;
|
|
RFAC = IFAC;
|
|
RNEW = RNEW - RFAC * RR32;
|
|
IF IDBGRR > 0 THEN PUT SKIP EDIT('RR: ',RSEED,RNEW)
|
|
(A,F(12,0),X(1),F(12,0));
|
|
RSEED = RNEW;
|
|
RETURN(RNEW);
|
|
END RANRAW;
|
|
|
|
/* procedure RANNUM --------------------------------------------*/
|
|
RANNUM: PROC RETURNS(DEC FLOAT(16));
|
|
DCL I BIN FIXED(31);
|
|
DCL RNEW DEC FLOAT(16);
|
|
|
|
IF RANINI = 0 THEN DO;
|
|
DO I=0 TO 127;
|
|
RSHUF(I) = RANRAW;
|
|
END;
|
|
RANINI = 1;
|
|
END;
|
|
|
|
I = RLAST * RDIVI;
|
|
RLAST = RSHUF(I);
|
|
RSHUF(I) = RANRAW;
|
|
RNEW = RLAST * RR32I;
|
|
IF IDBGRN > 0 THEN PUT SKIP EDIT('RN: ',I,RLAST,RNEW)
|
|
(A,F(12),X(1),F(12,0),X(1),F(12,8));
|
|
RETURN(RNEW);
|
|
END RANNUM;
|
|
END MCPI;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPIPLIT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#PLI JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=256K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC PL1LFCLG,
|
|
// PARM.PL1L='LOAD,NODECK,OPT=2',
|
|
// PARM.LKED='MAP,LIST'
|
|
//PL1L.SYSLIN DD UNIT=SYSDA
|
|
//PL1L.SYSIN DD *
|
|
/* 1 2 3 4 5 6 7*/--------
|
|
/*4567890123456789012345678901234567890123456789012345678901234567890*/--------
|
|
/* $Id: mcpi_pli.pli 978 2017-12-28 21:32:18Z mueller $ */
|
|
/*
|
|
/* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
|
/*
|
|
/* This program is free software; you may redistribute and/or modify */
|
|
/* it under the terms of the GNU General Public License version 3. */
|
|
/* See Licence.txt in distribition directory for further details. */
|
|
/* */
|
|
/* Revision History: */
|
|
/* Date Rev Version Comment */
|
|
/* 2017-12-28 978 1.1 use inverse to avoid divide by constant */
|
|
/* 2017-09-07 947 1.0 Initial version */
|
|
/* 2017-07-30 931 0.1 First draft */
|
|
|
|
MCPI: PROC OPTIONS(MAIN) REORDER;
|
|
DCL RSEED DEC FLOAT(16) INIT(12345.);
|
|
DCL RLAST DEC FLOAT(16) INIT(0.);
|
|
DCL RSHUF(0:127) DEC FLOAT(16) INIT((128)0.);
|
|
DCL RR32 DEC FLOAT(16) INIT(4294967296.);
|
|
DCL RDIV DEC FLOAT(16) INIT(33554432.);
|
|
DCL RANINI BIN FIXED(31) INIT(0);
|
|
DCL (IDBGRR,IDBGRN,IDBGMC) BIN FIXED(31) INIT(0);
|
|
|
|
DCL RANRAW ENTRY RETURNS(DEC FLOAT(16));
|
|
DCL RANNUM ENTRY RETURNS(DEC FLOAT(16));
|
|
|
|
DCL (I,NTRY,NHIT,NGO) BIN FIXED(31) INIT(0);
|
|
DCL (PIEST,PIERR) DEC FLOAT(16);
|
|
DCL (RHIT,RTRY) DEC FLOAT(16);
|
|
DCL (RR32I,RDIVI) DEC FLOAT(16);
|
|
DCL (X,Y,R) DEC FLOAT(16);
|
|
DCL PI DEC FLOAT(16) INIT(3.141592653589793E0);
|
|
|
|
ON ENDFILE(SYSIN) GOTO DONE;
|
|
ON CONVERSION GOTO ABORT;
|
|
|
|
RR32I = 1./RR32;
|
|
RDIVI = 1./RDIV;
|
|
|
|
GET EDIT(IDBGRR,IDBGRN,IDBGMC) (3(F(10)));
|
|
|
|
IF IDBGRR=0 & IDBGRN=0 & IDBGMC=0 THEN
|
|
PUT SKIP EDIT(' ntry nhit pi-est',
|
|
' pi-err seed')(A,A);
|
|
|
|
DO WHILE('1'B);
|
|
GET SKIP EDIT(NGO) (F(10));
|
|
IF NGO = 0 THEN GOTO DONE;
|
|
|
|
DO I=1 TO NGO;
|
|
X = 2.*RANNUM - 1.;
|
|
Y = 2.*RANNUM - 1.;
|
|
R = X*X + Y*Y;
|
|
NTRY = NTRY + 1;
|
|
IF R <= 1. THEN NHIT = NHIT + 1;
|
|
IF IDBGMC > 0 THEN PUT SKIP EDIT('MC: ',X,Y,R,NHIT)
|
|
(A,3(F(12,8),X(1)),F(12));
|
|
END;
|
|
|
|
RTRY = NTRY;
|
|
RHIT = NHIT;
|
|
|
|
PIEST = 4.E0 * (RHIT / RTRY);
|
|
PIERR = PIEST - PI;
|
|
IF PIERR < 0. THEN PIERR = -PIERR;
|
|
PUT SKIP EDIT('PI: ',NTRY,NHIT,PIEST,PIERR,RLAST)
|
|
(A,2(F(12),X(1)),2(F(12,8),X(1)),F(12));
|
|
END;
|
|
GOTO DONE;
|
|
|
|
ABORT: PUT SKIP EDIT('Conversion error, abort')(A);
|
|
DONE:;
|
|
|
|
/* procedure RANRAW --------------------------------------------*/
|
|
RANRAW: PROC RETURNS(DEC FLOAT(16));
|
|
|
|
DCL (RFAC,RNEW) DEC FLOAT(16);
|
|
DCL IFAC BIN FIXED(31);
|
|
|
|
RNEW = RSEED * 69069.;
|
|
RFAC = RNEW * RR32I;
|
|
IFAC = RFAC;
|
|
RFAC = IFAC;
|
|
RNEW = RNEW - RFAC * RR32;
|
|
IF IDBGRR > 0 THEN PUT SKIP EDIT('RR: ',RSEED,RNEW)
|
|
(A,F(12,0),X(1),F(12,0));
|
|
RSEED = RNEW;
|
|
RETURN(RNEW);
|
|
END RANRAW;
|
|
|
|
/* procedure RANNUM --------------------------------------------*/
|
|
RANNUM: PROC RETURNS(DEC FLOAT(16));
|
|
DCL I BIN FIXED(31);
|
|
DCL RNEW DEC FLOAT(16);
|
|
|
|
IF RANINI = 0 THEN DO;
|
|
DO I=0 TO 127;
|
|
RSHUF(I) = RANRAW;
|
|
END;
|
|
RANINI = 1;
|
|
END;
|
|
|
|
I = RLAST * RDIVI;
|
|
RLAST = RSHUF(I);
|
|
RSHUF(I) = RANRAW;
|
|
RNEW = RLAST * RR32I;
|
|
IF IDBGRN > 0 THEN PUT SKIP EDIT('RN: ',I,RLAST,RNEW)
|
|
(A,F(12),X(1),F(12,0),X(1),F(12,8));
|
|
RETURN(RNEW);
|
|
END RANNUM;
|
|
END MCPI;
|
|
/*
|
|
//LKED.SYSLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.STEPLIB DD DSN=SYS1.PL1LIB,DISP=SHR
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPISIMF,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1000K,TIME=(10,0),PRTY=2
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM=NOSUBCHK,
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
COMMENT
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
* 2017-09-17 951 1.0 Initial version
|
|
* 2017-09-08 949 0.1 First draft
|
|
*;
|
|
|
|
BEGIN
|
|
LONG REAL rr32,rr32i;
|
|
LONG REAL rdiv,rdivi;
|
|
LONG REAL pi;
|
|
LONG REAL rseed,rlast;
|
|
BOOLEAN ranini;
|
|
INTEGER idbgrr,idbgrn,idbgmc;
|
|
INTEGER i,ntry,nhit,ngo;
|
|
LONG REAL piest,pierr;
|
|
LONG REAL rhit,rtry;
|
|
LONG REAL x,y,r;
|
|
LONG REAL ARRAY rshuf(0:127);
|
|
|
|
LONG REAL PROCEDURE ranraw;
|
|
BEGIN
|
|
LONG REAL rfac,rnew;
|
|
rnew := rseed * 69069.0;
|
|
rfac := rnew * rr32i;
|
|
rfac := Entier(rfac);
|
|
rnew := rnew - rfac * rr32;
|
|
IF idbgrr > 0 THEN BEGIN
|
|
OutText("RR: ");
|
|
OutFix(rseed,1,14);
|
|
OutFix(rnew,1,14);
|
|
OutImage;
|
|
END;
|
|
rseed := rnew;
|
|
ranraw := rnew;
|
|
END ** ranraw **;
|
|
|
|
LONG REAL PROCEDURE rannum;
|
|
BEGIN
|
|
LONG REAL rnew;
|
|
INTEGER i;
|
|
IF NOT ranini THEN BEGIN
|
|
FOR i := 0 STEP 1 UNTIL 127 DO rshuf(i) := ranraw;
|
|
ranini := TRUE;
|
|
END;
|
|
i := Entier(rlast*rdivi);
|
|
rlast := rshuf(i);
|
|
rshuf(i) := ranraw;
|
|
rnew := rlast * rr32i;
|
|
IF idbgrn > 0 THEN BEGIN
|
|
OutText("RN: ");
|
|
OutInt(I,12);
|
|
OutFix(rlast,1,14);
|
|
OutFix(rnew,8,14);
|
|
OutImage;
|
|
END;
|
|
rannum := rnew;
|
|
END ** rannum **;
|
|
|
|
rr32 := 4294967296.0;
|
|
rr32i := 1.0/rr32;
|
|
rdiv := 33554432.0;
|
|
rdivi := 1.0/rdiv;
|
|
pi := 3.141592653589793;
|
|
rseed := 12345.0;
|
|
ranini := FALSE;
|
|
|
|
idbgrr := InInt;
|
|
idbgrn := InInt;
|
|
idbgmc := InInt;
|
|
|
|
IF idbgrr=0 AND idbgrn=0 AND idbgmc=0 THEN BEGIN
|
|
OutText(" ntry nhit pi-est");
|
|
OutText(" pi-err seed");
|
|
OutImage;
|
|
END;
|
|
|
|
WHILE TRUE DO BEGIN
|
|
ngo := InInt;
|
|
IF ngo = 0 THEN GOTO done;
|
|
FOR i := 1 STEP 1 UNTIL ngo DO BEGIN
|
|
x := 2.0 * rannum - 1.0;
|
|
y := 2.0 * rannum - 1.0;
|
|
r := x*x + y*y;
|
|
ntry := ntry + 1;
|
|
IF r <= 1.0 THEN nhit := nhit + 1;
|
|
IF idbgrr > 0 THEN BEGIN
|
|
OutText("MC: ");
|
|
OutFix(x,8,12);
|
|
OutFix(y,8,12);
|
|
OutFix(r,8,12);
|
|
OutInt(nhit,12);
|
|
OutImage;
|
|
END;
|
|
END;
|
|
rtry := ntry;
|
|
rhit := nhit;
|
|
|
|
piest := 4.0 * (rhit / rtry);
|
|
pierr := piest - pi;
|
|
|
|
OutText("PI: ");
|
|
OutInt(ntry,12);
|
|
OutInt(nhit,12);
|
|
OutFix(piest,8,12);
|
|
OutFix(pierr,8,12);
|
|
OutFix(rlast,1,14);
|
|
OutImage;
|
|
END;
|
|
|
|
done:
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
0 0 0
|
|
100
|
|
200
|
|
700
|
|
2000
|
|
7000
|
|
20000
|
|
70000
|
|
200000
|
|
700000
|
|
2000000
|
|
0
|
|
/*
|
|
//
|
|
./ ADD NAME=MCPISIMT,LEVEL=00,SOURCE=0,LIST=ALL
|
|
//MCPI#SIM JOB 'S322-0C4','WFJM',
|
|
// CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
|
|
// REGION=1000K,TIME=(1,0),PRTY=8
|
|
//CLG EXEC SIMCLG,
|
|
// PARM.SIM='',
|
|
// PARM.LKED='MAP,LIST,LET',
|
|
// PARM.GO='LINECNT=64'
|
|
//SIM.SYSIN DD *
|
|
COMMENT
|
|
*
|
|
* Copyright 2017- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
*
|
|
* This program is free software, you may redistribute and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* See Licence.txt in distribition directory for further details.
|
|
*
|
|
* Revision History:
|
|
* Date Rev Version Comment
|
|
* 2017-12-28 978 1.1 use inverse to avoid divide by constant
|
|
* 2017-09-17 951 1.0 Initial version
|
|
* 2017-09-08 949 0.1 First draft
|
|
*;
|
|
|
|
BEGIN
|
|
LONG REAL rr32,rr32i;
|
|
LONG REAL rdiv,rdivi;
|
|
LONG REAL pi;
|
|
LONG REAL rseed,rlast;
|
|
BOOLEAN ranini;
|
|
INTEGER idbgrr,idbgrn,idbgmc;
|
|
INTEGER i,ntry,nhit,ngo;
|
|
LONG REAL piest,pierr;
|
|
LONG REAL rhit,rtry;
|
|
LONG REAL x,y,r;
|
|
LONG REAL ARRAY rshuf(0:127);
|
|
|
|
LONG REAL PROCEDURE ranraw;
|
|
BEGIN
|
|
LONG REAL rfac,rnew;
|
|
rnew := rseed * 69069.0;
|
|
rfac := rnew * rr32i;
|
|
rfac := Entier(rfac);
|
|
rnew := rnew - rfac * rr32;
|
|
IF idbgrr > 0 THEN BEGIN
|
|
OutText("RR: ");
|
|
OutFix(rseed,1,14);
|
|
OutFix(rnew,1,14);
|
|
OutImage;
|
|
END;
|
|
rseed := rnew;
|
|
ranraw := rnew;
|
|
END ** ranraw **;
|
|
|
|
LONG REAL PROCEDURE rannum;
|
|
BEGIN
|
|
LONG REAL rnew;
|
|
INTEGER i;
|
|
IF NOT ranini THEN BEGIN
|
|
FOR i := 0 STEP 1 UNTIL 127 DO rshuf(i) := ranraw;
|
|
ranini := TRUE;
|
|
END;
|
|
i := Entier(rlast*rdivi);
|
|
rlast := rshuf(i);
|
|
rshuf(i) := ranraw;
|
|
rnew := rlast * rr32i;
|
|
IF idbgrn > 0 THEN BEGIN
|
|
OutText("RN: ");
|
|
OutInt(I,12);
|
|
OutFix(rlast,1,14);
|
|
OutFix(rnew,8,14);
|
|
OutImage;
|
|
END;
|
|
rannum := rnew;
|
|
END ** rannum **;
|
|
|
|
rr32 := 4294967296.0;
|
|
rr32i := 1.0/rr32;
|
|
rdiv := 33554432.0;
|
|
rdivi := 1.0/rdiv;
|
|
pi := 3.141592653589793;
|
|
rseed := 12345.0;
|
|
ranini := FALSE;
|
|
|
|
idbgrr := InInt;
|
|
idbgrn := InInt;
|
|
idbgmc := InInt;
|
|
|
|
IF idbgrr=0 AND idbgrn=0 AND idbgmc=0 THEN BEGIN
|
|
OutText(" ntry nhit pi-est");
|
|
OutText(" pi-err seed");
|
|
OutImage;
|
|
END;
|
|
|
|
WHILE TRUE DO BEGIN
|
|
ngo := InInt;
|
|
IF ngo = 0 THEN GOTO done;
|
|
FOR i := 1 STEP 1 UNTIL ngo DO BEGIN
|
|
x := 2.0 * rannum - 1.0;
|
|
y := 2.0 * rannum - 1.0;
|
|
r := x*x + y*y;
|
|
ntry := ntry + 1;
|
|
IF r <= 1.0 THEN nhit := nhit + 1;
|
|
IF idbgrr > 0 THEN BEGIN
|
|
OutText("MC: ");
|
|
OutFix(x,8,12);
|
|
OutFix(y,8,12);
|
|
OutFix(r,8,12);
|
|
OutInt(nhit,12);
|
|
OutImage;
|
|
END;
|
|
END;
|
|
rtry := ntry;
|
|
rhit := nhit;
|
|
|
|
piest := 4.0 * (rhit / rtry);
|
|
pierr := piest - pi;
|
|
|
|
OutText("PI: ");
|
|
OutInt(ntry,12);
|
|
OutInt(nhit,12);
|
|
OutFix(piest,8,12);
|
|
OutFix(pierr,8,12);
|
|
OutFix(rlast,1,14);
|
|
OutImage;
|
|
END;
|
|
|
|
done:
|
|
END;
|
|
/*
|
|
//GO.SYSOUT DD SYSOUT=*,OUTLIM=5000
|
|
//GO.SYSIN DD *
|
|
1 1 1
|
|
10
|
|
0
|
|
/*
|
|
//
|
|
./ ENDUP
|
|
@@
|
|
/*
|
|
//
|