! XCODESCAN - scans .MOB files for Extracode calls

%begin
%include "inc:util.imp"
%constinteger jsr=16_4eb8,jmp=16_4ef8
%recordformat fe02(%byte type,version,%half flags,export,import,
                   %integer code,%half reset,main,%integer own,stack,s1,s2)
%record(fe02)%name mob
%integer pos,size,i
%string(255)parm,file

%constinteger n=109

%conststring(15)%array codename(1:n)=-
      "RomREBOOT",        "RomBOOT",        "RomLOAD",        "RomPHEX",
       "RomPHEX4",       "RomPHEX2",       "RomPHEX1", "RomPRINTSYMBOL",
 "RomPRINTSTRING", "oldprintsymbol", "oldprintstring",  "oldreadsymbol",
  "oldnextsymbol",      "oldprompt",  "oldtestsymbol", "oldselectinput",
"oldselectoutput",  "oldresetinput", "oldresetoutput",  "oldcloseinput",
 "oldcloseoutput",   "oldopeninput",  "oldopenoutput",   "oldetheropen",
  "oldetherclose",  "oldetherwrite",   "oldetherread",       "oldfcomm",
      "oldfcommw",      "oldfcommr",      "oldsignal",        "oldread",
       "oldwrite",        "oldmull",        "olddivl",      "oldscompu",
       "oldscomp",     "oldcputime",    "oldarraydef",    "oldarrayget",
    "oldarrayref", "oldsettermmode", "absentintpower",    "absentrplus",
   "absentrminus",    "absentrmult",     "absentrdiv",   "absentrpower",
  "absentrnegate",    "absentfloat",   "absentfracpt",    "absentintpt",
     "absentsqrt",    "absentline3", "absenttrapeze3","absenttriangle3",
     "olddefname",     "oldrefname",   "oldtransname",    "olddefineeh",
        "oldnhex",        "oldbhex",        "oldwhex",        "oldlhex",
        "oldrhex","absentetherbits",   "absenthline3",    "absentfill3",
   "absentclear3",   "absentvline3",    "absentresol",  "absentconnect",
  "absentextload",    "connectfile",      "[monitor]",    "closeoutput",
     "closeinput",      "setoutput",       "setinput",   "selectoutput",
    "selectinput",     "openoutput",      "openinput",    "printstring",
    "printsymbol",     "readsymbol",     "skipsymbol",     "nextsymbol",
        "dispose",            "new",           "sqrt",         "fracpt",
          "intpt",            "int",       "fraction",          "trunc",
          "round",          "float",           "FPOW",           "FDIV",
           "FMUL",           "FSUB",           "FADD",           "FNEG",
           "IPOW",           "IDIV",           "IMUL",         "SIGNAL",
      "screenput"
%constintegerarray codeaddr(1:n)=-
16_0400,16_0404,16_0408,16_040C,
16_0410,16_0414,16_0418,16_041C,
16_0420,16_10C0,16_10C4,16_10C8,
16_10CC,16_10D0,16_10D4,16_10D8,
16_10DC,16_10E0,16_10E4,16_10E8,
16_10EC,16_10F0,16_10F4,16_10F8,
16_10FC,16_1100,16_1104,16_1108,
16_110C,16_1110,16_1114,16_1118,
16_111C,16_1120,16_1124,16_1128,
16_112C,16_1130,16_1134,16_1138,
16_113C,16_1140,16_1144,16_1148,
16_114C,16_1150,16_1154,16_1158,
16_115C,16_1160,16_1164,16_1168,
16_116C,16_1170,16_1174,16_1178,
16_117C,16_1180,16_1184,16_1188,
16_118C,16_1190,16_1194,16_1198,
16_119C,16_11A0,16_11A4,16_11A8,
16_11AC,16_11B0,16_11B4,16_11B8,
16_11BC,16_3E2E,16_3E34,16_3E3A,
16_3E40,16_3E46,16_3E4C,16_3E52,
16_3E58,16_3E5E,16_3E64,16_3E6A,
16_3E70,16_3E76,16_3E76,16_3E7C,
16_3E82,16_3E88,16_3E8E,16_3E94,
16_3E9A,16_3EA0,16_3EA6,16_3EAC,
16_3EB2,16_3EB8,16_3EBE,16_3EC4,
16_3ECA,16_3ED0,16_3ED6,16_3EDC,
16_3EE2,16_3EEE,16_3EF4,16_3EFA,
16_3FA2

%integerarray count(0:n)

%integerfn find(%integer value)
%integer lo=1,hi=n,mid
  %cycle
    %if lo>hi %start
      printstring("Unknown "); phex4(value)
      write(lo,2); write(hi,2); write(mid,2); newline
      %result = 0
    %finish
    mid = (lo+hi)>>1
    %result = mid %if value = codeaddr(mid)
    %if value>codeaddr(mid) %then lo = mid+1 %else hi = mid-1
  %repeat
%end

parm = cliparam.","
%while parm -> file.(",").parm %cycle
  file = file.".mob"
  count(i) = 0 %for i = 0,1,n
  connectfile(file,0,pos,size)
  printstring("File ".file); newline
  mob == record(pos)
  %if mob_type=16_fe %and mob_version=2 %start
    pos = pos+sizeof(mob)+mob_export+mob_import
    size = mob_code
  %finish
  %while size>0 %cycle
    %if halfinteger(pos)=jsr %or halfinteger(pos)=jmp %start
      pos = pos+2; size = size-2
      i = find(halfinteger(pos))
      count(i) = count(i)+1
    %finish
    pos = pos+2; size = size-2
  %repeat
  %for i = 1,1,n %cycle
    %if count(i)#0 %start
      write(count(i),3); space; phex4(codeaddr(i))
      space; printstring(codename(i)); newline
    %finish
  %repeat
%repeat
%endofprogram
