from the imp11 documentation: %routinespec WRITE(%integer N, PLACES) outputs the decimal value of N to the currently selected output stream (using PRINTSYMBOL). If PLACES is greater than zero the number will be output right-justified in a field of PLACES+1 character positions, otherwise it will be output right-justified in a field of -PLACES character positions. In either case the size of the field will be expanded if the requested size is too small to hold the number. The maximum field size is 63 characters. -- from the imp80 documentation: %routine WRITE(%integer I, J) This routine transmits the value of the integer expression I to the currently selected output stream. The second parameter specifies the number of positions to be used. To simplify the alignment of positive and negative numbers, an additional position is allowed for a sign, but the sign is only printed in the case of negative numbers. If the number to be printed needs more positions than are specified by the second parameter, then more positions are used. Examples: WRITE(I, 4) WRITE(TOTAL+SUM+ROW(I), 6) WRITE(SNAP, POS+4) {IMP77: the total number of print positions to be used is defined by the modulus of the second parameter. If this parameter is negative, no space character is output before a positive value.} %routine PRINT(%long %real X, %integer I, J) This routine transmits to the currently selected output stream the value of the real expression specified by the first parameter. The second and third parameters should be integer expressions specifying the number of places to be allowed before and after the decimal point. If the integer part needs more positions than are specified by the parameter, then more positions will be taken. One position is allowed for a sign which is printed only in the negative case. If necessary, the fractional part will be rounded. Examples: PRINT(A, 2, 3) PRINT(COS(A-B), 1, 10) {IMP77: The second parameter is interpreted in the same way as the second parameter of WRITE (described above).} -- The vertical column is the number of digits in 'n' The horizontal row is 'm', as in write(n,m) This is what the current Imp library outputs: dig\m 0 1 2 3 4 5 6 7 1 [1] [ 1] [ 1]+ [ 1] [ 1] [ 1]* [ 1]* [ 1]* 2 [10] [ 10] [ 10] [ 10]+ [ 10] [ 10] [ 10]* [ 10]* 3 [100] [ 100] [ 100] [ 100] [ 100]+ [ 100] [ 100] [ 100]* 4 [1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000]+ [ 1000] [ 1000] 5 [10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000]+[ 10000] 6 [100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000]+ This is what I think the Imp library should output: dig\m 0 1 2 3 4 5 6 7 1 [1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] 2 [10] [ 10] [ 10] [ 10] [ 10] [ 10] [ 10] [ 10] 3 [100] [ 100] [ 100] [ 100] [ 100] [ 100] [ 100] [ 100] 4 [1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] 5 [10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] 6 [100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] The rule, as I understand it, is 'no leading spaces for m=0, but for all other m': First, prepend one space to the raw number. Then, add more spaces while the field width is less than m. I've marked with a '+' or a '*' the ones I believe to be wrong in the current implementation. The ones at the top-right of the matrix marked '*' are not using the full field width. The ones in the diagonal lower down marked '+' have an extra space and exceed their field width, for example write(100,4) should take up 4 characters, not 5. -- Although having written that, I pulled out the 3L implementation from ARM and it is identical to the current one, so I guess my memory of how it works is wrong :-) -- I'm still pondering this, and despite the fact that JDM's write() and the code from 3L's Acorn compiler both output the same text, I *still* think that it must be wrong, because there's no possible definition of write whereby write(1,7) outputs only 5 characters. It makes a mockery of the whole field width argument. I suspect that the implementation that JDM has based his code on was itself wrong, which is why they match. I will see if I can find the pdp9/15 code by Hamish or the EMAS implementation by Peter Stephens and see what they do. I know this seems a trivial thing to fixate on, but I'm having to compare output from JDM's imp and my C translations, and it's exceedingly difficult if every line is different due to spacing issues. (It is further complicated by some code in the compiler that does a write(n,1) when clearly it has to be write(n,0) to work correctly, eg in the display of assembly code labels ("L 1000" vs "L1000") - and it happens in multiple places, it's not just a 1-off typo) -- Here's Hamish's version for the 68000 compiler. %routine WRITE(%integer v,p) %integer vv,q,pos %byteintegerarray store(0:15) vv = v; vv = -vv %if vv > 0 pos = 15 %while vv <= -10 %cycle q = vv//10 store(pos) = q*10-vv+'0'; pos = pos-1 vv = q %repeat store(pos) = '0'-vv %if p <= 0 %start spaces(pos-16-p) %if p < 0 %finish %else %start spaces(pos-16+p) print symbol(' ') %if v >= 0 %finish print symbol('-') %if v < 0 print symbol(store(pos)) %and pos = pos+1 %until pos = 16 %end -- PS from the IMP80 manual: %routine WRITE(%integer I, J) This routine transmits the value of the integer expression I to the currently selected output stream. The second parameter specifies the number of positions to be used. To simplify the alignment of positive and negative numbers, an additional position is allowed for a sign, but the sign is only printed in the case of negative numbers. If the number to be printed needs more positions than are specified by the second parameter, then more positions are used. Examples: WRITE(I, 4) WRITE(TOTAL+SUM+ROW(I), 6) WRITE(SNAP, POS+4) {IMP77: the total number of print positions to be used is defined by the modulus of the second parameter. If this parameter is negative, no space character is output before a positive value.} -- Plugging this into my test bed, it's not quite exactly what I thought the 'correct' output should have been (from memory) but it is far more consistent with my recollection than the current code derived from some 3L code. The vertical column is the number of digits in 'n' The horizontal row is 'm' in write(n,m) This is what the current Imp library outputs: digits 0 1 2 3 4 5 6 7 1 [1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] 2 [10] [ 10] [ 10] [ 10] [ 10] [ 10] [ 10] [ 10] 3 [100] [ 100] [ 100] [ 100] [ 100] [ 100] [ 100] [ 100] 4 [1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] 5 [10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] 6 [100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] This is what I think the Imp library should output: digits 0 1 2 3 4 5 6 7 1 [1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] 2 [10] [ 10] [ 10] [ 10] [ 10] [ 10] [ 10] [ 10] 3 [100] [ 100] [ 100] [ 100] [ 100] [ 100] [ 100] [ 100] 4 [1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] 5 [10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] 6 [100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] Finally here's what Hamish's 68K code outputs: digits 0 1 2 3 4 5 6 7 1 [1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] 2 [10] [ 10] [ 10] [ 10] [ 10] [ 10] [ 10] [ 10] 3 [100] [ 100] [ 100] [ 100] [ 100] [ 100] [ 100] [ 100] 4 [1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] [ 1000] 5 [10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] [ 10000] 6 [100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] [ 100000] --