I compare the .ibj and .icd files from all 3 bootstrapping phases once built to confirm that everything built identically with the c version of Imp77 and the Imp version. Almost everything was identical, but two files differed: impcore-fexp.imp implib-read.imp The differences in both were in the same area - the constant table. My suspicion is that it is floating point constants that differ, but I haven't tracked it down precisely to confirm yet. impcore-fexp.imp ================ {------------------------------------------------------------------------------} ! Returns floating point x ^ p %external %long %real %function impfexp ( %integer p, %long %real x) %long %real r; %if (p = 0) %then %result = 1.0 %if (x = 0.0) %then %result = 0.0 ! deal with negative exponents %if (p < 0) %start x = 1.0/x p = -p %finish r = 1.0 %cycle %if ((p & 1) # 0) %then r = r * x; p = p >> 1; %if (p = 0) %then %result = r; x = x * x; %repeat %end {------------------------------------------------------------------------------} %endoffile c: CONST SEGMENT WORD PUBLIC 'CONST' 0000 00 B0 db 00,B0 ; .. 0002 02 18 db 02,18 ; .. 0004 01 38 db 01,38 ; .8 0006 B8 00 db B8,00 ; .. 0008 00 B0 db 00,B0 ; .. 000A 02 01 db 02,01 ; .. 000C 10 38 db 10,38 ; .8 000E B8 00 db B8,00 ; .. 0010 00 B0 db 00,B0 ; .. 0012 02 01 db 02,01 ; .. 0014 10 38 db 10,38 ; .8 0016 B8 00 db B8,00 ; .. CONST ENDS imp: CONST SEGMENT WORD PUBLIC 'CONST' 0000 00 00 db 00,00 ; .. 0002 00 00 db 00,00 ; .. 0004 00 00 db 00,00 ; .. 0006 F0 3F db F0,3F ; .? CONST ENDS ################################################################################## implib-read.imp =============== {----------------------------------------------------------------------------} ! General Imp READ routine ! Copyright 2002 NB Information Limited ! Enhanced JD McMullin 2021 ! Types extracted from general names ! Curious naming strategy because we don't want to clobber ! the built-in functions and maps like "integer" or "int" %constinteger intgr = 1 %constinteger float = 2 %constinteger strng = 3 %constinteger byte = 6 %constinteger double = 8 ! Limits %constinteger MaxInt = ((-1)>>1) %constinteger MaxByte = 255 %constlongreal MaxFloat = 3.3@38 %external %routine Read( %name ptr) %string(255) s %integer ch %integer sign, digit, len, adr, type, base, found %longreal r, exp, frac ! following variables used when copying %string s into %name ptr %byte %name dst,src %integer i len = size of(ptr) adr = addr(ptr) type = type of(ptr) %unless intgr <= type <= strng %or type = byte %or type = double %start %signal 5,5,type %finish ! skip white space skip symbol %while next symbol = ' ' %or next symbol = 8 %or next symbol = NL %or next symbol = 13 %if type = strng %start length(s) = 0 %cycle ch = next symbol %exit %if ch = ' ' %or ch = NL %or ch = 8 length(s) = length(s) + 1 charno(s,length(s)) = ch skip symbol %repeat %signal 6,1 %if length(s) > len ! Now to put the string just "read", into the variable specified %for i = 0,1,length(s) %cycle dst == byteinteger( adr + i ) src == byteinteger( addr(s) + i ) dst = src %repeat %return %finish ! The rest (int/real/byte/lreal) all expect a number ! We collect it in a longreal so that we can correctly read ! an integer into a real that is bigger than MaxInt base = 10 sign = 0 readsymbol(sign) %if next symbol = '-' %or next symbol = '+' %cycle r = 0 found = 0 %cycle ch = next symbol %if '0' <= ch <= '9' %start digit = ch - '0' %else %if 'A' <= ch & 95 <= 'Z' digit = ch & 95 - 'A' + 10 %finish %else %exit %exit %if digit >= Base found = 1 skip symbol r = r * Base + digit %repeat %exit %if ch # '_' %or r = 0 base = int(r) skipsymbol %repeat ! here we've got an integer in R - if that's what we want, exit now %if type = intgr %or type = byte %start %signal 3,1,ch %if found = 0; ! no digits? Then report the char we found %if type = intgr %start %if r > MaxInt %then %signal 1,1 %if sign = '-' %then r = -r integer(adr) = int(r) %else %if r > MaxByte %or sign = '-' %then %signal 1,1 byte integer(adr) = int(r) %finish %return %finish ! If we're still here, we are collecting a floating point number %if ch = '.' %start skip symbol frac = 0 exp = 10 %cycle ch = next symbol %exit %unless '0' <= ch <= '9' frac = frac + (ch - '0')/exp exp = exp*10 found = 1 skip symbol %repeat r = r + frac %finish ! We should really worry about @Exponent at this point... ! ... add that to the to-do list! %signal 3,1,ch %if found = 0 %if type = float %and r > MaxFloat %then %signal 1,2 %if sign = '-' %start r = -r %finish %if type = float %start real(adr) = r %else long real(adr) = r %finish %end {----------------------------------------------------------------------------} %endoffile c: CONST SEGMENT WORD PUBLIC 'CONST' 0000 62 B0 db 62,B0 ; b. 0002 02 B0 db 02,B0 ; .. 0004 00 98 db 00,98 ; .. 0006 48 62 db 48,62 ; Hb 0008 62 AC db 62,AC ; b. 000A 02 B0 db 02,B0 ; .. 000C 00 50 db 00,50 ; .P 000E 48 62 db 48,62 ; Hb 0010 FF FF db FF,FF ; .. 0012 FF 7F db FF,7F ; .. 0014 FF 00 db FF,00 ; .. 0016 00 00 db 00,00 ; .. 0018 0A 00 db 0A,00 ; .. 001A 00 00 db 00,00 ; .. CONST ENDS imp: CONST SEGMENT WORD PUBLIC 'CONST' 0000 62 24 db 62,24 ; b$ 0002 72 05 db 72,05 ; r. 0004 76 08 db 76,08 ; v. 0006 EF 47 db EF,47 ; .G 0008 FF FF db FF,FF ; .. 000A FF 7F db FF,7F ; .. 000C FF 00 db FF,00 ; .. 000E 00 00 db 00,00 ; .. 0010 0A 00 db 0A,00 ; .. 0012 00 00 db 00,00 ; .. CONST ENDS The code is affected too: < 0306 DB 05 10 00 00 00 FILD [COT+0010] < 030C DE D9 FCOMPP ST(1),ST --- > 0306 DB 05 08 00 00 00 FILD [COT+0008] > 030C DE D9 FCOMPP ST( 1),ST (it's hard to compare the two .lis files because of all the differences in spaces)