DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦f6961fa77⟧ TextFile

    Length: 97536 (0x17d00)
    Types: TextFile
    Names: »tpascallib«

Derivation

└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ.
    └─⟦b2ec5d50f⟧ 
        └─⟦this⟧ »tpascallib« 

TextFile

; pascal library
;
; version 8
; date 79 07 03
;
; the contents is for the time being :
;  segmno  entries
;    0-1    runtime error 
;
;    2      ln
;           exp
;           sinh
;           system
;           clock
;
;    3      arcsin
;           sqrt
;           date
;           time
;
;    4      arctan
;           arg
;           cos
;           sin
;           monitor
;
;    5-6    file initialization
;           reset
;           rewrite
;           close
;           remove
;           replace
;
;    7-8   write (text)
;           real
;           integer
;           boolean
;           character
;           string
;          put
;
;     9-10 read (text)
;           iso
;           get
;           char
;           integer
;           real
;
;     11   read/write (binary)
;          pack
;          unpack
s. s10 w.
p.<:fpnames:>

; definition of zone states
; (values almost as in algol)
s1 = 1 ; after read char
s3 = 3 ; after write char
s4 = 4 ; after declaration
s5 = 5 ; after read binary
s6 = 6 ; after write binary
s8 = 8 ; after open
\f


; segment 0-1
; the virtual part of runtime error
; call :
;  w0 = abs addr of first of procedure table
;  w1 = abs addr of interrupt routine
;  w2 = abs addr of first of library table
;  w3 = abs addr of param-area
;
; the procedure writes out a text indicating a runtime
; error and a line number, then fp-end is called to terminate normally.
;

b. c50, g2 w.
g0:                    ; start of buffer
     jl.        g1.    ;   goto init;

; initcode for pascal-program:
; insert the programname 'pascrun' just before the old program name

b. a10, b10 w.

a0:                    ; start of initcode
     b10               ; size of initcode (number of words)

     rl  w0  x1+h51    ;   move fp-modebits to program stack
     rs. w0     b3.    ;

     la. w0     b0.    ;   remove fp-modebits: pause and list;
     rs  w0  x1+h51    ;

     al  w0  x2+b5     ;   current command := current command - simulated;
     rs  w0  x1+h8     ;

     rl. w0     b1.    ;   insert dummy 'end' in front;
a1:  rs  w0  x2+b5     ;
     rl  w0  x2        ;   move a possible lefthand side and
     al  w2  x2+2      ;     the delimiter preceding the program name;
     sh  w2  x3+2      ;
     jl.        a1.    ;

; now there is room for inserting a new program name etc.

     al. w3     b2.    ;   w3 := start of new program name etc.;
a5:  rl  w0  x3        ;
     rs  w0  x2+b5     ;   move new program name to fp-program stack;
     al  w2  x2+2      ;
     al  w3  x3+2      ;
     se. w3     b4.    ;
     jl.        a5.    ;

     al  w2     0      ;   w2 := normal return to fp;
     jl      x1+h7     ;   goto fp-end-program;

b0:  -1 - 1<3 - 1<0    ; mask out: pause + list from modebits

b1:  2<12 + 2          ; dummy 'end'-element;

b2:                    ; start of new program name etc:
     <:pascrun:>, 0    ;
     4<12 + 10         ;
     0                 ;
b3:  0-0-0             ; (old fp-mode bits)
     0                 ;
     0                 ;
     4<12 + 10         ;
b4:                    ; top of new program name etc:

b5 = b2 - b4 - 2       ; size of inserted elements (negative)


b10 = (:k - a0:) > 1   ; number of words in init-code

e.                     ;

\f



g2:                    ; start of text-table:
h.
      c0., c1., c2., c3., c4., c5., c6., c7., c8., c9.,
     c10.,c11.,c12.,c13.,c14.,c15.,c16.,c17.,c18.,c19.,
     c20.,c21.,c22.,c23.,c24.,c25.
w.
c0:<:end<0>:>
c1:<:process too small<0>:>
c2:<:index or subrange out of bounds, value is: <0>:>
c3:<:wrong answer on input request<0>:>
c4:<:wrong no of halfwords transferred<0>:>
c5:<:break<0>:>
c6:<:giveup, blocklength = <0>:>
c7:<:negative field width<0>:>
c8:<:replace file not ok<0>:>
c9:<::>
c10:<:negative argument to ln or sqrt<0>:>
c11:<:illegal argument to exp or sinh<0>:>
c12:<:illegal argument to arcsin<0>:>
c13: <:illegal zonestate<0>:>
c14:<:eof trouble<0>:>
c15:<:file cannot be connected for i/o<0>:>
c16:<:file cannot be removed<0>:>
c17:<:file desc. cannot be changed<0>:>
c18:<:file does not exist<0>:>
c19:<:file cannot be looked up<0>:>
c20:<:b,o or h expected<0>:>
c21:<:digit expected<0>:>
c22:<:try to read past eof<0>:>
c23:<:integer overflow<0>:>
c24:<:illegal pointer value<0>:>
c25:<:dispose outside used area<0>:>

     0, r. (:(:k+511:)>9<9-k:)>1 + 1  ; fill up to whole segment

b. a20, b30, d50, f10, m99, p10 w.

; d-names and f-names are relative to call in resident code

d38 =  0  ; error number
d39 =  2  ; stackref when error occured
d40 =  4  ; abs returnaddr where error occured
d41 =  6  ; return point: abs proc table entry
d42 =  8  ;               rel return addr
d43 = 10  ; current pascal procedure
f9  = 12  ; enter fp-break
f0  = 14  ; transfer from program file
d44 = 16  ; blocksread
d45 = 18 ; abs return address of last library call

; description of procedure table entry

p0  =  0  ; segment number in program file
p2  =  2  ; top of proc
p4  =  4  ; size of stack-space
p6  =  6  ; first of proc
p8  =  8  ; virtual addr of first error line

b0:  0                 ; abs start of procedure table
b1:  0                 ; abs addr of interrupt routine
b2:  0                 ; abs start of library table
b3:  0                 ; rs-param address

b5:                    ; abs addresses in fp
  m30: h30             ; unstack zone
  m31: h31-2           ; outtext
  m32: h32-2           ; outinteger
  m26: h26-2           ; outchar
  m7:  h7 -2           ; end-program
  m66: h66+2           ; bytes transferred in fp-answer
  m68: h68             ; fp-stderror
b6:                    ; (end of table)

b9:  <:<10>blocksread = <0>:>
b10: <:<10>occured in  <0>:>
b11: <:<10>called from <0>:>
b12: 0-0-0             ; abs line number
b13: <: = line <0>:>
b14: 0-0-0             ; rel line number
b15: <: of <0>:>
b16: 0, r.4, 0         ; procedure name (terminated with zero)
b17: <:   :>            ; (three spaces, to convert capital to small letters)

b18: <: rel of segm <0>:>

b20: -1 -1<23          ; max level (initially: max)
b21: 0                 ; current level (initially: zero)
b22: 0-0-0             ; procedure table entry
b23: 0-0-0             ; rel proc addr
b24: 0-0-0             ; cur virt error table addr
b25: 0                 ; index-value (initially zero)
b26: 0-0-0             ; stackref
b27: <: of library<0>:>
b28: <: of program<0>:>


; procedure get stack item
;
; call: w0 = wanted item no
;       w3 = return
;
; exit: w0 = actual item no
;       w1 = point: proc table entry
;       w2 =        rel proc return
;       w3 = stackref

b. i10, j10 w.

j0:  0                 ; saved return
j1:  0                 ; wanted item no

m0:                    ;
     ds. w0     j1.    ;   save (return, wanted item no);

     al  w0     0      ;   actual item no := 0;

     rl. w3     b3.    ;
     dl  w2  x3+d42    ;   w1w2 := return point where error occured;
     rl  w3  x3+d39    ;   w3 := stackref when error occured;

i1:                    ; rep:
     se. w0    (j1.)   ;   if act item no = wanted item no
     sh  w2    -1      ;   or rel return addr < 0 then
     jl.       (j0.)   ;     return;

     sl. w1    (b2.)   ;   if proc table entry >= first library entry then
     jl.        i3.    ;     goto after library call;

     dl  w2  x3-2041   ;   w1w2 := returnpoint (stackref);
     rx  w1     4      ;
     rl  w3  x3-2037   ;   w3 := dynamic link (stackref);
i2:                    ; next:
     ba. w0     1      ;   increase (act item no);

     jl.        i1.    ;   goto rep;

i3:                    ; after library call:
     rl. w1     b3.    ;
     rl  w2  x1+d45    ;   w2 := rel return from last library call;
     rl  w1  x1+d43    ;   w1 := current pascal procedure;
     ws  w2  x1+p6     ;

     jl.        i2.    ;   goto next;

e.                     ;


; procedure get next virt
;
; call: w3 = return
;
; exit: w0 = word
;       w2 = unchanged

b. i10, j10 w.

j0:  -1                ; current segment (initially: undef)
j1:  0                 ; saved w2
j2:  0                 ; return
j3:  0                 ; rel linebuffer

m1:                    ;
     ds. w3     j2.    ;   save (w2, return);

     rl. w1     b24.   ;
     al  w1  x1+2      ;   increase (cur virt addr);
     rs. w1     b24.   ;

     al  w0  x1-2      ;   segment := previous virt
     ld  w1    -9      ;           divided by 512;
     ls  w1    -24+9   ;   rel linebuffer := previous virt
     rs. w1     j3.    ;           mod 512;

     sn. w0    (j0.)   ;   if segment <> current segment then
     jl.        i1.    ;     begin

     rs. w0     j0.    ;     current segment := segment;
     rl. w2     b3.    ;
     jl  w2  x2+f0     ;     transfer from program file;
       jl.   a8.       ;+2:      ioerror: goto write absolute;

i1:                    ;     end;

     rl. w1     j3.    ;
     rl. w0  x1+g0.    ;   w0 := linebuffer (rel linebuffer);

     dl. w3     j2.    ;   restore (w2, return);
     jl      x3        ;   return;

e.                     ;


g1:                    ; init:

     ds. w1     b1.    ;   save (abs proc table start, interrupt address);
     ds. w3     b3.    ;   save (abs lib  table start, rs-param addr);

     rl  w2     66     ;
     rl  w2  x2+22     ;   w2 := first of process;
     al. w1     b5.    ;   w1 := first of fp-entry table
a0:                    ; rep:
     rl  w0  x1        ;
     wa  w0     4      ;   convert whole table to abs addresses;
     rs  w0  x1        ;
     al  w1  x1+2      ;
     se. w1     b6.    ;   if not whole table converted then
     jl.        a0.    ;     goto rep;

; unstack the whole chain for output-zone

     al  w1  x2+h21    ;   w1 := addr of 'output';
     al  w2  x2+h55+30 ;   w2 := addr of 'output' chain;
     al. w3     2      ;   w3 := return to here...
     rl  w0  x2        ; rep:
     se  w0     0      ;   while stackchain <> 0 do
     jl.       (m30.)  ;     unstack (output, output chain);

     rl. w0     m68.   ;   primary output.error action := fp-stderror;
     rs  w0  x1+h2+2   ;

     al  w2     10     ;
     jl. w3    (m26.)  ;   outchar (newline);

     rl. w2     b3.    ;

     rl  w1  x2+d38    ;   w1 := error number;
     se  w1     5      ;   if error number = break then
     jl.        a2.    ;     begin
     rl. w3     b1.    ;     w3 := interrupt address;
     rl  w1  x3+10     ;     w1 := break-address;

     rl  w0  x1-2      ;     w0 := erroneous instruction;
     se  w0     0      ;     if all zero then
     jl.        a11.   ;       begin <* io-errors are trapped as such *>
     rl. w0    (m66.)  ;       value := bytes transferred in fp-answer;
     al  w1     6      ;       error number := io-error;
     jl.        a12.   ;       goto set value and error;
a11:                   ;       end;

     ls  w0    -18     ;     w0 := instruction code (break-instruction);
     se  w0     30     ;     if instruction = 'instr 30' then
     jl.        a2.    ;       begin
     bz  w0  x1-2      ;
     ls  w0     12+6   ;
     ls  w0    -12-6-4 ;       w0 := w-field of instruction;
     ls  w0     1      ;
     wa  w3     0      ;
     rl  w0  x3        ;       value := regdump (w-field);

     al  w1     2      ;       w1 := error number := index-error;

a12:                   ; set value and error:
     rs. w0     b25.   ;
     rs  w1  x2+d38    ;
a2:                    ;       end;
                       ;     end;
     al. w0     g2.    ;
     wa  w0  x2+d38    ;   w0 := error table address (error number);
     ba  w0    (0)     ;   w0 := abs addresses of error text;
     jl. w3    (m31.)  ;   outtext (error text);

     rl  w0  x2+d38    ;
     sn  w0     0      ;   if error number = 0 <* i.e. normal end *> then
     jl.        a10.   ;     goto terminate;

     sn  w0     6      ;   if error number = io-error then
     al  w0     2      ;     error number := 2; <* force printing *>

     se  w0     2      ;   if error number = 2 <* index error *> then
     jl.        a3.    ;
     rl. w0     b25.   ;
     jl. w3    (m32.)  ;     outinteger (value);
       1<23 + 32<12 + 1;
a3:                    ;

     rl. w0     b20.   ;
     jl. w3     m0.    ;   max level := get stack item (maximum);
     rs. w0     b20.   ;

a1:                    ; unwind:
     rl. w0     b21.   ;
     sn. w0    (b20.)  ;   if cur level = max level then
     jl.        a10.   ;     goto terminate;

     jl. w3     m0.    ;   get stack item (cur level);
     ba. w0     1      ;
     rs. w0     b21.   ;   increase (cur level);

     sh. w1     0      ;   if proc table entry is rel then
     wa. w1     b0.    ;     make proc table entry abs;
     ds. w2     b23.   ;   save (point);
     rl  w2  x1+p8     ;   current virt error addr :=
     rs. w2     b24.   ;     virt error addr (proc table entry);
     rs. w3     b26.   ;   save (stackref);

     sn  w0     1      ;   text := if firstline then
     am         b10-b11;     <:occured in :> else
     al. w0     b11.   ;     <:called from :>;
     jl. w3    (m31.)  ;   outtext (text);

     rl. w0     b22.   ;   if called from library then
     sl. w0    (b2.)   ;
     jl.        a8.    ;     goto write absolute;

     jl. w3     m1.    ;   firstline := get virt;
     rs. w0     b12.   ;

     al. w2     b16.   ;
a5:  jl. w3     m1.    ;   procname := 4 * get virt;
     lo. w0     b17.   ;   (converted to small letters)
     rs  w0  x2        ;
     al  w2  x2+2      ;
     se. w2     b16.+8 ;
     jl.        a5.    ;

     rl. w2     b12.   ;   line := firstline;
a6:                    ; rep:
     al  w2  x2+1      ;   increase (line);
     jl. w3     m1.    ;   if get virt <= rel return then
c.-1
m.*** midlertidig omregning til halvord
 ls w0 1
z.
     sh. w0    (b23.)  ;
     jl.        a6.    ;     goto rep;

     al  w0  x2-2      ;
     jl. w3    (m32.)  ;   outinteger (line - 2);
       32<12 + 6       ;

     al. w0     b13.   ;
     jl. w3    (m31.)  ;   outtext (<: = line :>);

     al  w0  x2-2      ;
     ws. w0     b12.   ;
     jl. w3    (m32.)  ;   outinteger ( line-2 - firstline );
       32<12 + 2       ;

     al. w0     b15.   ;
     jl. w3    (m31.)  ;   outtext (<: of :>);

     al. w0     b16.   ;
     jl. w3    (m31.)  ;   outtext (procedure name);

m.***     jl.        a1.    ;   goto unwind;


a8:                    ; write absolute:
m.*** midlertidig udskrift af sref
     rl. w0     b26.   ;
     jl. w3    (m32.)  ;   outinteger (stackref);
       32<12 + 6       ;

     rl. w0     b23.   ;
     jl. w3    (m32.)  ;   outinteger ( rel proc return );
       1<23 + 32<12 + 4;

     al. w0     b18.   ;
     jl. w3    (m31.)  ;   outtext (<: rel of segm :>);

     rl. w2     b22.   ;
     rl  w0  x2+p0     ;
     jl. w3    (m32.)  ;   outinteger (segment number of procedure);
       32<12 + 2       ;

     sl. w2    (b2.)   ;   text := if entry < first of library table
     am         b27-b28;     then <: of library:>
     al. w0     b28.   ;     else <: of program:>;
     jl. w3    (m31.)  ;   outtext (text);

     jl.        a1.    ;   goto unwind;



a10:                   ; terminate:
     al. w0     b9.    ;
     jl. w3    (m31.)  ;   outtext (<:blocksread =:>);
     rl. w3     b3.    ;
     rl  w0  x3+d44    ;
     jl. w3    (m32.)  ;   outinteger (blocksread);
       32<12 + 1       ;
     al  w2     10     ;
     jl. w3    (m26.)  ;   outchar (newline);
     rl. w3     b3.    ;
     rl  w0  x3+d38    ;   w0 := error number;
     se  w0     0      ;   w2 := result :=
     am         1      ;     if normal end then 0 <* ok *>
     al  w2     0      ;      else 1 <* not ok *>;

     sn  w0     6      ;   if io-error then
     jl.        a13.   ;     goto stderror;

     se  w0     5      ;   if not break then
     jl.       (m7.)   ;     goto fp end-program;

     jl      x3+f9     ;   goto break;

a13: rl. w3     b1.    ; stderror:
     dl  w1  x3+2      ;   restore (w0,w1,w2,w3) from regdump;
     dl  w3  x3+6      ;
     jl.       (m68.)  ;   goto fp-stderror;

e.                     ; end program block;
e.                     ; end segment block;


\f


; segment 2
; library procedures : ln, exp, sinh, system, clock
; ln, exp sinh has been made by ns and nsa
 
0,r.(:1026-k:)>1
s. a1,b16,c17,d6,g5,w.
       jl.      d1.     ; entry ln
       jl.      d2.     ; entry exp
       jl.      d3.     ; entry sinh
       jl.      d5.     ; entry system
       jl.      d6.     ; entry clock
       0                ; saved stack top
d0:    0                ; save return adress
 
; working locations
g0:    0                ; single cell
       0
g2:    0                ; double cell
       0
g3:    0                ; double cell
       0
g4:    0                ; double cell

; floating point constants
       0
c0:    2048             ; 0
h.     1024   , 0       ;
c1:    0      , 1       ; 1
      -2048   , 0
c2:    0      , 0       ;-1
       1024   , 0
c3:    0      , 2       ; 2
       8.2613 , 8.4413
c4:    8.7676 , 0       ; ln2
       8.2650 , 8.1171
c5:    8.4640 , 0       ; sqrt2/2
       1024   , 0
c6:    0      , 0       ; 0.5

; constants for ln
       8.5154 , 8.3642
c7:    8.7704 , 1       ; d
       8.5603 , 8.5212
c8:    8.0121 , 1       ; c
       8.2411 , 8.1173
c9:    8.4457 , -2      ; b
       8.2705 , 8.2435
c10:   8.4504 , 2       ; a

; constants for exp
       8.2500 , 8.3355
c11:   8.6211 , 6       ; d
       8.2347 , 8.1522
c12:   8.3445 , 3       ; c
       8.3145 , 8.1273
c13:   8.6157 , -4      ; b
w.
c14=c3                  ; a

; integer constants
w.

c15:   2048
c16:  -2049
c17:   2049
 
 
; real procedure ln(u)
   
d1:    ds.w3    d0.     ; store return address  (entry from complex)

       sh w0    0       ; if u <= 0
       jl.       a0.    ;  then goto alarm message
       hs.w1    g0.     ; n := exponent(u)
       hl.w1   -5       ; x := fraction(u)
       dl w3    2
       fs.w1    c5.     ; x1:= x-1/sqrt2
       fa.w3    c5.     ; x2:= x+1/sqrt2
       fd w1    6       ; t := x1/x2
       ds.w1    g2.
       fm w1    2       ; t2:= t**2
       ds.w1    g3.
       fa.w1    c7.
       dl.w3    c8.
       fd w3    2
       fa.w3    c9.
       fm.w3    g3.
       fa.w3    c10.
       fm.w3    g2.     ; s := t*(a+t2*(b+c/(d+t2)))
       bl.w1    g0.
       ci w1    0
       fs.w1    c6.
       fa w1    6       ; r := s+n-0.5
       fm.w1    c4.     ; w0w1 := ln := r*ln2
       jl.       d4.    ; end ln
\f

; real procedure exp(u)

d2:    ds.w3    d0.     ; store return address  ( entry from complex )
       al w2    2
       al w3    b16
       jl.      b0.

; real procedure sinh(u)

d3:    ds.w3    d0.     ; store return address  ( entry from complex )
       al w2    b15
       al w3    b12
b0:    hs.w2    b13.
       hs.w3    b14.

       ds.w1    g2.     ;
       fd.w1    c4.     ; comment underflow may occur
       fa.w1    c6.     ; x := u/ln2+0.5
       bl w2    3       ; v := exponent(x)
       sl w2    14      ; if v >= 14
       jl.      b2.     ;  then goto b2
       as w0 x2-23      ; n := entier(fraction(x)*2**(v-23))
       rs.w0    g0.
       ci w0    0
       fm.w0    c4.     ; s := n*ln2
       dl.w2    g2.
       fs w2    0       ; x := u-s
       ds.w2    g2.
       fm w2    4       ; x2:= x**2
       ds.w2    g3.
       fa.w2    c11.
       dl.w0    c12.
       fd w0    4
       fa.w0    c13.
       fm.w0    g3.
       fa.w0    c14.
       ds.w0    g4.     ; s := a+x2*(b+c/(x2+d))
       fs.w0    g2.     ; s1 := s-x
       ds.w0    g3.
       dl.w1    g2.
       fm.w1    c3.
       fd.w1    g3.
       fa.w1    c1.     ; r := 1+2*x/s1
       rl.w2    g0.

b11:   jl.      0       ; branching for exp or sinh

b13 = b11+1
       ba w2   3        ; v := n+exponent(r)
       hl w1    5       ; r := r*2**n
       sl.w2   (c15.)   ; if v >= 2048
       jl.      b3.     ;  then goto b3
       sh.w2   (c16.)   ; if v <= -2049
b1:    dl.w1    c0.     ;  then exp := 0
       jl.       d4. 

b2:    rl.w3    g2.-2   ; b2:
       sh w3   -1       ; if u <= 0
b4:    jl.      0       ;     or called from exp then goto alarm
b3:    jl.       a1.    ; else goto b1

b14 = b4 + 1
b16 = b1-b4

; sinh
b5:    se w2    0
       jl.      b6.     ; if n <> 0 then goto b6
       dl.w1    c1.   
       dl.w3    g4.
       fa.w3    g2.
       fd w1    6
       dl.w3    c1.
       fd.w3    g3.     ; s1 := s-x
       fa w1    6       ; rh := (1/(s+x)+1/(s-x))*x
       fm.w1    g2.
       jl.      b9.     ; goto b9

b6:    sl w2    0       ; if n > 0
       jl.      b7.     ;  then goto b7
       dl.w3    c2.
       fd w3    2       ; r := -1/r
       dl w1    6
       ac.w2   (g0.)    ; n := -n
b7:    ba w2    3       ; b7: v := n + exponent(r)
       sl.w2   (c17.)   ; if v > 2048
       jl.       a1.   ;  then goto alarm
       sl w2    19      ; if v >= 19
       jl.      b10.    ;  then goto b10
       hs w2    3       ; r := r*2**n
       dl.w3    c1.
       fd w3    2
       fs w1    6
       fm.w1    c6.     ; w0w1 := (r-1/r)/2
b9:    jl.       d4. 
b10:   al w2 x2-1       ; b10:
       hl w1    5       ; w0w1 := r*2**(n-1)
       jl.       d4.    ; end sinh

b15 = b5-b11
b12 = b3-b4
 
; error return
a0:  am         10-11   ; alarm 10 negative argument
a1:  al  w1     11      ;   -   11
     rl. w2     d0.-2   ;
     rl  w3  x2+4       ;   add of runtime procedure
     rs. w3     d0.-2   ;
     rl  w2  x2+8       ;   w2 := stacktop
     rl. w3     d0.     ;   w3 := add where error occurred
     al  w0    -1       ;   indicate error ocuured in library
     jl.       (d0.-2)  ;   jump to rt error
 
d4:  dl. w3     d0.     ;
     rl  w2  x2+8       ;   w2 := stacktop
     jl      x3+2       ;

\f


; system
; call : 
;  w0 - add of integer
;  w1 - add of alfa
;  w2 - abs proc table entry (unimportant)
;  w3 - return - 4
;        +0  segm<12 + rel
;        +2  param no
m.******** hovsa: pas paa paging-fejl
; return
;  w1 - seperator (sep<12 + length) if error 0 is returned
;  and value set in integer var or alfa
;
; the procedure searches the fp-stack to find the parameter denoted by w0.
; if the parameter is found it is copied into either an integer or an alfa.
; if not found 0 is returned in the seperator.
 
b. b5, a7  w.
b0:  0,r.4               ;   saved registers
b1:  <:   :>           ;   (three spaces)
a0:  0                   ;
d5:  ds. w0     b0.+2    ;
     ds. w2     b0.+6    ;
     rl  w3  x3+2        ;
     rs. w3     a0.      ;
     rl  w2     66       ;
     rl  w2  x2+22       ;   w2 := process start
     rl  w2  x2+h8       ;   ptr := start of fp-stack
     al  w1     0        ;
a2:  sl. w1    (a0.)     ;   while par < wanted par then
     jl.        a1.      ;   begin
     ba  w2  x2+1      ;     increase (pointer);
     bl  w3  x2        ;     w3 := seperator;
     sh  w3     3      ;     if end of command then
     jl.        a4.    ;       goto not found;
     al  w1  x1+1        ;     param := param + 1
     jl.        a2.      ;   end
a1:  bz  w3  x2+1        ;   w3 := length
;ks-1100
     se  w3     4        ;   if integer then
     jl.        a5.      ;
     rl  w3  x2+2        ;
;ks-1101
     rs. w3    (b0.+2)   ;    int := value from fp-stack
     jl.        a6.      ;
a5:  se  w3     10       ;   if alfa then
     jl.        a4.      ;
     rl. w1     b0.+4    ;   w1 := add of alfa
     dl  w0  x2+4        ;
     lo. w3     b1.    ;
     lo. w0     b1.    ;
     ds  w0  x1+2        ;
     dl  w0  x2+8        ;   copy name from stack
     lo. w3     b1.    ;
     lo. w0     b1.    ;     (filled up with spaces)
     ds  w0  x1+6        ;   to alfa
a6:  rl  w1  x2          ;   w1 := seperator < 12 + length
a7:  rl. w2     b0.+6    ;  return
     rl  w2  x2+8        ;   reestablish stack top
     rl. w3     b0.      ;
     jl      x3+4        ;
a4:  al  w1     0        ;   error return
     jl.        a7.      ;
 
e.

; clock (real function)
; the procedure delivers the time elapsed since the process was started.
; the result may be delivered with an error the size of a time slice
; usually (25.6 msec).
; call :
;  w2 = proc table entry
;  w3 = return-2
;        +0: segm<12 + rel
; return :
;  w0,w1 result as a real
 
b. a1 w.
     10000<9
a0:  4096 + 14 - 47

d6:                    ; clock:
     ds. w3     d0.    ;
     rl  w1     66     ;
     dl  w1  x1+56     ;   time slices used by own process
     nd  w1     3      ;
     fd. w1     a0.    ;
     jl.        d4.    ;   return;
e.
e.
 
\f


; segment 3
;slang subroutines: arcsin, sqrt, date and time
;rc  30.11.70
;by ns adapted from nsa
; changed 78 03 30 by bbj to fit pascal

0,r.(:1538-k:)>1
b. a1,b25,c6,d14,g10,w.
       jl.      d1.     ; entry arcsin
       jl.      d2.     ; entry sqrt
       jl.       d12.   ; entry date
       jl.       d13.   ; entry time
 
       0                ; saved w2
d0:    0                ; save return adress
 
; working locations
w.
       0
g3:    0                ; double cell
       0
g4:    0                ; double cell
g8:    0

; floating point constants
h.
       1024   , 0
c1:    0      , 1       ; 1
      -2048   , 0
c2:    0      , 0       ;-1
       1024   , 0
c3:    0      , 2       ; 2
       8.3110 , 8.3755
c4:    8.2421 , 1       ; pi/2

; chebyshev constants for arcsin
       8.5737 , 8.2725
c5:    8.5063 , 5       ; p0,q0
       8.2607 , 8.1707
       8.7441 , 5       ; p1
       8.4222 , 8.3364
       8.1301 , 3       ; p2
       8.3174 , 8.7301
       8.3566 , -1      ; p3
       8.3067 , 8.2571
       8.5276 , 5       ; q1
       8.5325 , 8.2076
c6:    8.3306 , 4       ; q2

\f


w.
; real procedure arcsin(u)

d1:    ds.w3    d0.     ; store return address ( complex entry point )
       al w3    d8
       hs.w3    d6.

       bl w3    3       ; if exponent(u) <= -16
       sh w3   -16      ;  then arcsin := u
       jl.       d11.   ; else
       ds.w1    g3.     ;  begin
       sl w0    0    
       jl.      b0.
       fm.w1    c2.     ;
       bl w3    3
b0:    sh w3   -1       ; if abs(u) <= 0.5 then
       jl.      b1.     ;  begin
       al w3    b8
       hs.w3    b9.     ;  b := true
       jl.      b6.     ;  goto b6
b1:    al w3    2       ;  end
       hs.w3    b9.     ;  b := false
       fm w1    2       ;  u2 := u**2
       dl w3    2       ; w2w3:=u2
b3:    ds.w1    g4.     ;
       fa.w3    c6.     ;
       fm.w3    g4.     ;
       fa.w3    c6.-4   ;
       fm.w3    g4.     ;
       fa.w3    c5.     ;
       fm.w1    c6.-8   ;
       fa.w1    c6.-12  ;
       fm.w1    g4.     ;
       fa.w1    c6.-16  ;
       fm.w1    g4.     ;
       fa.w1    c5.     ;
       fd w1    6       ;
b5:    jl.      0       ;  if b then goto b7
       fm.w1    g3.     ;     arcsin := u*y
       jl.       d11.   ;     return

b6:    dl.w3    c1.     ; b6:
       fs w3    2
       sh w2   -1       ;  if abs(u) > 1
       jl.       a0.    ;   then goto alarm
       fd.w3    c3.
       dl w1    6       ;   u2 := (1-abs(u))/2
       jl.      b3.     ;   goto b3
b7:    rx.w0    g4.-2   ; b7:
       rx.w1    g4.     ;  w0w1 := u2
       jl.      d4.     ;  u1 := sqrt(u2)
d10:   fm.w1    g4.
       fm.w1    c3.
       fs.w1    c4.     ;  arcsin := y := 2*u1*y - pi/2
       rl.w2    g3.-2
       sl w2    0       ;   if u >= 0
       fm.w1    c2.     ;    then arcsin := -y
       jl.       d11.   ; end arcsin

b8 = b7-b5
b9 = b5+1
\f

; real procedure sqrt(u)

d2:    ds.w3    d0.     ; store return address ( complex entry point )

       al w3    d7
       hs.w3    d6.

d4:    sh w0    -1    ; if u<0
       jl.        a1. ; then goto alarm
       sn w0     0    ; if u=0
       jl.       d5.  ; then sqrt:=0 and jump out
       rl w3     0    ; else begin w3:=w0:=u0
       as w3     -2   ; start 1. iteration, w3:=u0/4
       rs.w3     g8.  ; store u0/4
       wa.w3     b21. ; w3:=u0/4+c/4
       rl.w2     b22. ; w2:=b/16
       wd w3     6    ; w3:=b/2/(u0+c)
       la.w3     b25. ; remove sign bit of w3
       wa.w3     b23. ; u1/2:=w3:=(a+b/(u0+c)
       rl.w2     g8.  ; start 2. iteration, w2:=u0/4
       rs.w3     g8.  ; store u1/2
       wd w3     6    ; w3:=u0/u1
       as w3     -1   ; w3:=u0/u1/2
       wa.w3     g8.  ; u2:=w3:=(u1+u0/u1)/2
       al w2   x3     ; start 3. iteration, w2:=u2
       bl w3     3    ; w3:=two_exp of u
       as w3     -1   ; w3:=two_exp//2
       sz w1        1 ; if two_exp is odd
       fm.w3     b24. ;  then w2w3:=w2w3*sqrt(2)
       fd w1     6    ; w0w1:=u/u2
       fa w1     6    ; w0w1:=u/u2+u2
       bl w2     3    ; w2:=two_exp of w0w1
       al w2  x2 -1   ; w2:=two_exp-1
       hl w1     5    ; w0w1:=w0w1/2:=sqrt(u)
d5:    jl.       0    ; end

b21:   8.2143 1676    ; c/4      c=2.1938165
b22:   8.6573 4114    ; b/16     b=-5.0350099
b23:   8.1116 2452    ; a/2-1    a=2.5764869. sqrt(u)=a+b/(u+c)
       8.2650 1171    ;
b24:   8.4640 0001    ; sqrt(2)
b25:   8.3777 7777    ; 2**23-1
d6=d5+1
m.****** sqrt: ikke pæn addressering
d7=b6-2-d5
d8=d10-d5

; return
d11: dl. w3     d0.   ;
     rl  w2  x2+8     ;
     jl      x3+2     ;   return
 
; error return
a0:  am         12-10 ; alarm 12 illegal arg to arcsin
a1:  al  w1     10    ; alarm 10 negative arg to sqrt
     rl. w2     d0.-2 ;
     rl  w3  x2+4     ;
     rs. w3     d0.-2 ;   store add of rt error
     rl  w2  x2+8     ;   w2 := stacktop
     rl. w3     d0.   ;   w3 := error address
     al  w0    -1     ;
     jl.       (d0.-2);   jump to rt error

\f


; date and time
; call :
;  w1 - add of alfa variable
;  w2 - abs add of proc table entry
;  w3 - return - 2
;
; the procedure returns the date and time in the alfa variable
; addressed by w1.
; the result is delivered as :
;  date : yy.mm.dd.
;  time : hh.mm.
;
b. a20, b10 w.
b0:  0,r.2              ;
b1:  10                 ;
b2:  48<16+48<8+46      ;
b3:  <:   :>            ;
b5:  0,r.4              ;
 
; variables and constants for short clock
a0:  1172               ;   units per minute
a1:  70313              ;     -    -  hour
a2:  1687500            ;     -    -  day
a3:  153                ;   days in five months (march-july)
a4:  1461               ;   days in four years
a5:  99111              ;   offset for computing year
a6:  5                  ;
     0                  ;   saved minute
a9:  0                  ;   saved hour
a11=461                 ;   three months offset
a12=5                   ;   one days offset
a13=586                 ;   half a minute
 
d12: am         1      ;   date
d13: al  w0     0      ;   time
     ds. w1     b0.+2  ;
     ds. w3     d0.    ;
     jd         1<11+36;   get clock
     ld  w1     5      ;
;ks-1200

; short clock
     ld  w2    -100    ;   clear w1,w2
     al  w3     0      ;   clear w3
     ld  w0     10     ;   w3,w0:= truncated clock>9
     wd. w0     a2.    ;   w0 := dayno
     al  w3  x3+a13    ;   add minute rounding
     wd. w3     a1.    ;   w3 := hour
     wd. w2     a0.    ;   w2 := minute
     ds. w3     a9.    ;   save minute , hour
     al  w3     0      ;
     ld  w2    -100    ;     
     ls  w0     2      ;   w0 := dayno*4
     wa. w0     a5.    ;   add offset
     wd. w0     a4.    ;   w0 := year
     ls  w3    -2      ;   w3 is converted
     wm. w3     a6.    ;   to fitfh-days
     al  w3  x3+a11    ;   w3 := w3+three months offset
     wd. w3     a3.    ;   w3:=month
     sh  w3     12     ;   if month > 12 then
     jl.        a15.   ;   begin
     ba. w0     1      ;     increase year
     al  w3  x3-12     ;     decrease month
a15: al  w2  x2+a12    ;   end
     wd. w2     a6.    ;   w2:=date
; end short clock

     rl. w1     b0.    ;
     sn  w1     0      ;   if 0 then
     jl.        b4.    ;    goto time
;ks-1201

; date
;  w0 - year
;  w1 - month
;  w2 - day
     ds. w3     b5.+6   ;
     rl  w1     0       ;
     jl. w2     b10.    ;   pack into chars
     rl. w3     b0.+2   ;
     rs  w0  x3         ;   alfa(1) := year
     rl. w1     b5.+6   ;
     jl. w2     b10.    ;
     rs  w0  x3+2       ;   alfa(2) := month
     rl. w1     b5.+4   ;
     jl. w2     b10.    ;
     rs  w0  x3+4       ;   alfa(3) := day
     jl.        b6.     ;   return
 
; time
; a9 - hour
; a9-2 - minute
b4:  rl. w1     a9.     ;
     jl. w2     b10.    ;
     rl. w3     b0.+2   ;
     rs  w0  x3         ;   alfa(1) := hour
     rl. w1     a9.-2   ;
     jl. w2     b10.    ;
     rs  w0  x3+2       ;   alfa(2) := minute
     rs  w1  x3+4       ;   alfa(3) := <:   :>
b6:  rs  w1  x3+6       ;   alfa(4) := <:   :>
     jl.        d11.    ;   return

; pack an integer to a string
; w1 - number to split into characters
; w2 - return
b10: al  w0     0       ;
     wd. w1     b1.     ;
     ls  w1     16      ;   first digit < 16
     ls  w0     8       ;  +second digit < 8
     lo  w0     2       ;
     wa. w0     b2.     ;  +space
     rl. w1     b3.     ;
     jl      x2         ;
e.
e.
\f


; segment 4
;slang subroutines:  arctan, arg, cos, sin, monitor
;by ns adapted from nsa
; changed 78 03 30 by bbj to fit pascal

0, r.(:2050-k:)>1
b. b12,c27,d14,g6,w.
       jl.      d1.     ; entry arctan
       jl.      d2.     ; entry arg
       jl.      d3.     ; entry cos
       jl.      d4.     ; entry sin

       0                ; saved w2
d0:    0                ; save return adress
w.
; working locations

       0
g0:    0                ; double cell
       0
g1:    0                ; double cell
       0
g2:    0                ; double cell
g3:    0
g4:    0
g5:    0
g6:    0


; floating point constants

h.     0      , 0
c0:    0      ,-2048    ; 0
       1024   , 0
c1:    0      , 1       ; 1
      -2048   , 0
c2:    0      , 0       ;-1
       1024   , 0
c3:    0      , 2       ; 2
       8.3110 , 8.3755
c4:    8.2421 , 0       ; pi/4
       8.3110 , 8.3755
c5:    8.2421 , 1       ; pi/2
       8.3110 , 8.3755
c6:    8.2421 , 2       ; pi
       8.3110 , 8.3755
c7:    8.2421 , 3       ; pi*2
       8.3240 , 8.4746
c8:    8.3177 ,-1       ; sqrt2 - 1

; constants for arctan

w.     c20=c1           ; d0
h.     8.4005 , 8.1433
c21:   8.5135 ,-6       ; d1
       8.2063 , 8.3675
c22:   8.1510 , 2       ; d2
       8.3173 , 8.7332
c23:   8.5776 , 1       ; d3
       8.5521 , 8.2144
c24:   8.6150 , 0       ; e1
       8.4513 , 8.6070
c25:   8.1005 ,-1       ; e2

; constants for sin

       8.4317 , 8.1351
c26:   8.3444 ,-18      ; a5
       8.2500 , 8.1775
       8.7702 ,-12      ; a4
       8.5464 , 8.5673
       8.3771 ,-7       ; a3
       8.2431 , 8.5357
       8.7411 ,-3       ; a2
       8.5325 , 8.0414
       8.3304 , 0       ; a1
       8.3110 , 8.3755
       8.2420 , 1       ; a0
\f


w.
; real procedure arctan(u)

d1:    ds.w3    d0.     ; store return address  (entry from complex)
       al w2    d10
       hs.w2    d7.

d5:    ds.w1    g0.
       sh w0   -1       ; absu := abs(u)
       jl.      b0.
       dl.w3    c4.
       jl.      b1.
b0:    dl.w1    c0.     ; phi := if u >= 0 then pi/4
       ds w1    6       ;        else -pi/4
       fs.w1    g0.
       fs.w3    c4.
b1:    ds.w1    g1.
       fs.w1    c8.
       sl w0    0       ; if absu < sqrt2-1 then
       jl.      b2.     ;  begin
       dl.w1    g0.     ;   t := u; phi := 0
       dl.w3    c0.     ;  end
       jl.      b4.     ;
b2:    fs.w1    c3.     ; else
       sl w0    0       ; if absu < sqrt2 + 1 then
       jl.      b3.     ;  begin
       dl.w1    g1.
       fs.w1    c2.
       ds.w1    g2.
       dl.w1    g1.
       fa.w1    c2.
       fd.w1    g2.     ;  t := (absu - 1)/(absu + 1)
       rx.w3    g0.-2
       sh w3   -1       ;  if u <= 0 then
       fm.w1    c2.     ;   t := -t
       rx.w3    g0.-2   ; end
       jl.      b4.     ; else
b3:    dl.w1    c2.     ; begin
       fd.w1    g0.     ;   t := -1/u
       al w3 x3+1       ;   phi := 2*phi
b4:    ds.w3    g1.     ;  end;
       ds.w1    g0.     ; comment (g0) := t ,  (g1) := phi
       bl w3    3       ; if exponent(t) <= -18 then
       sh w3   -18      ;  arc := t
       jl.      b5.     ; else
       fm w1    2       ;  begin
       ds.w1    g2.     ;   t2 := t**2
       fa.w1    c23. 
       dl.w3    c25.
       fd w3    2
       fa.w3    g2.
       fa.w3    c22.
       dl.w1    c24.
       fd w1    6
       fa.w1    c21.
       fm.w1    g2.
       fa.w1    c20.
       fm.w1    g0.     ;   arc := t*(d0+t2*(d1+e1/(d2+t2+e2/(t2+d3))))
                        ;  end
b5:    fa.w1    g1.     ; arctan := phi + arc
d7 = b5+3
d9:    jl.      0       ; if called from arg then return to arg
                        ; end arctan
\f


d2:    ds.w3    d0.     ; return address; comment entry from complex
m.***** 'arg' can't be called like this...

       dl w3 x2
       ds.w3    g4.     ; commment (g4) := x
       ds.w1    g6.     ; comment (g6) := y
       bl w1    3
       bs w1    7       ;  n := exponent(y) - exponent(x)
       sh w1    36      ; if n > 36 then
       jl.      b7.     ; b6:
b6:    dl.w1    c5.     ;  begin
       rl.w2    g5.     ;   arg := pi/2
       sh w2   -1       ;   if y < 0
       fm.w1    c2.     ;    then arg := -pi/2
       jl.       d11.   ;  end
d10=k-2-d9              ; else
b7:    sl w1   -2047    ; if n < -2047 then
       jl.      b9.     ; b8: begin
b8:    dl.w1    c0.     ;      arg := 0
       rl.w2    g3.   
       sh w2   -1       ;      if x < 0
       dl.w1    c6.     ;       then arg := sign(y)*pi
       jl.      b6.+2   ;    end
b9:    dl.w1    g6.     ; else
                        ;  begin
       sn w0    0       ;   if y = 0
       jl.      b8.     ;    then goto b8
       sn w2    0       ;   if x = 0
       jl.      b6.     ;    then goto b6
       fd w1    6
       al w2    d8
       hs.w2    d7.
       jl.      d5.     ; arg := phi := arctan(y/x)
d6:    rl.w2    g3.
d8 = d6-d9
       sl w2    0       ;  if x < 0
       jl.       d11.
       rl.w2   g5.      ;
       sh w2   -1       ; if y < 0
       fs.w1    c6.     ;
       sl w2    0       ;
       fa.w1    c6.     ;  arg := phi + sign(y)*pi
       jl.       d11.   ; end arg
\f


; real procedure cos(u)

d3:    ds.w3    d0.     ; store return address ( entry from complex )
       dl.w3    c5.
       fs w3    2
       dl w1    6       ; u := pi/2 - u
       jl.      b10.     ; cos := sin(u)

; real procedure sin(u)

d4:    ds.w3    d0.     ; store return address  ( entry from complex )

b10:   bl w3    3
       sh w3   -18      ;  if exponent(u) <= 18 then
       jl.       d11.   ;   sin := u
       fd.w1    c5.     ;  else
       bl w2    3       ;  if exponent(u/pi/2) > 35 then
       sh w2    35      ;   sin := 0
       jl.      b11.
       dl.w1    c0.     ;  else
       jl.       d11.   ;   begin
b11:   sh w2    22      ;    z := u/pi/2
       jl.      b12.    ;    if exponent(z) > 22 then
       rs w0    6       ;     begin
       as w3 x2-43
       ci w3    20      ;      z1 := entier(z*2**(-20))*2**20
       fs w1    6       ;      z  := z - z1
                        ;     end
b12:   rs w0    6
       bl w2    3
       as w3 x2-23
       al w3 x3+1
       as w3   -1
       rs.w3    g5.     ;  n := (entier(z)+1)2
       ci w3    1
       fs w1    6       ;  x := z-float(2*n)
       rl.w2    g5.
       sz w2    1       ; if n is odd
       fm.w1    c2.     ;  then x := -x
       ds.w1    g2.
       fm w1    2       ; x2 := x*x
       ds.w1    g4.     ; p := x2
       fm.w1    c26.    ; p := p*a5
       fa.w1    c26.+4  ; p := p + a4
       fm.w1    g4.     ; p := p * x2
       fa.w1    c26.+8  ; p := p + a3
       fm.w1    g4.     ; p := p * x2
       fa.w1    c26.+12 ; p := p + a2
       fm.w1    g4.     ; p := p * x2
       fa.w1    c26.+16 ; p := p + a1
       fm.w1    g4.     ; p := p * x2
       fa.w1    c26.+20 ; p := p + a0
       fm.w1    g2.     ; sin := x*p
       jl.       d11.   ; end sin

d11: dl. w3     d0.   ;
     rl  w2  x2+8     ;
     jl      x3+2     ;   return
0,r.(:2562-k:)>1
e.
\f


; segment 5-6
; file handling procedures
; call parameters :
;  w0 - see each procedure
;  w1 - add of zone descriptor + -h0 (+36)
;  w2 - abs add of proc table entry
;  w3 - return - 2
;
; the stack picture looks like (if not input or output) :
;   name of file    (8 halfwords)
;   zone descriptor (h5 halfwords)
;   share    -      (h6    -     )
;   data buffer     (512   -     )
;   file buffer (if binary file)
;
; the following free parameters in a zone descriptor
; are used by the pascal i/o system :
;
;   z+h2+6 (halfword) : zone state (almost as in algol)
;                           (see definition of s-names)
;   z+h2+7 (halfword) : file type
;                         0 = binary
;                         1 = text
;                         2 = iso
;   z+h3+6 (word)     : (not used, but could be used for recsize)
;   z+h4+0 (halfword) : eof
;                         0 = false
;                         1 = true
;   z+h4+1 (halfword) : eoln
;                         0 = false
;                         1 = true
;   z+h4+2 (word)     : length of binary file (irrell if text file)
;                         read: remaining halfwords
;                         write: number of halfwords written
;   z+h4+4 (word)     : file buffer
;                         binary file: address of filebuf
;                         text file  : next character
;
; the following field is used in the share descriptor:
;
;   first share+(14:20) : file name
;
; the organization of the code :
;
;  init and select
;  file initialization (i1)  4<12 + 0
;  reset               (i2)  4<12 + 2
;  rewrite             (i3)  4<12 + 4
;  close               (i4)  4<12 + 6
;  remove              (i5)  4<12 + 8
;  replace             (i9)  4<12 + 10

; monitor              (i10) 4<12 + 12

;  error return
;
; b-variables are global variables for all procedures
; c-variables are error returns
;
\f


b. b20, c10, i10 w.

     jl.        i0.    ;+0
     jl.        i0.    ;+2
     jl.        i0.    ;+4
     jl.        i0.    ;+6
     jl.        i0.    ;+8
     jl.        i0.    ;+10
     jl.        i0.    ;+12

b0:  0                 ; saved w0: (sometimes addr of name)
b1:  0                 ; saved w1: zone address
b2:  0                 ; saved w2: proc table entry
b3:  0                 ; saved w3: (increased) return

b4:  0                 ; first of process
b5:  0, r.10           ; tail for lookup entry

i0:                    ; common entry:
     al  w3  x3+2      ;   (increase entry);
     ds. w1     b1.    ;
     ds. w3     b3.    ;   save (registers);

     bl  w2  x3-1      ;   w2 := rel entry;
     am        (66)    ;
     rl  w3    +22     ;   w3 := first of process;
     rs. w3     b4.    ;   save (first of process);

     bl  w0  x1+h2+6   ;   w0 := zone state;

; w0 = zone state
; w1 = zone
; w2 = rel entry
; w3 = first of process

     jl.     x2+2      ;   switch to:

     jl.        i1.    ;   file init
     jl.        i2.    ;   reset
     jl.        i3.    ;   rewrite
     jl.        i4.    ;   close
     jl.        i5.    ;   remove
     jl.        i9.    ;   replace
     jl.        i10.   ;   monitor
 
\f


; file initialization
; this procedure has two parameters in the original call :
;  +0 4<12 + 0
;  +2 text (1) / binary (0) / iso (2)
;
; the procedure initializes a zone and share descriptor :
;  base buffer area
;  set share to base buffer area + 1
;  last add of buffer
;  used share
;  first share
;  last share
;  give up mask
;  give up action
;
; also the private variables are set:
;  zone state
;  file type
;  eof
;  length of binary file
;  file buffer
;  file name
;
; if zone is 'current in' or 'current out' then the zone
; is stacked prior to initializing private variables
;
; call parameters :
;  w0 - add of external file name 
;  w1 - zone add
;

b. a10 w.

i1:                    ; file init:
     se  w1  x3+h20    ;   if zone = current input then
     jl.        a1.    ;

     jl  w3  x3+h29-4  ;     stack current input
     jl.        a5.    ;   else
a1:                    ;
     se  w1  x3+h21    ;   if zone = current output then
     jl.        a2.    ;     begin
     al  w2  x3+h55+30 ;     chain := std chain for output;
     jl  w3  x3+h29    ;     stack zone;
     jl.        a5.    ;     end
a2:                    ;   else
m.*** 'fileinit': midlertidigt ingen test af zonestate
c.-1
     se  w0     s4     ;   if zonestate <> after decl then
     jl.        c6.    ;     error(illegal zone state);
z.

; the following initialization ougth to be done in a separate call

     al  w2  x1+h0+h5  ;   w2 := address of share 0 := first free after zone;

     al  w3  x2+h6-1   ;   w3 := base buffer := last of share descr;
     al  w0  x3+512    ;   w0 := last of buffer; (* bufsize = 512 *)
     ds  w0  x1+h0+2   ;

     ba. w0     1      ;   first of file buffer :=
     rs  w0  x1+h4+4   ;     top of buffer;

     al  w3  x3+1      ;   first shared (share 0) :=
     rs  w3  x2+2      ;     first of buffer;

     rs  w2  x1+h0+4   ;   used share := share;
     rs  w2  x1+h0+6   ;   first share:= share;
     rs  w2  x1+h0+8   ;   last share := share;

     al  w0     0      ;
     rs  w0  x2+14     ;   filename(0) (in share 0) := 0; <* prepare rewrite *>
     rs  w0  x1+h2+0   ;   giveup mask := 0;
     rl. w3     b4.    ;
     rl  w0  x3+h20+h2+2;  (use same giveup action as in primary input);
     rs  w0  x1+h2+2   ;   giveup action := pascal runtime system;

     rl. w3     b3.    ;
     bl  w0  x3+1      ;   filetype := param from call;
     hs  w0  x1+h2+7   ;

a5:                    ; common init:
     al  w0     s8     ;   zone state := after open;
     hs  w0  x1+h2+6   ;

     rl. w3     b0.    ;   w3 := file name param;
     rl  w2  x1+h0+6   ;   w2 := file name addr;
     al  w2  x2+14     ;

     dl  w1  x3+2      ;   move filename from param
     ds  w1  x2+2      ;     to share 0 (* for later use by 'reset' etc *)
     dl  w1  x3+6      ;
     ds  w1  x2+6      ;
     jl. w3     i8.    ;   replace trailing spaces by nulls;

     rl. w3     b3.    ;
     al  w3  x3+2      ;   increase (return); i.e. skip filename param;
     rs. w3     b3.    ;

     jl.        i7.    ;   return;

e.

\f


; reset
; the procedure has the following function :
;  terminate transfers
;  if file does not exist then error
;  connect input
;  copy file length to zone description

b. a10 w.

i2:                    ; reset:
     sn  w0     s4     ;   if zone state = after decl then
     jl.        c6.    ;     error (illegal zone state);

     jl. w3     i6.    ;   terminate transfer;

     rl  w3  x1+h0+6   ;   w3 := file name addr;
     al  w3  x3+14     ;
     al. w1     b5.    ;
     jd         1<11+42;   lookup entry;
     se  w0     0      ;   if not ok then
     jl.        c2.    ;     error (file does not exist);

     al  w2  x3        ;
     rl. w1     b1.    ;   w1 := zone;
     am.       (b4.)   ;
     jl  w3    +h27    ;   connect input (zone, filename);
     se  w0     0      ;   if not ok then
     jl.        c5.    ;     error (file not connected);

     rs  w0  x1+h4+0+1 ;   eof := eoln := false;

     rl. w0     b5.+18 ;   zone.filelength :=
     rs  w0  x1+h4+2   ;     tail.length;  <* irrell for text files *>

     bl  w0  x1+h2+7   ;   zonestate :=
     sn  w0     0      ;     if filetype = binary then
     am         s5-s1  ;       after read binary
     al  w0     s1     ;     else
     hs  w0  x1+h2+6   ;       after read char;
m.*** 'reset': midlertidig opdigtet 'newline'
c.+1
     al  w2     10     ;
     sn  w0     s1     ;   if read char then
     rs  w2  x1+h4+4   ;     filebuf := newline;
     al  w2     1      ;
     sn  w0     s1     ;   if readchar then
     hs  w2  x1+h4+1   ;     eoln := true;
z.

     jl.        i7.    ;   return;
e.
 

\f


; rewrite
; the function of the procedure :
;  terminate transfer
;  connect output
;  reset filelength

b. a10 w.

i3:                    ; rewrite:
; notice: the check on zonestate is not needed, because the
;         filename is initialized to zero by 'file init'
     sn  w0     s4     ;   if zonestate = after decl then
     jl.        c6.    ;     error (illegal zonestate);

     jl. w3     i6.    ;   terminate transfer;

     rl  w2  x1+h0+6   ;   w2 := filename addr;
     al  w2  x2+14     ;
     al  w0     1<1+1  ;   w0 := 1 slice, pref. on disc;
     am.       (b4.)   ;
     jl  w3    +h28    ;   connect output (zone, filename, w0);
     se  w0     0      ;   if not ok then
     jl.        c5.    ;     error (file cannot be connected);
; notice: fp will initialize filename, if it was empty

m.***** rewrite: ad hoc metode: nulstil segm count
     rs  w0  x1+h1+16  ;   segment count := 0;
     rs  w0  x1+h4+2   ;   filelength := 0;

     rl  w2  x1+h0+6   ;   w2 := file name addr;
     al  w2  x2+14     ;
     se  w0 (x2+0)     ;   if filename was empty then
     jl.        a1.    ;     begin
     dl  w0  x1+h1+4   ;
     ds  w0  x2+2      ;     move zonename to filename;
     dl  w0  x1+h1+8   ;
     ds  w0  x2+6      ;
a1:                    ;   end;
     al  w2     1      ;   eof := true;
     hs  w2  x1+h4+0   ;

     bl  w0  x1+h2+7   ;   zonestate :=
     sn  w0     0      ;     if filetype = binary then
     am         s6-s3  ;       after write binary
     al  w0     s3     ;     else
     hs  w0  x1+h2+6   ;       after write char;

     jl.        i7.    ;   return;
e.

\f


; close
; the function of the procedure:
;  if file not used then the procedure is blind
;  terminate transfers
;  if 'current in' and not 'i-bit' then unstack
;  if 'current out' then unstack

b. a10 w.

i4:                    ; close:
     sn  w0     s4     ;   if zonestate = after decl then
     jl.        i7.    ;     return;

     jl. w3     i6.    ;   terminate transfer;

     al  w0     s4     ;   zonestate :=
     hs  w0  x1+h2+6   ;     after decl;

     rl. w3     b4.    ;   w3 := first of process;

     se  w1  x3+h20    ;   if zone = 'current in' then
     jl.        a1.    ;     begin
     rl  w0  x1+h2+0   ;     if 'i-bit' not set in giveup mask then
     so  w0     2.1    ;
     jl  w3  x3+h30-4  ;       unstack current input;
     jl.        i7.    ;     end
a1:                    ;   else
     al  w2  x3+h55+30 ;
     sn  w1  x3+h21    ;   if zone = 'current out' then
     jl  w3  x3+h30    ;     unstack (current output chain);

     jl.        i7.    ;   return;
e.


; remove entry
; the procedure cancels files
; no matter the result of the remove it is assumed to be ok. (30/11/78)
;
b. w.

i5:                    ; remove:
     rl  w3  x1+h0+6   ;   w3 := file name addr;
     al  w3  x3+14     ;
     jd         1<11+48   ;   remove entry
;ks-820
;    sn  w0     0         ;   if entry removed then
     jl.        i7.       ;    return
;    jl.        c4.       ;   else error(entry not removed)
e.

\f


; terminate (help procedure)
; the procedure has the following function :
;  if after write char then closeup text
;  if after write binary then outblock, in case of data in share
;  if after read or write then terminate zone
;  if output to bs area then
;    begin
;    set shortclock in catalog entry
;    cut area to used size
;    set filelength in tail, in case of binary file
;    end
;
; call: w1 = zone
;        w3 = return
; exit: w1 = zone, other regs undef

b. a10, f10 w.

f0:  0                 ; saved return

i6:                    ; terminate transfer:
     rs. w3     f0.    ;   save (return);

     bl  w0  x1+h2+6   ;   w0 := zone.state;
     rl. w2     b4.    ;   w2 := first of process;

     se  w0     s3     ;   if zonestate = after write char then
     jl.        a1.    ;     begin
     jl  w3  x2+h95    ;     close up text (zone);
     rl. w2     b4.    ;     w2 := first of process;
     jl.        a5.    ;     goto terminate;
a1:                    ;     end;
     se  w0     s6     ;   if zonestate = after write binary then
     jl.        a2.    ;     begin
     rl  w0  x1+h3+0   ;     w0 := record base;
     rl  w3  x1+h0+4   ;     w3 := used share;
     sl  w0 (x3+2)     ;     if recbase >= first shared(used share) then
     jl  w3  x2+h23    ;       outblock;
     jl.        a5.    ;     goto terminate;
a2:                    ;     end;
     se  w0     s1     ;   if zonestate = after read char or
     sn  w0     s5     ;      zonestate = after read binary then
a5:                    ; terminate:
     jl  w3  x2+h79    ;     terminate zone (zone);

     bl  w2  x1+h1+1   ;   w2 := kind (zone);
     bl  w0  x1+h2+6   ;   w0 := zonestate;

     se  w0     s3     ;   if (zonestate = after write char or
     sn  w0     s6     ;       zonestate = after write binary)
     se  w2     4      ;   and zonekind = 'bs' then
     jl.        a10.   ;     begin

     rl  w3  x1+h0+6   ;     w3 := filename addr;
     al  w3  x3+14     ;

     al. w1     b5.    ;     w1 := tail addr;
     jd         1<11+42;     lookup entry (name, tail);
     se  w0     0      ;     if not ok then
     jl.        c2.    ;       error (file does not exist);

     rl. w0     b5.+0  ;     w0 := size.tail;
     sh  w0    -1      ;     if size < 0 then
     jl.        a9.    ;       return;

     jd         1<11+36;     tail.shortclock :=
     ld  w1     5      ;       getclock shift (-19) extract 24;
     rs. w0     b5.+10 ;

     rl. w1     b1.    ;     w1 := zone addr;

     rl  w0  x1+h1+16  ;     size.tail := segment count (zone);
     rs. w0     b5.+0  ;

     bl  w0  x1+h2+7   ;     if filetype = binary then
     rl  w2  x1+h4+2   ;
     sn  w0     0      ;
     rs. w2     b5.+18 ;       filelength.tail := filelength (zone);

     al. w1     b5.    ;
     jd         1<11+44;     change entry (name, tail);
a9:                    ;     end;

                       ; return:
     rl. w1     b1.    ;   w1 := zone;
a10: jl.       (f0.)   ;   return;
e.
 
\f


; replace of spaces with binary zero in file name
; call: w2 = filename addr
;       w3 = return
; exit: all regs undef

b. a10, f10 w.

f0:  0                 ; start of filename
f1:  0                 ; saved return

i8:                    ; replaces spaces:
     ds. w3     f1.    ;   save (filename addr, return);

     al  w2  x2+8      ;   wordaddr := top of filename;

a0:                    ; next word:
     al  w2  x2-2      ;   decrease (wordaddr);
     rl  w0  x2        ;   word := filename (wordaddr);

     al  w3     0      ;   shift := 0;
a1:                    ; next char:
     al  w3  x3-8      ;   shift := shift - 8;
     ld  w1  x3        ;   w0 := first char(s);
     ls  w1    -16     ;   w1 := char (shift);
     se  w1     32     ;   if char <> space then
     jl.       (f1.)   ;     return;

     ac  w1  x3        ;
     ls  w0  x1        ;   w0 := first char(s) leftjustified;
     rs  w0  x2        ;   filename (wordaddr) := word;

     se  w3    -24     ;   if not all chars in word tested then
     jl.        a1.    ;     goto next char;

     se. w2    (f0.)   ;   if not all filename converted then
     jl.        a0.    ;     goto next word;

     jl.       (f1.)   ;   return;
e.
\f


; replace ( <programname> )
;
; call: w1 = addr of name of new program

b. a10 w.

a0:                  ; start of program-stack
     2<12 + 2        ;
     2<12 + 10       ;
     <:pascrun:>, 0  ;
     4<12 + 10       ;
     0
a1:  0-0-0           ; (old fp-mode bits)
     0               ;
     0               ;
     4<12 + 10       ;
a2:  0, r.4          ; name of new program
a3:                  ; top of program-stack

i9:                    ; replace:
     dl  w3  x1+2      ;   move name to program-stack;
     ds. w3     a2.+2  ;
     dl  w3  x1+6      ;
     ds. w3     a2.+6  ;

     al. w2     a2.    ;   insert zeroes for spaces;
     jl. w3     i8.    ;

     rl  w3     66     ;
     rl  w3  x3+22     ;   w3 := start of process;

     rl  w2  x3+h51    ;
     rs. w2     a1.    ;   move fp-modebits to program stack;
     sz  w2     2.1    ;   remove list-bit;
     al  w2  x2-2.1    ;
     rs  w2  x3+h51    ;

     rl  w2  x3+h8     ;   w2 := current command;
a5:  ba  w2  x2+1      ; next:
     bl  w0  x2+0      ;   if seperator (increase (pointer)) <> 'end' then
     sl  w0     4      ;
     jl.        a5.    ;     goto next;

     al. w1     a3.    ;   w1 := top of program-stack;
a7:  al  w2  x2-2      ; rep:
     al  w1  x1-2      ;   decrease pointers;
     rl  w0  x1        ;
     rs  w0  x2        ;   move one word;
     se. w1     a0.    ;   if w1 <> start of program-stack then
     jl.        a7.    ;     goto rep;

     rs  w2  x3+h8     ;   current command := command pointer;

m.****** replace: husk at afstakke current output
     al  w2     0      ;   w2 := normal return to fp;
     jl      x3+h7     ;   goto fp-end-program;
e.                     ;


; monitor procedure
;
; the procedure sets up a monitor call
;
; the functions implemented are:
;   40: create entry
;   42: lookup entry
;   44: change entry
;   48: remove entry
;
; call:  w0: name address (may be padded with blank)
;        w1: tail address
;        w2: proc table entry
;        w3: return-4
;               +0 : segm<12 + rel
;               +2 : function number

b. a10 w.

a0:  0, r.4            ; name (without trailing spaces)

i10:                   ;
     rl. w2     b3.    ;
     al  w0  x2+2      ;
     rs. w0     b3.    ;   return := after parameters;

     al  w1    -1      ;   w1 := illegal result;

     rl  w2  x2+0      ;   w2 := function number;
     sl  w2     40     ;   if function out of range then
     sl  w2     48+1   ;
     jl.        i7.    ;     return;

     al  w2  x2-2048   ;
     hs. w2     a1.    ;   save function in monitor call;

     rl. w3     b0.    ;   w3 := name addr;
     al. w2     a0.    ;   w1 := local name;
     dl  w1  x3+2      ;
     ds  w1  x2+2      ;   move name;
     dl  w1  x3+6      ;
     ds  w1  x2+6      ;
     jl. w3     i8.    ;   remove spaces;

     rl. w1     b1.    ;   w1 := tail address;
     al. w3     a0.    ;   w3 := name address;

     jd         1<11+0+0+0;
a1 = k-1               ;

     rl  w1     0      ;   w1 := result;

     jl.        i7.    ;   return;

e.                     ;
 
\f


; error return
c6:  am         13-19  ;13:    illegal zonestate:
c1:  am         1     ;19 -   file cannot be looked up
c2:  am         1     ;18 -   file   does not exist
c3:  am         1     ;17 -   file cannot be removed
c4:  am         1     ;16 -   file cannot be changed
c5:  al  w1     15    ;15 -     -    -    -  connected for i/o
     rl. w2     b0.+4 ;
     rl  w3  x2+4     ;   w3 := add of rt error
;ks-819
     rs. w3     b0.+4 ;
     rl  w2  x2+8     ;   w2 := stacktop
     rl. w3     b0.+6 ;   w3 := add where error occurred
     al  w0    -1     ;
;ks-820
     jl.       (b0.+4);   jump to rt error

; normal return

i7:  rl. w2     b0.+4 ;
     rl  w2  x2+8     ;   w2 := stacktop
     jl.       (b0.+6);   return
e.
\f


; segment 7-8
; pascal i/o
; write routines for text files
b. a45,b15,c22, i5, d15 w.
0,r.(:3586-k:)>1
 
     jl.        i0.     ;+0   write real
     jl.        i0.     ;+2   write integer, boolean, char, string
 
; this is the common part for all write routines (text).
; registers at call :
;  w0 - argument or add of argument
;  w1 - zone desc add 
;  w2 - procedure table add
;  w3 - return - 4
;        +0  5<12 + relative
;        +2  m<12 + n/relative1
;
; if the relative add is odd, the call is writeln = write, outchar(nl)
; instead of write


d0:  0,r.4              ;   saved registers
d1:  0                  ;   process start
d2:  0                  ;   write (0)/writeln(1)

i0:  ds. w3     d0.+6   ;
     rl  w2     66      ;
     rl  w2  x2+22      ;   w2 := process start
     rs. w2     d1.     ;   process start
     ds. w1     d0.+2   ;
     bl  w2  x1+h2+6   ;   w2 := zonestate;
     se  w2     s3     ;   if zonestate <> after write text then
     jl.        d12.   ;     error (illegal zonestate);
     bl  w1  x3+1       ;
     al  w2     1       ;
     la  w2     2       ;   if writeln then
     rs. w2     d2.     ;   d2 := 1 else d2 := 0
     bl  w1  x3+1       ;   w1 := rel entry add
     jl.     x1+2       ;
     jl.        i1.     ;   write real
     jl.        i2.     ;   write integer etc.
 
; at exit registers contain :
;  w0 - argument or add of argument
;  w3 - return-4
 
\f


; write real.
;
; call parameters :
;  w0    - add of argument (first word)
;  w3    - return-4, pointing to
;           +0 5<12 + 0 or 1
;           +2 m<12 + n
;
; if m,n is not specified , the default value 14<12 + 0 
; must be present.
;
;
; the format is as follows :
;   bit      meaning
;   0
;   1-5      no of significant digits (b)
;   6-9      -  -  digits before point (h)
;   10-13    -  -    -    after    -   (d)
;   14-15    not used                  (pn)
;   16-17    sign of number (01)        (fn)
;   18-19    no of digits in exponent   (s)
;   20-21    first letter of exponent part (pe)
;   22-23    sign of exponent (fe)
;
; the format is packed as follows :
;   m:=m-2 (one space for . , and one for sign)
;  if n<>0 then
;   m<18 + (m-n)<14 + n<10 + 1<6
;  if n = 0 then
;   (m-4)<18 + 1<14 + (m-5)<10 + 1<6 + 3<4 + 3<2 + 2
;
b. c10 w.
 
     1<23
c0:  0                   ;   layout words
c2:  1<6 + 3<4 +2<2 +2   ;   part of layout
c3:  1<6                 ;     -   -    -
c7:  2                   ;   constant
c8:  4                   ;

i1:  bl  w0  x3+2        ;   w0 := m
     sh  w0    -1        ;   if m < 0 then
     jl.        d13.     ;    error(negative field width)
     sh  w0     14       ;   if m > 15 then
     jl.        c1.      ;   begin
     rl  w2     0        ;     w2 := m
     rl. w1     d0.+2    ;     w1 := zone desc
     al  w2  x2-14       ;
     jl. w3     d10.     ;     outspace
     al  w0     14       ;
     rl. w3     d0.+6    ;
c1:                      ;   end
     ws. w0     c7.      ;   m:=m-2
     bl  w1  x3+3        ;   w1 := n
     al  w2     1        ;
     sn  w1     0        ;   if n<> 0 then
     jl.        c4.      ;
     rl  w2     0        ;
     ws  w2     2        ;    w2 := m-n
     jl.        c5.      ;   else w2 := 2
c4:  rl  w1     0        ;   if n<>0 then w1 := n
     al  w1  x1-5        ;    else w1 := n-5
     ws. w0     c8.      ;   m := m - 4
c5:
     ls  w0     18       ;
     ls  w2     14       ;
     ls  w1     10       ;
     lo  w0      2       ;
     lo  w0      4       ;   w0 := w0<18 + w2<14 + w1<10
     rl. w3     d0.+6    ;
     bl  w3  x3+3        ;
     sn  w3     0        ;   if n=0 then
     lo. w0     c2.      ;    add exponent part
     se  w3     0        ;     else no exponent
     lo. w0     c3.      ;
     rs. w0     c0.      ;
     rl. w1     d0.      ;
     dl  w1  x1+2        ;   load argument
     al. w2     c0.      ;   load abs add of format
     jl. w3     a44.     ;   goto write real
     jl.        d11.     ;   return
e.

; output character
b. e0    w.
e0:  0
a14: rl. w1     d0.+2    ;   w1 := zone desc add
     rs. w3     e0.      ;   store return
     am.       (d1.)     ;
     jl  w3     h26      ;   outchar
     jl.       (e0.)     ;   return
e.

h.
     2048,   0
a26:    0,   0 ; -1 floating
     1024,   0
a34:    0,   1 ; 1.0
 1280,   0
    0,   4     ;  10**1
 1600,   0
    0,   7     ;  10**2
 1250,   0 
    0,  14     ;  10**4
 1525,3600
    0,   27    ;  10**8
 1136,3556
 3576,  54     ;  10**16
 1262, 726      
 3393, 107     ;  10**32
 1555,3087
 2640, 213     ;  10*64
 1181,3363
 3660, 426     ;  10**128
 1363,3957   
 4061, 851     ;  10**256
 1816,3280
 1397,1701     ;  10**512
 
a0:h.
32; sp
48; 0
43; +
45; -
46; .
39; '
w.
 
0          ;  w2 for write real - w3 for write signed word
a1:
0; return for write real (w3)
0; +2  point buf
0; +4  unpack buf
0; +6  start buf
0,0; +8  layout
0; +12 first digit buffer
a8: 10;constant
5; +2 constant
a2:0, r. 15;buffer
  
a5: rs. w3 a1. -2  ; write signed integer word
ds. w1 a2. +2
al w3 0
hs. w3 a23.
a24: dl w2 x2   ;  w1,w2:= layout
ls w1 -1
ds. w2 a1. +10
dl. w1 a2. +2
se w3 0
jl. a22.
sz w2 3<6
bz. w3 a0.
lo w1 0
sn w1 0
jl. a12.
sz w2 2<6
bz. w3 a0. +2
a22: am 301
a12: al w1 -300
so w2 1<8
al w1 300
so w2 2<8
al w1 1
rs. w1 a1. +12
 sl w0 0
jl. a20.
ld w1 48
ss. w1 a2. +2
ds. w1 a2. +2
bz. w3 a0. +3
a20: hs. w3 a19.
ld w3 -18
ac w2 x2
hs. w2 a18.
al w2 0
ld w3 4
ls w3 -20
al. w3 x3 a2. -1
rs. w3 a1. +2
wa w2 6
rs. w2 a1. +6
wa. w3 a1. +12
rs. w3 a1. +12
a13: rl. w1 a1. +8
ls w1 1
rs. w1 a1. +8
al. w3 a13.
bz. w2 a0.
sh w1 -1
jl.  a14.      ;   output character
al. w1 a2. +29
dl. w0 a2. +2
a7: sh. w1 (a1. +12)
bz. w2 a0. +1
hs w2 x1
al w1 x1 -1
sl. w1 a2.
jl. a7.
a23=k+1
 al w1 x1
jl. a9.
a10: al w2 0
wd. w3 a8. +2
rx w2 6
wd. w0 a8.
al w1 x1 1
ba. w3 a0. +1
hs w3 x1
rs w2 6
ls w0 1
ld w0 -1
a9: sn w0 0
se w3 0
jl. a10.
sh. w1 a2. -1
rl. w1 a1. +2
rs. w1 a1. +4
a18=k+1
 al w1 x1
bz. w2 a0. +1
a16: sh. w1 a2. -1
jl. a21.
sh. w1 (a1. +2)
bz. w2 a0.
hs w2 x1
al w1 x1 -1
jl. a16.
a21: dl. w3 a1. +8
ws. w2 a1. +4
ls w3 x2
rl. w2 a1. +4
sl. w2 (a1. +6)
ds. w3 a1. +8
rl.  w2 a1. +10
so w2 3<8
am 3<8
sz w2 0
jl. w3 a4.
rl.w0 a1. +6
a11:se. w0 (a1. +12)
 sn. w0 (a1. +4)
jl. w3 a4.
rl. w2 a1. +8
a15: ld w2 1
rs. w2 a1. +8
bz. w2 a0.
sz w1 1
jl. w3  a14.      ;   output character
sh. w0 a2. -1
jl. (a1. -2)
bz w3 (0)
bz. w2 a0.
bz. w2 a0. +4
sn. w0 (a1. +2)
jl. w3  a14.      ;   output character
bz w2 (0)
jl. w3  a14.      ;   output character
bs. w0 a15. +1
jl. a11.
a4: al w2
a19 = a4 +1
sn w2 0
jl x3
al w1 0
hs. w1 a4. +1
jl.  a14.      ;   output character
h.
     -1000, -100
a33:   -10,   -1 ; exp limits
        -1,   -1
a30:    -1,   -1 ; rounding constant, no-sign exp limit
 
w.
a44: ds. w3 a1.   ;   write real 
sl w0 0
jl. a25. 
fm. w1 a26. 
am. (a0. +2)
a25: al w3 0
hs. w3 a27.
so. w0 (a34. -2)
jl. a35. 
ds. w1 a2. +2 
bz w2 x2 
a28: sl w2 13<6 -1
la. w2 a28. 
hs. w2 (a1. -2)
ld w3 -6
ls w3 -20 
ws w3 4 
rl. w1 (a1. -2) 
ls w1 10 
ls w1 -20
wa w3 2
sl w3 0 
am x3
al w3 1 
rs. w3 a2. +16 
dl. w0 a2. +2 
a39: hs w0 2
sh w1 -1 
jl. a38. 
al w1 x1 128 
fd. w0 a34. +32
jl. a39. 
a38: hs. w1 a29. 
ds. w0 a2. +10
rl. w3 (a1. -2)
dl. w1 a30.
sz w3 3
dl. w1 a33. 
sz w3 2<4
ld w1 -24
sz w3 1<4
ld w1 -12
hs. w1 a31.
al. w3 a34.
dl w1 x3
a36: al w3 x3 4 
sz w2 1
fm w1 x3
ls w2 -1
sl w2 1
jl. a36. 
jl. w3 a37. 
ds. w1 a2. +6
al w3 9
a40: dl. w1 a2. +10
ls w3 2
fm. w1 x3 a34. +4
ds. w1 a2. +14
ls w3 -2
sl w3 10
al. w3 a6.
a37: bl w2 3
sh w2 40
ld w1 x2 -46
ss. w1 a30.
ld w1 -1
sl w3 10
jl x3
ss. w1 a2. +6
al w2 -1
ls w2 x3
a29=k+1
al w2 x2
sh w0 -1
a31=k+1
sh w2 
jl. a32. 
dl. w1 a2. +14
ds. w1 a2. +10
hs. w2 a29. 
a32: al w3 x3 -1
jl. a40.
a6: ds. w1 a2. +2
lo w0 2
sn w0 0
jl. a35.
rl. w3 a2. +16 
ls w3 10
ba. w3 a29.
al w2 0 
wd. w3 a2. +16
bl. w1 a29.
ws w1 4
bl. w3 a31. 
sl w1 x3 +1 
jl. a42. 
al w1 x3 1
ac w2 x3 1
ba. w2 a29. 
jl. a42.
a35: ld w2 48
ds. w2 a2. +2
a42: hs. w1 a29. 
hs. w2 a23. 
dl. w3 a1.
rl w0 x2
sn w1 0
sz w0 3<4+1
al. w3 a43.
rs. w3 a1. -2
a27=k+1
al w3
jl. a24. 
a43: rl. w0 a1. +10
bl. w3 a29. 
bz. w2 a0. 
sn w3 0
so w0 3<2
bz. w2 a0. +5
jl. w3  a14.      ;   output character
al. w2 a1. +10
rl w0 x2
ls w0 18
al w3 15<2
ld w0 2
ls w3 4
ld w0 10
rs w3 x2
bl. w1 a29.
rl. w3 a1.
 sl  w1     0   ;   write signed word
     am         1   ;
     al  w0    -1   ;
     jl.        a5. ;
 
\f


; this is the write routines for
;  integer, boolean, string, character, the proc put and writeln.
; the call is as follows :
;  +0 segm<12 + 2 or 3
;  +2 m   <12 + relative
;
;  where relative is :
;   +2 integer, +4 boolean, +6 char,
;   +8 string , +10 put   , +12 writeln (without parameters)
;
; if m is not used the default value must be used

; common code for all procedures
i2:  bl  w2  x3+2      ;   w2 := m
     sh  w2    -1      ;   if m < 0 then
     jl.        d13.   ;    error(negative field width)
     bl  w3  x3+3      ;   w3 := relative
     rl. w1     d0.+2  ;   w1 := zone desc
     jl.     x3        ;
     jl.        d5.    ;   write integer
     jl.        d6.    ;     -   boolean
     jl.        d7.    ;     -   character
     jl.        d8.    ;     -   string
     jl.        d9.    ;   put(filebuffer)
     jl.        d11.   ;   writeln (without parameters)

; at exit to each procedure
;  w0 - argument
;  w1 - zone desc
;  w2 - m
 
; write integer
b. a2 w.
     1<23 + 32<12 + 0-0-0 ; layout for negative numbers
a2:  0<23 + 32<12 + 0-0-0 ; layout for positive numbers
d5:  sh  w2     12     ;   if m > 12 then
     jl.        a0.    ;   begin
     al  w2  x2-12     ;     m:=m-12
     jl. w3     d10.   ;     outspace
     al  w2     12     ;     m:=12
     rl. w0     d0.    ;     w0 := argument
a0:                    ;   end
     sh  w0    -1      ;   if number < 0 then
     am        -2      ;     layout := <<-d>
     wa. w2     a2.    ;   else
     rs. w2     a1.    ;     layout := <<d>;
     am.       (d1.)   ;
     jl  w3     h32    ;   outinteger
a1:  1<23 + 32<12 + 0  ;
     jl.        d11.   ;   return
e.
 
; write boolean
b. a2 w.
a1: <:false<0>:>
a2: <:true<0>:>
d6:  al  w2  x2-4      ;   if true then m := m-4
     sn  w0     0      ;           else m := m-5
     al  w2  x2-1      ;
     jl. w3     d10.   ;   outspace(m-4/m-5)
     rl. w2     d0.    ;   w2 := false(0) / true(1)
     al. w0     a2.    ;
     sn  w2     0      ;
     al. w0     a1.    ;
     am.       (d1.)   ;
     jl  w3     h31    ;   outtext(true/false)
     jl.        d11.   ;   return
e.
 
; write character
b. w.
d7:  al  w2  x2-1      ;
     jl. w3     d10.   ;   outspace
     rl. w2     d0.    ;
     am.       (d1.)   ;
     jl  w3     h26    ;   outchar
     jl.        d11.   ;   return
e.
 
; write string
; call :
;  w0 - start add of string
;  w1 - zone desc
;  w2 - m (total length)
;  return + 4 - length of string in characters
;
; algorithm :
;  if m > length then outspace(m-length)
;  i := length mod 3
;  j := length div 3
;  x := word(w0+2*j)
;  if i=0 then x := <0><0><0>
;  if i=1 then x := x la 11111111 <0> <0>
;  if i=2 then x := x la 1111111111111111 <0>
;  word(w0+2*j) := x
;  outtext
;  restore word(w0+2*j)
;
b.    a5       w.
a0:  0,0               ;   stored registers
a2:  3                 ;   const
a3:  0                 ;   temp word
a4:  2.111111110000000000000000 ; mask 1
a5:  2.111111111111111100000000 ; mask 2

d8:  ds. w1     a0.+2  ;   save registers
     rl. w3     d0.+6  ;   w3 := return add
     sh  w2 (x3+4)     ;   if m > length then
     jl.        a1.    ;   begin
     ws  w2  x3+4      ;     m := m-length
     jl. w3     d10.   ;     outspace(m)
     rl. w2     d0.+6  ;
     rl  w2  x2+4      ;     w2 := length
a1:                    ;   end
     al  w1     0      ;
     wd. w2     a2.    ;   w1 := length mod 3
     ls  w2     1      ;   w2 := length in halfwords
     wa. w2     a0.    ;   w2 := add of word where <0> is to be inserted
     rl  w3  x2        ;
     rs. w3     a3.    ;   save word
     sn  w1     0      ;   if rest = 0 then w0 := 0
     al  w0     0      ;
     sn  w1     1      ;   if rest=1 then w0:= mask1
     rl. w0     a4.    ;
     sn  w1     2      ;   if rest = 2 then w0 := mask2
     rl. w0     a5.    ;
     la  w0  x2        ;   insert <0> in the right place
     rs  w0  x2        ;
     dl. w1     a0.+2  ;   w0 := start add of string
     am.       (d1.)   ;   w1 := zone desc add
     jl  w3     h31    ;   outtext
     rl. w0     a3.    ;
     rs  w0  x2        ;
     rl. w3     d0.+6  ;
     al  w3  x3+2      ;
     rs. w3     d0.+6  ;
     jl.        d11.   ;  return
e.
 
; put(filebuffer)
b. w.
d9:  rl  w2  x1+h4+4   ;   w2 := filebuffer
     am.        (d1.)  ;
     jl  w3     h26    ;   outchar
     jl.        d11.   ;   return
e.
 
; outspace (help procedure)
; call :
;  w1 - zone desc
;  w2 - m
;  w3 - return
; function of procedure :
;  while m > 0 do
;  begin outchar(sp); m:=m-1
;  end
 
b. a2 w.
a1:  0,r.2
d10: ds. w3     a1.+2   ;
a2:  al  w2     32      ;   char := sp
     rl. w0     a1.     ;   w0 := m
     sh  w0     0       ;   while m > 0 do
     jl.       (a1.+2)  ;   begin
     am.       (d1.)    ;
     jl  w3     h26     ;     outchar(sp)
     rl. w2     a1.     ;
     al  w2  x2-1       ;     m:=m-1
     rs. w2     a1.     ;
     jl.        a2.     ;   end
e.
 
; return
b. a0 w.
d11: rl. w0     d2.     ;
     sn  w0     0       ;   if writeln then
     jl.        a0.     ;   begin
     al  w2     10      ;
     rl. w1     d0.+2   ;     zone desc
     am.       (d1.)    ;
     jl  w3     h33     ;     outend(nl)
a0:                     ;   end
     dl. w3     d0.+6   ;
     rl  w2  x2+8       ;   reestablish stacktop
     jl      x3+4       ;   return
e.
 
; error return
d13: am         7-13    ;   alarm  7 - negative field width
d12: al  w1     13      ;   alarm 13 - illegal zonestate
     rl. w2     d0.+4   ;
     rl  w3  x2+4       ;   w3 := add of rt error
     rs. w3     d0.+4   ;
     rl  w2  x2+8       ;   w2 := stacktop
     rl. w3     d0.+6   ;   w3 := add where error occurred
     al  w0    -1       ;
     jl.       (d0.+4)  ;   jump to error return
e.
\f


; segment 9-10
; read and get (textfiles)
; the read procedure always takes the first character from the filebuffer.
;
; call of read and get :
;  w0 - add of var to return read 'item' in (if real then first word)
;  w1 - zone desc 
;  w3 - return -2
;
; call code :
;   jl     (x2-2035)
;   6<12 + relative
;  relative :
;   +0 read iso          +1 readline iso
;   +2 get
;   +4 read char         +5 readline char
;   +6 read integer      +7 readline integer
;   +8 read real         +9 readline real
;                        +11 readline (without parameters)
;
; return : the item read in word(w0) (if real then word(w0) and word(w0+2))
;
; used globals
;  z+h4+0 - eof (true=1/false=0)
;  z+h4+1 - eoln
;  z+h4+4 - filebuf

b. b3, g10, i15 w.
0,r.(:512*9+2-k:)>1
     jl.        i10.   ;
     jl.        i10.   ;
     jl.        i10.   ;
     jl.        i10.   ;
     jl.        i10.   ;
     jl.        i10.   ;
b0:  0,r.4             ;   saved registers
b1:  0                 ;   process start
b2:  0                 ;   readline (1)/ read (0)

i10: ds. w3     b0.+6  ;   save w2,w3
     rl  w2     66     ;
     rl  w2  x2+22     ;
     rs. w2     b1.    ;   save process start
     ds. w1     b0.+2  ;   save w0,w1
     bl  w2  x1+h2+6   ;   w2 := zonestate;
     se  w2     s1     ;   if zonestate <> after read char then
     jl.        g5.    ;     error (illegal zonestate);
     bz  w2  x1+h4+0   ;
     sn  w2     1      ;   if eof then
     jl.        g1.    ;    runtime error(try to read past eof)
     bl  w3  x3+1      ;
     al  w2     1      ;
     la  w2     6      ;   if read line then
     rs. w2     b2.    ;   b2 :=1 else b2:= 0
     rl  w2  x1+h4+4   ;   w2 := filebuf;
     jl.     x3+2      ;
     jl.        i1.    ;   read-iso
     jl.        i2.    ;   get
     jl.        i3.    ;   read-char
     jl.        i4.    ;   read-integer
     jl.        i5.    ;   read-real
     jl.        i6.    ;   readln (without parameters)

; registers at exit to the procedures
;  w0 - add of var to read to
;  w1 - zone desc add
;  w2 = filebuf

; read character

i3:                    ;
     se  w2     10     ;
     sn  w2     12     ;   if char = newline or char = formfeed then
     al  w2     32     ;     char := space;
     sl  w2     32     ;   if char outside legal range then
     sl  w2     128    ;
     jl.        g4.    ;     goto index-alarm;

; read iso

i1:                    ;
     rs. w2    (b0.)   ;   var := filebuffer;

     jl.        i2.    ;   goto get next char;
\f


; read integer/ read real (text)
;
; variables
;  f - global for both integer and real
;  c - actions
;  v - states
 
b.  f5, c40, r40    w.
f1:  0                  ;   current state

; character set table
f0: h.
 16,10,10,10,10,10,10,10,10,10,10,10,10,16,10  ;  0-14
 10,10,10,10,10,10,10,10,10,10,14,10,10,10,10  ;  15-29
 10,10,12,10,10,4 ,10,10,10,8,10,10,10, 2,10   ;  30-44
  0, 4,10,6,6,6,6,6,6,6,6,6,6,10,10            ;  45-59
 10,10,10,10,10,8,8,8,8,8,8,10,10,10,10        ;  60-74
 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10  ;  75-89
 10,10,10,10,10,10,10,8,8,8,8,8,8,10,10        ;  90-104
 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10  ;  105-119
 10,10,10,10,10,10,10,16                       ;  120-127
 w.
 
; note that # and . are classified equal, this means
; that # and . may replace each other.
 
; read character and choose action
c0:                    ;
     am.        (b1.)  ;
     jl  w3    +h25    ;   read char;
     rs  w2  x1+h4+4   ;   filebuf := char;
     sl  w2     128    ;   if illegal char then
     al  w2     0      ;     char := null;
f3:  bl. w3  x2+f0.     ;   w3 := char type
     am.       (f1.)    ;
f4:  rl. w3  x3         ;
     hs. w3     f1.+1   ;   store new state
     bl  w3     6       ;
f2:  jl.     x3         ;   goto action
 
; error return
g5:  am         13-23  ; 13 - illegal zonestate:
g0:  am         23-22   ; 23 - integer overflow
g1:  am         22-21   ; 22 - try to read past eof
g2:  am         21-20   ; 21 - digit expected
g3:  am         20-2    ; 20 - b,o or h expected
g4:  al  w1     2      ; 2  - index alarm
     rl. w2     b0.+4   ;
     rl  w3  x2+4       ;
     rs. w3     b0.+4   ;   
     rl  w2  x2+8       ;   w2 := stacktop
     rl. w3     b0.+6   ;   w3 := error add
     al  w0    -1       ;
     jl.       (b0.+4)  ;   jump to rt error
\f


; read integer
; the integer obeys the following syntax :
;  (+/-) (spaces) (#b/#o/#h) ((digit))
; the reading is performed as a state/action table
; variables
;  r - states
;  d - global var
;  a - local var

b. d10 w.
d2:  0                ;   sign
d3:  0                ;   base
 
 
; actions :
; c0 - chose action on basis of char and state
; c1 - sign
; c2 - chose base <> 10
; c3 - int := int * base + ch - cst
; c4 - terminate
; g2,g3 - error

; init code
i4:  al  w0     1     ;
     rs. w0     d2.   ;   sign := plus
     al  w0     10    ;
     rs. w0     d3.   ;   base := 10
     hs. w0     d4.    ;
     al  w0     r0    ;
     rs. w0     f1.   ;   state := r0
     al  w0     0      ;   integer := 0;
     jl.        f3.   ;   goto start

; sign
c1:  al  w3     -1    ;
     rs. w3     d2.   ;   sign := -1
     jl.        c0.   ; goto next action
 
; recalculate base and digit
b.  a2    w.
c2:  sl  w2     97     ;   if small letter then convert to capital;
     al  w2  x2-32     ;
     se  w2     98-32 ;   if b then
     jl.        a0.   ;   begin (* binary *)
     al  w2     2     ;     base := 2
     jl.        a2.   ;   end
a0:  se  w2     111-32;   if o then
     jl.        a1.   ;   begin (* octal *)
     al  w2     8     ;     base:=8
     jl.        a2.   ;   end
a1:  se  w2     104-32;   if h then
     jl.        g3.   ;   begin (* hexadecimal *)
     al  w2     16     ;     base := 16
a2:  rs. w2     d3.   ;   end else error(b,o or h expected)
     hs. w2     d4.    ;
     jl.        c0.   ;  goto next action
e.

; calculate next digit of integer
; algorithm :
; if ch > digit (2,7,9,f) then error
; cst := 48
; if ch > 'a' then cst := 87
; int := int*base + ch -cst
; if int > maxint then overflow

c5:                    ; hexadecimal digit (or exponent mark)
     sh  w2     64     ;   if not letter then
     jl.        c4.    ;     goto end of integer;

     sh  w2     96     ;   if capital letter then
     am        -55+87  ;     w2 := capital letter - 55
     am        -87+48  ;   else w2 := small letter - 87
                       ; otherwise
c3:                    ; digit:
     al  w2  x2-48     ;   w2 := digit - 48;
     sl  w2     0-0-0  ;   if w2 >= base then
d4 = k-1 ; base
     jl.        g2.    ;     error (read integer);
     wm. w0     d3.    ;   integer * base
     wa  w0     4      ;    + ch
     se  w3     0      ;   if w3 <> 0 then
     jl.        g0.    ;    error(overflow)
     jl.        c0.    ;  goto next action
 
; end of integer
c4:                    ;
     wm. w0     d2.    ;
     rs. w0    (b0.)   ;   var := read integer
     jl.        i6.    ;  return
 
; state action table
h.
;    0       2         4         6         8         10         12       14       16
;    -       +         #         0..9     a..f      others      sp       em     blinds
r0=k-f4
 c1-f2,r1, c0-f2,r1, c0-f2,r2, c3-f2,r3, c0-f2,r0, c0-f2,r0, c0-f2,r0, g1-f2,r4, c0-f2,r0 ;
r1=k-f4
 g2-f2,r0, g2-f2,r0, c0-f2,r2, c3-f2,r3, g2-f2,r0, g2-f2,r0, c0-f2,r1, g1-f2,r4, c0-f2,r1 ;
r2=k-f4
 g3-f2,r0, g3-f2,r0, g3-f2,r0, g3-f2,r0, c2-f2,r3, c2-f2,r3, g3-f2,r0, g1-f2,r4, c0-f2,r2 ; b,o or h expected
r3=k-f4
 c4-f2,r4, c4-f2,r4, c4-f2,r4, c3-f2,r3, c5-f2,r3, c4-f2,r4, c4-f2,r4, c4-f2,r4, c0-f2,r3 ; int:=int*base+ch-cst
r4=k-f4
w.
e.
\f


; read real
; a real obeys the following scheme :
;  (+/-) unsigned int (.) ((digit)) (e) (+/-) unsigned int
; 
; this is implemented by a state action table
; where
;  r's are states
;  c's are actions
;
; the actions are
;  c0 - next char and action
;  c21 - sign of number part
;  c22 - number := number*10+ch-48
;  c23 - fraction := fraction  * 10 + ch - 48
;        s:=s/10
;  c24 - scale factor:= scale factor*10 + ch - 48
;  c25 - sign of scale factor
;  c26 - finish action

b.  e10    w.
e0:  0                 ;   sign of number
e1:  0,0               ;   number (floating)
e2:  0,0               ;   fraction part (floating)
e3:  0                 ;   scale factor
e4:  0                 ;   sign of scale
e6:  8388607           ;   max integer
h.
e5:  1280, 0           ;
     0   , 4           ;   floating 10
e7:  1638,1638         ;
     1638, -3          ;   floating 0.1
w.
e8:  0,0               ;   used in fraction part (1.0)

 
; init 
i5:  al  w0     1      ;
     rs. w0     e0.    ;   sign := 'plus'
     rs. w0     e4.    ;   sign of scale := 'plus'
     al  w0     0      ;
     rs. w0     e2.    ;   fraction part := 0
     rs. w0     e1.    ;   number := 0
     rs. w0     e3.    ;   scale factor := 0
     al  w0     1      ;
     ci  w0     0      ;
     ds. w0     e8.+2  ;   fraction const := 1.
     al  w0     r20    ;
     rs. w0     f1.    ;   set state to start
     jl.        f3.    ;  goto start
 
; sign
c21: al  w0     -1     ;
     rs. w0      e0.   ;   sign of number := -
     jl.         c0.   ;   goto next action
 
; number part
; nb ! no check on integer overflow
b. a0     w.
a0: 10                 ;
c22: rl. w0     e1.    ;
     wm. w0     a0.    ;   number * 10
     al  w2  x2-48     ;   ch-48
     wa  w0     4      ;
     rs. w0     e1.    ;   number :=
     jl.        c0.    ;  goto next action
 
 
; fraction
; algorithm :
;  if fraction > maxint then skip
;  fraction := fraction * 10 + ch -48
;  s:= s * 0.1

c23: rl. w0     e2.   ;
     sl. w0    (e6.)  ;   if fraction > maxint then
     jl.        c0.   ;    goto next action
     wm. w0     a0.   ;   fraction * 10
     al  w2  x2-48    ;
     wa  w0     4     ;   + (ch-48)
     rs. w0     e2.   ;   fraction :=
     dl. w0     e8.+2 ;   w0,w1 := 0.1
     fm. w0     e7.+2 ;
     ds. w0     e8.+2 ;   s := s*0.1
     jl.        c0.   ;  goto next action
 
; scale factor
c24: rl. w0     e3.   ;
     wm. w0     a0.   ;   scale factor * 10
     al  w2  x2-48    ;
     wa  w0     4     ;   +ch - 48
     rs. w0     e3.   ;   scale factor :=
     jl.        c0.   ;   goto next action
e.
 
; sign of scale factor
c25: al  w0     -1    ;
     rs. w0      e4.  ;   sign of scale factor := -1
     jl.         c0.  ;  goto next action

; finish action
; algorithm :
;  filebuffer := ch
;  number := (number + fraction part) ** 10 sign*scalefactor
b.   a3          w.
a0:  0,0               ;
c26:                   ;
     rl. w2     e4.    ;   w2 := sign of scale
     dl. w0     e5.+2  ;   w0,w3 := 10.
     sn  w2     -1     ;
     dl. w0     e7.+2  ;   scaling := 10. or .1
     ds. w0     a0.+2  ;
     rl. w0     e2.    ;   w0 := fraction
     ci  w0     0      ;   convert  fraction to real
     fm. w0     e8.+2  ;
     ds. w0     e2.+2  ;   fraction := fraction * s
     rl. w0     e1.    ;   w0 := number
     ci  w0     0      ;   convert number part to real
     fa. w0     e2.+2  ;    number + fraction part
     rl. w2     e3.    ;   w2 := scale factor
a1:  sh  w2     0      ;   while scale > 0 do
     jl.        a2.    ;   begin
     fm. w0     a0.+2  ;     number := number **10*sign
     al  w2  x2-1      ;
     jl.        a1.    ;   end
a2:  ds. w0     e1.+2  ;
     rl. w0     e0.    ;   w0 := sign of number
     ci  w0     0      ;
     fm. w0     e1.+2  ;
     rl. w2     b0.    ;
     ds  w0  x2+2      ;   store result in variable
     jl.        i6.    ;   goto return
e.
 
; return
b.   a3       w.

i6:                    ; terminate after read integer - read real:
     rl  w2  x1+h4+4   ;   w2 := last char;
     jl.        a0.    ;   goto examine;

i2:                    ; get next char:
     am.       (b1.)   ;
     jl  w3    +h25    ;   read char;

a0:                    ; examine:

     rl. w0     b2.    ;   w0 := readline-flag;
     sn  w0     0      ;   if readline then
     jl.        a2.    ;     begin
     al  w0     0      ;     (prepare reset of readline-flag)
     sn  w2     25     ;     if char = em then
     rs. w0     b2.    ;       readline-flag := 0;
     se  w2     10     ;     if char = newline
     sn  w2     12     ;     or char = form feed then
     rs. w0     b2.    ;       readline flag := 0;
     jl.        i2.    ;     goto get next char;
a2:                    ;     end;

; w0 = 0
; w1 = zone
; w2 = last char
     hs  w0  x1+h4+1   ;   eoln := false;
     rs  w2  x1+h4+4   ;   filebuf := last char;

     sl  w2     32     ;   if last char is graphic then
     sl  w2     128    ;
     jl.        a3.    ;
     jl.        a1.    ;     goto return;

a3:                    ; non-graphic:
     al  w0     1      ;
     se  w2     10     ;   if last char = newline
     sn  w2     12     ;   or last char = form feed then
     hs  w0  x1+h4+1   ;     eoln := true;
     sn  w2     25     ;   if last char = em then
     hs  w0  x1+h4+1   ;     eoln := true;

     sn  w2     25     ;   if last char = em then
     hs  w0  x1+h4+0   ;     eof := true;

     bl  w0  x1+h2+7   ;   w0 := filetype;
     se  w0     1      ;   if filetype <> text then
     jl.        a1.    ;     goto return;

     se  w2     10     ;   if last char = newline or
     sn  w2     25     ;      last char = em then
     jl.        a1.    ;     goto return;

     se  w2     12     ;   if last char = ff then goto return;

     jl.        i2.    ;   goto get next char;

a1:  dl. w3     b0.+6  ;
     rl  w2  x2+8      ;   reestablish stack
     jl      x3+2      ;   return
e.
 
; state action table
;  0          2           4            6          8          10           12         14         16
;  -          +           .           0..9        '         others        sp         em       blinds
h.
r20=k-f4
c21-f2,r21, c0-f2 ,r21, c0-f2 ,r20, c22-f2,r22, c0-f2 ,r20, c0-f2 ,r20, c0-f2 ,r20, g1-f2,r20, c0-f2,r20; skip until +,-,0..9
r21=k-f4
g2-f2 ,r20, g2-f2 ,r20, g2-f2 ,r20, c22-f2,r22, g2-f2 ,r20, g2-f2 ,r20, c0-f2 ,r21, g1-f2,r20, c0-f2,r21; sign of number part
r22=k-f4
c26-f2,r27, c26-f2,r27, c0-f2 ,r23, c22-f2,r22, c0-f2 ,r24, c26-f2,r27, c26-f2,r27, c26-f2,r27, c0-f2,r22; number part
r23=k-f4
c26-f2,r27, c26-f2,r27, c26-f2,r27, c23-f2,r23, c0-f2 ,r24, c26-f2,r27, c26-f2,r27, g1-f2,r20, c0-f2,r23; fraction part
r24=k-f4
c25-f2,r25, c0-f2 ,r25, g2-f2 ,r20, c24-f2,r26, g2-f2 ,r20, g2-f2 ,r20, c0-f2 ,r24, g1-f2,r20, c0-f2,r24; sign of scale factor
r25=k-f4
g2-f2 ,r20, g2-f2 ,r20, g2-f2 ,r20, c24-f2,r26, g2-f2 ,r20, g2-f2 ,r20, c0-f2 ,r25, g1-f2,r20, c0-f2,r25; scale factor
r26=k-f4
c26-f2,r27, c26-f2,r27, c26-f2,r27, c24-f2,r26, c26-f2,r27, c26-f2,r27, c26-f2,r27, g1-f2,r20, c0-f2,r26; scale factor and finish
r27=k-f4
w.
 
e.                     ;   end read real
e.                     ; end segment;
 
e.
\f


; segment 11
b.   f5,c1       w.
0,r.(:5634-k:)>1
     jl.        f4.     ;
     jl.        f4.     ;
     jl.        f4.     ;
c0:  0,r.4
f4:  al  w3  x3+2       ;
     ds. w3     c0.+6   ;   save registers
     ds. w1     c0.+2   ;
     bl  w2  x3-1       ;
     jl.     x2+2       ;
     jl.        f1.     ;+0 read/write binary
     jl.        f2.     ;+2 pack
     jl.        f3.     ;+4 unpack
 
; at exit to each procedure the registers are untouched
; except for w2
 
\f


; read / write binary file
; the procedure transfers a number of halfwords (to) from
; a zone buffer to (from) a variable.
; 
; the procedures include both read/write and get/put because get and put
; are special cases of read/write where w0 points to the filebuffer
; situated immediately after the data buffer.
;
; call :
;  w0 - start add of var to read to/write from
;  w1 - zone description
;  w3 - return-4 :
;         +0  7<12 + 0 (read)/ 1 (write)
;         +2 no of halfwords to read/write (length)
;
; the following globals are used :
;  z+h2+6 (halfword): zonestate
;  z+h3+0 (word)    : record base
;  z+h3+2 (word)    : last byte
; (z+h3+4 (word)    : record length)  (not used yet)
;  z+h4+0 (halfword): eof
;  z+h4+2 (word)    : length of file (in halfwords)
; (z+h4+4 (word)    : file buffer addr)
;
; algorithm:
;   length of file := if input then length - recsize
;                              else length + recsize
;   if length = 0 then eof := true;
; rep:
;   for zonesize := lastbyte - recbase while zonesize = 0 do
;     inblock (or outblock);
;   if recsize = 0 then return;
;   size := minimum (zonesize, recsize);
;   move 'size' halfwords between zone and record;
;   recsize := recsize - size;
;   recbase := recbase + size;
;   goto rep;
;
; notice: the algorithm will always ensure room in the buffer for
;         at least one word

b. a20, i10 w.

i1:  0                    ; remaining halfwords to move
i2:  0                    ; top fromptr

f1:                       ; binary read-write:
; w0 = record addr
; w1 = zone
; w2 = rel entry (0==read, 1==write)
; w3 = return-2
     rl  w3  x3        ;   remaining := recsize param;
     rs. w3     i1.    ;

     bl  w0  x1+h2+6   ;   w0 := zonestate;
     se  w2     0      ;   if
     am         s6-s5  ;     (write and zonestate <> after write binary)
     se  w0     s5     ;   or (read and zonestate <> after read binary) then
     jl.        a11.   ;     error (illegal zonestate);

     sn  w0     s5     ;   if after read binary then
     ac  w3  x3        ;     remaining filelength := filelength - recsize
     wa  w3  x1+h4+2   ;   else
     rs  w3  x1+h4+2   ;     remaining filelength := filelength + recsize;

     se  w0     s5     ;   if after write binary then
     jl.        a1.    ;     goto test zone size;

     rl. w0     i1.    ;   w0 := recsize; (* prepare moving of filebuffer *)

     sl  w3     0      ;   if remaining file length < 0 then
     jl.        a0.    ;     begin

     bl  w3  x1+h4+0   ;    w3 := eofflag;
     se  w3     0      ;     if eof then
     jl.        a12.   ;       error (try to read past eof);

     rs. w3     i1.    ;     recsize := 0; (* don't read to filebuffer *)

     al  w3     1      ;     eof := true;
     hs  w3  x1+h4+0   ;
a0:                    ;     end;
; move filebuffer to read-record
; w0 = original recsize
     rl  w3  x1+h4+4   ;   w3 := from-address := addr of file buffer;
     rl. w2     c0.    ;   w2 := to-address := addr of record;
     rs. w3     c0.    ;   (addr of record := filebuffer)
     se  w2  x3        ;   if not 'get' then
     jl.        a4.    ;     goto move;

a1:                    ; test zone size:
     rl  w0  x1+h3+2   ;   zonesize := lastbyte
     ws  w0  x1+h3+0   ;             - recbase;
     se  w0     0      ;   if zonesize = 0 then
     jl.        a2.    ;     begin
     rl  w2     66     ; 
     rl  w2  x2+22     ;
     bl  w0  x1+h2+6   ;     if zonestate = after write binary then
     sn  w0     s6     ;
     am         h23-h22;       outblock (zone)
     jl  w3  x2+h22    ;     else inblock (zone);
     jl.        a1.    ;     goto test zone size;
a2:                    ;     end;

     rl. w3     i1.    ;   w3 := remaining recsize;
     sh  w3     0      ;   if remaining <= 0 then
     jl.        a10.   ;     goto return;

; w0 = zonesize
; w1 = zone addr
; w3 = remaining recsize

     sl  w0  x3        ;   size := minimum (zonesize, recsize);
     al  w0  x3        ;

     ws  w3     0      ;   remaining recsize := remaining recsize
     rs. w3     i1.    ;     - size;

     rl  w2  x1+h3+0   ;   recbase :=
     wa  w2     0      ;     recbase + size;
     rx  w2  x1+h3+0   ;   zonefirst := old recbase + 1;
     al  w2  x2+1      ;

     rl. w3     c0.    ;   recordptr :=
     wa  w3     0      ;     recordptr + size;
     rx. w3     c0.    ;   recfirst := old recordptr;

; w0 = number of halfwords to move
; w1 = zone addr
; w2 = zonefirst
; w3 = recfirst

     bl  w1  x1+h2+6   ;
     sn  w1     s5     ;   if zonestate = after read binary then
     rx  w3     4      ;     exchange (zonefirst, recfirst);

a4:                    ; move:

; w0 = number of halfwords to move
; w2 = to-address
; w3 = from-address

     so  w0     2.10   ;   if odd number of words to move then
     jl.        a5.    ;     begin
     rl  w1  x3        ;
     rs  w1  x2        ;     move one word;
     al  w2  x2+2      ;     increase (to-address);
     al  w3  x3+2      ;     increase (from-address);
     bs. w0    -1;note ;     decrease (number of halfwords);
a5:                    ;     end;

     wa  w0     6      ;
     rs. w0     i2.    ;   top fromptr := from-address + no of halfwords;

     jl.        a7.    ;   goto test;

a6:                    ; move double:
     dl  w1  x3+2      ;
     ds  w1  x2+2      ;   move two words;
     al  w2  x2+4      ;   increase (to-address);
     al  w3  x3+4      ;   increase (from-address);
a7:                    ; test:
     se. w3    (i2.)   ;   if from-address <> top fromptr then
     jl.        a6.    ;     goto move double;

     rl. w1     c0.+2  ;   w1 := zone address;
     jl.        a1.    ;   goto test zonesize;

a10:                   ; return:
     dl. w3     c0.+6  ;   w3 := return-2;
     rl  w2  x2+8      ;   w2 := stackref;
     jl      x3+2      ;   return;

a11: am         13-22  ; illegal zonestate:
a12: al  w1     22     ; try to read past eof:
     dl. w3     c0.+6  ;   w3 := return address;
     rl  w0  x2+4      ;   w0 := address of runtime error;
     rl  w2  x2+8      ;   w2 := stackref;
     jl        (0)     ;   goto runtime error;
e.
 
\f


; pack (limited to string/alfa)
; call parameters :
;  w0 - start add of array to pack from
;  w1 -   -    -   - string/alfa to pack to
;  w3 - return-4
;        +2 number of elements to pack

b. a4     w.
a1:  0                  ;   add of last word to pack
 
f2:  rl  w2  x3         ;
     ls  w2     1       ;   length*2
     wa  w0     4       ;   last add to pack from
;ks-950
     rs. w0     a1.     ;
     al  w3     0       ;

     rl. w2     c0.    ;   w2 := start addr to pack from;

a2:                    ; next to-word:
     al  w0     1      ;   partial word := 1;

a3:                    ; next char:
     sl. w2    (a1.)   ;   if from-addr >= top addr to pack from then
     jl.        a4.    ;     goto terminate packing;

     ld  w0     8      ;   partial word := partial word shift 8
     lo  w0  x2        ;      + char(from addr);
     al  w2  x2+2      ;   increase (from addr);
     se  w3     1      ;   if partial word not full then
     jl.        a3.    ;     goto next char;

     rs  w0  x1        ;   word (to pointer) := partial word;
     al  w1  x1+2      ;   increase (to pointer);
     jl.        a2.    ;   goto next to-word;

a4:                    ; terminate packing:
; w0 contains: 0, 1 or 2 characters, rigthjustified
     sn  w0     1      ;   if partial word is empty (i.e. = flag) then
     jl.        f5.    ;     goto return;
     ld  w0     8      ;   fill partial word up with spaces;
     al  w2     32     ;   w2 := space;
     lo  w0     4      ;
     se  w3     1      ;
     ld  w0     8      ;
     lo  w0     4      ;

     rs  w0  x1        ;   word (to pointer) := partial word;

     jl.        f5.    ;   goto return;
e.
 
 
; unpack (limited as pack)
; call parameters :
;  w0 - start add of array to contain unpacked characters
;  w1 - start add of string/alfa to unpack
;  w3 - return-4
;        +2 length of string/alfa to unpack
;
b.   a5      w.
a1:  0                  ;   last add to contain unpacked
 
f3:  rl  w2  x3         ;
     ls  w2     1       ;   length * 2
     wa  w0     4       ;
;ks-955
     rs. w0     a1.     ;   add of last word to unpack into

     rl. w2     c0.    ;   w2 := to pointer;

a2:                    ; next word:
     rl  w0  x1        ;
     al  w3     0      ;   char := first char of word (from pointer);
     ld  w0     8      ;   partial word := char 2,3 + one;
     ba. w0     1      ;

a3:                    ; next char:
     sl. w2    (a1.)   ;   if to pointer >= top to pointer then
     jl.        f5.    ;     goto return;

     rs  w3  x2        ;   word (to pointer) := char;
     al  w2  x2+2      ;   increase (to pointer);

     al  w3     0      ;   char := leftmost char of partial word;
     ld  w0     8      ;   partial word := partial word shift 8;
     se  w0     0      ;   if partial word <> 0 then
     jl.        a3.    ;     goto next char;

     al  w1  x1+2      ;   increase (from pointer);
     jl.        a2.    ;   goto next word;
e.
 
f5:  dl. w3     c0.+6   ;
     rl  w2  x2+8       ;
     jl      x3+2       ;   return
 
e.
e.
 
0,r.(:6146-k:)>1
e.   ; end fpnames
; end segment
e.
▶EOF◀