|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 105216 (0x19b00) Types: TextFile Names: »tselib «
└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer └─⟦f546e193b⟧ └─⟦this⟧ »tselib «
; pascal library ; ; version 11 ; date 88 06 14 ; ; 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 ; ; 5-6 file initialization ; reset ; rewrite ; close ; remove ; replace ; monitor ; ; 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: <:serun:>, 0, 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>:> 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>:> c18:<:file does not exist: <0>:> c8:<:end<0>:> ; reserved for simulated break, i.e. ok.no c9:c16:c17:c19: <: unused error code! ???<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, p15 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 d46 = 20 ; additional error inf d47 = 24 ; double word for time stamps d48 = 26 ; start of process ; 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 p10 = 16 ; length of procedure table entries p12 = 12 ; double word containing processing time p14 = 14 ; activation counter 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 ; end-program m66: h66+2 ; bytes transferred in fp-answer m68: h68 ; fp-stderror m51: h51 ; mode bits 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) 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); ; time stamp main program !! dl w1 110 ; current time ss w1 x3+d47 ; - old time rl. w2 b0. ; address( proc table ) aa w1 x2+p12 ; add delta ds w1 x2+p12 al w0 1 rs w0 x2+p14 ; # calls := 1 !!!! rl w2 x3+d48 ; w2:= own process descr address 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 x3+12 ; w0 := break-cause; se w0 0 ; if cause <> instruction-error then jl. a2. ; goto print error text; 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 13 ; if instruction = jl then jl. a15. ; begin bl w0 x1-1 ; if address of instruction = -1234 then se w0 -1234 ; index error, value in w-field of instruction jl. a2. ; jl. a16. ; get value a15: ; end else se w0 30 ; if instruction = 'instr 30' then jl. a2. ; begin a16: 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 ; se w0 8 ; if error number = 8 <* i.e. simulated break *> or sn w0 0 ; if error number = 0 <* i.e. normal end *> then jl. a10. ; goto terminate; se w0 15 ; if file connect errors then sn w0 18 ; jl. a4. ; goto print file name; 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; jl. a3. ; (skip print file name) a4: ; print file name: rl w1 x2+d46 ; zone := additional error inf; rl w1 x1+h0+6 ; w1 := first share; al w0 x1+14 ; w0 := file name addr; jl. w3 (m31.) ; outtext (file name); 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; 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 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); jl. a1. ; goto unwind; a8: ; write absolute: 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. w0 (m51.) ; get mode bits so w0 1<8 ; skip if mode listing jl. a14. b. c15 , q10 w. ; print heading al. w0 c9. ; jl. w3 (m31.) ; outtext( 'performance measurement ... ') jl. w3 q8. ; print ( '----------------------------' ) rl. w2 b0. ; get start of procedure table ; compute total run time and total number of calls al w3 0 dl. w1 c0. q1: aa w1 x2+p12 ; add time wa w3 x2+p14 ; add # calls al w2 x2+p10 se. w2 (b2.) ; until top of procedures jl. q1. ds. w1 c0. ; save sum rs. w3 c1. ; print table rl. w1 b0. q2: rs. w1 b22. ; repeat rl w0 x1+p8 ; start of routine error table rs. w0 b24. jl. w3 m1. ; get start line rs. w0 b12. al. w2 b16. ; get routine name q3: jl. w3 m1. rs w0 x2 al w2 x2+2 se. w2 b16.+8 jl. q3. al. w0 b16. ; outtext(routinename) jl. w3 (m31.) rl. w0 b12. ; get start line jl. w3 (m32.) ; outinteger( start line ) 32<12 + 5 rl. w2 b22. ; current proc table entry rl w0 x2+p14 ; jl. w3 (m32.); outinteger( # calls ) 32<12 + 10 rl w0 x2+p14 ; # calls wm. w0 c3. ; * 100000 wd. w0 c1. ; div sum of calls al w3 0 wd. w0 c4. ; div 1000 rs. w3 c2. ; temp := fraction part jl. w3 (m32.); outinteger( call % ) 1<23+ 32<12 + 8 al w2 46 jl. w3 (m26.); outchar( . ) rl. w0 c2. jl. w3 (m32.) ; outinteger(%-fraction) 48<12 + 3 ; rl. w2 b22. rl w3 x2+p14 ; average per call se w3 0 jl. q4. al. w0 c6. ; outtext(' ------') jl. w3 (m31.) jl. q5. ; skip q4: dl w1 x2+p12 ; time wd w1 6 ; div # calls al w0 0 ; nb: time per call < 13 min wd. w1 c8. ; div 10000 rs. w0 c2. ; save fraction al w0 x1 jl. w3 (m32.) ; outinteger 32<12 + 9 al w2 46 jl. w3 (m26.) ; outchar( . ) rl. w0 c2. jl. w3 (m32.) ; outinteger( fraction ) 48<12 + 4 q5: rl. w2 b22. ; module total dl w0 x2+p12 wd. w0 c8. ; div 10000 rs. w3 c2. ; save fraction jl. w3 (m32.) ; outinteger( time in seconds ) 32<12 + 8 al w2 46 jl. w3 (m26.) rl. w0 c2. jl. w3 (m32.) ; outinteger( fraction ) 48<12 + 4 ; percent of total dl. w1 c0. ; total time wd. w1 c11. ; div 10 rs. w1 c2. ; units of ms rl. w2 b22. rl w0 x2+p12 ; only low bits wm. w0 c8. ; * 10000 wd. w0 c2. al w3 0 wd. w0 c4. ; div 1000 rs. w3 c2. ; save fraction jl. w3 (m32.) ; outintger( % of total ) 32<12 + 10 al w2 46 jl. w3 (m26.) ; outchar ( . ) rl. w0 c2. jl. w3 (m32.) ; outinteger( fraction ) 48<12 + 3 al w2 10 ; nl jl. w3 (m26.) ; writeln rl. w1 b22. al w1 x1+p10 se. w1 (b2.) ; until top of procedures jl. q2. ; output totals jl. w3 q8. ; --------------------- al. w0 c10. jl. w3 (m31.) ; outtext('<nl>Totals') rl. w0 c1. jl. w3 (m32.) ; outinteger( total calls ) 32<12 + 17 dl. w0 c0. ; total time wd. w0 c1. ; div # calls al w3 0 wd. w0 c8. ; div 10000, convert to seconds rs. w3 c2. jl. w3 (m32.) ; outinteger( average per call ) 32<12 + 21 al w2 46 jl. w3 (m26.) ; outchar ( . ) rl. w0 c2. jl. w3 (m32.) ; outinteger( fraction ) 48<12 + 4 dl. w0 c0. ; total time wd. w0 c8. ; div 10000 rs. w3 c2. jl. w3 (m32.) ; outinteger( time in seconds ) 32<12 + 8 al w2 46 jl. w3 (m26.) ; outchar( . ) rl. w0 c2. jl. w3 (m32.) ; outinteger(fraction) 48<12 + 4 al w2 10 jl. w3 (m26.) ; outnl jl. a14. ; pass the constants ; procedure printline , destroy all regs q8: rs. w3 c2. ; save return al w1 81 ; line length q9: rs. w1 c7. ; save counter al w2 45 ; '-' jl. w3 (m26.) ; repeat outchar('-') rl. w1 c7. al w1 x1-1 se w1 0 ; until w1 = 0 jl. q9. al w2 10 jl. w3 (m26.) ; outnl jl. (c2.) ; return ; constants and variables 0 c0: 0 ; total time c1: 0 ; total number of calls c2: 0-0-0 ; work c7: 0-0-0 ; work c3: 100000 c4: 1000 c5: 100 c11: 10 c6: <: ------<0>:> c8: 10000 c9: <:<12><10>Performance measurement summary for PASCAL program : <10><10>:> <: Name Line Called % of calls Average (sec) Total (sec) % of time<10><10><0>:> c10: <:<10> Totals:<0>:> e. a14: 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 0, r.(:(:k+511:)>9<9-k:)>1 + 1 ; fill to segment boundary m. start of page 1 ; library procedures : ln, exp, sinh, system, clock ; ln, exp sinh has been made by ns and nsa 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 ; 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 0, r.(:(:k+511:)>9<9-k:)>1 + 1 ; fill to segment boundary m. start of page 2 ;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 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 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 0, r.(:(:k+511:)>9<9-k:)>1 + 1 ; fill to segment boundary m. start of page 3 ;slang subroutines: arctan, arg, cos, sin, monitor ;by ns adapted from nsa ; changed 78 03 30 by bbj to fit pascal 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 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 e. \f 0, r.(:(:k+511:)>9<9-k:)>1 + 1 ; fill to segment boundary m. start of page 4 ; 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 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; rl. w1 b1. ; w1 := zone; se w0 0 ; if not ok then jl. c2. ; error (file does not exist); al w2 x3 ; 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; 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<2+0 ; w0 := 1 sliceon first document with free temp resources; 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 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 ; <:serun:>, 0, 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; 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-18 ;13: illegal zonestate: c2: am 18-15 ;18 - file does not exist c5: al w0 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 rx w1 0 ; w0 := additional inf (= zone), w1 = errorcode ;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 0, r.(:(:k+511:)>9<9-k:)>1 + 1 ; fill to segment boundary m. start of page 5 ; pascal i/o ; write routines for text files b. a45,b15,c22, i5, d15 w. i5: 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 address or stackref, depending on callmethod ; w3 - return - 4 ; +0 5<12 + relative or -1<12 + relative (normal call or direct call) ; +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 ; saved x3+0, write (even)/writeln(odd) 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); rl w1 x3 ; rs. w1 d2. ; save call parameter 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. ; so w0 1 ; 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. w0 d2. ; if not direct call sl w0 0 ; then rl w2 x2+8 ; reestablish stackref jl x3+4 ; return e. ; error return d13: am 7-13 ; alarm 7 - negative field width d12: al w1 13 ; alarm 13 - illegal zonestate dl. w3 d0.+6 ; reestablish regisers w2,w3 el. w0 d2. ; if direct call then sh w0 0 ; jl. (i5.+2) ; rt error, address set up by initcode rl w0 x2+4 ; w0 := add of rt error rs. w0 d0.+4 ; rl w2 x2+8 ; w2 := stacktop al w0 -1 ; jl. (d0.+4) ; jump to error return e. \f 0, r.(:(:k+511:)>9<9-k:)>1 + 1 ; fill to segment boundary m. start of page 6 ; 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 ; w2 - address of routine table entry or stackref (normal call or direct call) ; w3 - return -2 ; ; call code : ; jl (x2-2035) ; 6<12 + relative or -1<12 + relative (direct call) ; 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. i15: 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 dl. w3 b0.+6 ; reestablish registers w2, w3 el w0 x3 ; if direct call then sh w0 0 ; jl. (i15.+2) ; rt error, address set up by initcode else 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 w0 x3 ; if not direct called sl w0 0 ; then 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 0, r.(:(:k+511:)>9<9-k:)>1 + 1 ; fill to segment boundary m. start of page 7 b. f5,c1 w. c1: 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 ; w2 - procedure table entry address or stackref (direct call) ; w3 - return-4 : ; +0 7<12 + 0 (read)/ 1 (write) or -1<12 + 0/1 (direct call) ; +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 w0 x3-2 ; if not direct call sl w0 0 ; then 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 x3-2 ; if direct call sh w0 0 ; then jl. (c1.+2) ; call runtime error, address set up by initcode; else 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 ; w2 - address of procedure table entry or stackref (direct call) ; w3 - return-4 ; +0 7<12 + relative or -1<12 + relative ; +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 ; w2 - address of procedure table entry or stackref (direct call) ; w3 - return-4 ; +0 7<12 + relative or -1<12 + relative ; +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 w0 x3-2 ; if not direct call sl w0 0 ; then rl w2 x2+8 ; jl x3+2 ; return e. e. 0, r.(:(:k+511:)>9<9-k:)>1 + 1; fill to segment boundary e. ; end fpnames ; end segment e. ▶EOF◀