{#######################################} {# PDP11 IMP77 Object File Generator #} {# #} {# Copyright November 1981 #} {# Peter S. Robertson #} {# #} {#######################################} {#################################################################} {# Object file format: = Word value N, [N] = Byte value N #} {# #} {# Zeroth word: 0 or size in bytes of Data Items #} {# First word: #} {# Second word: #} {# Third word: #} {# Fourth word: #} {# Fifth word: #} {# "Section name" #} {# #} {# External Definitions #} {# [Area] "REFERENCE" #} {# #} {# "REFERENCE" #} {# External References #} {# #} {# Data Items #} {# #} {# Item 1: Select code area at displacement #} {# Item 2: Select gla area at displacement #} {# Item 3: Select diag area at displacement #} {# Item 4: Select line area at displacement #} {# Item 5: Relocate by code area base #} {# Item 6: Relocate by gla area base #} {# Item 7: Relocate by diag area base #} {# Item 8: Relocate by line area base #} {# Item 9: Relocate by external #} {# Item 10: Relocate by -PC #} {# Item 11: [B] Add byte [B] to current area #} {# Item 12: Add word to current area - aligned! #} {# Item 13: This is line #} {# Item 14: Event Block #} {# Item 15: End of file #} {#################################################################} %CONSTINTEGER Select Code= 1, Select Gla = 2, Select Diag = 3, Select Line = 4, Code Reloc = 5, Gla Reloc = 6, Diag Reloc = 7, Line Reloc = 8, Ext Reloc = 9, Pc Reloc = 10, Add Byte = 11, Add Word = 12, Line No = 13, Event Block = 14, Eof = 15 {Configuration constants} %CONSTINTEGER Max Item= 8000, Max External = 200, X Length = 15, Objectives = 1, Directives = 2, Object = 3 %EXTERNALSTRING (63) %FNSPEC usual ItoS %ALIAS "S#ITOS"(%INTEGER N) %BEGIN %STRINGFN itos(%INTEGER a,b) %RESULT = usual itos(a) %END {itos} {Block attributes} %CONSTINTEGER Attr R1= 1<< 8, Attr R2 = 1<< 9, Attr Inner Uses = 1<<10, Attr Uses locals = 1<<11, Attr Dynamic = 1<<12, Attr String = 1<<13 %RECORDFORMAT Itemfm((%BYTE Type, Flags %ORINTEGER Dummy %ORINTEGER Frame %ORINTEGER String %ORINTEGER %C Entry1),(%INTEGER Ca %ORRECORD (Itemfm) %NAME First %ORINTEGER %C Attr %ORINTEGER Entry2), (%RECORD (Itemfm) %NAME Label %ORRECORD (Itemfm) %NAME %C Second %ORINTEGER Params), %RECORD (Itemfm) %NAME Link) {* %recordformat Itemfm( %c} {* (%byte Type, Flags, %integer Ca, %record(Itemfm)%name Label, Link) %c} {* %or (%integer Dummy, %record(Itemfm)%name First, Second) %c} {* %or (%integer Frame, Attr, Params) %c} {* %or (%integer String) %c} {* %or (%integer Entry1, Entry2))} { *------*-------*---------*--------*--------*} { | Type | Flags | Ca | Label | Link |} { *------*-------+---------+--------*--------*} { | First | Second |} { *--------------+---------*--------*} { | Frame | Attr | Params |} { *--------------*---------*--------*} { | String |} { *--------------*---------*} { | Entry 1 | Entry 2 |} { *--------------*---------*} {Types} {Flags} %CONSTINTEGER Lab= 0, Long = 1<<0, Slab = 1, Invert = 1<<1, McUsed = 2, Removed = 1<<2, Return = 3, Unreach = 1<<3, EndJ = 4, Forward = 1<<4, Call = 5, CallP1 = 6, CallP2 = 7, JumpC = 8, JumpP1 = 9, JumpP2 = 10, Uncond = 11, CjumpC = 12, CjumpP1 = 13, CjumpP2 = 14, Cond = 15, OldLab = 16, Prefix = 17 { label link} { *-----*------*-----*----* *-------*------*-------*---*} { Z--> | lab | size | * | *-+------> | frame | attr | param | * |} { *-----*------*--+--*----* *-------*------*-------*-+-*} { | |} { | v} { v *-------*------*-------*---*} { Labels & Defs |string | | | * |} { *-------*------*-------*-+-*} { |} { v} { Next block} %INTEGER More %CONSTINTEGER SpMove= 2 %INTEGER Events,Event Count %OWNSTRING (15) Section= "", New Section = "" %OWNINTEGER Xmin= Max External+1, Xmax = 6, Xnum = 0, Spec List = 0 %OWNINTEGERNAME Spec End %STRING (X Length) %ARRAY Xspec(2:Max External) %INTEGERARRAY Xused,Xmap(2:Max External) %CONSTRECORD (Itemfm) %NAME Null= 0 %RECORD (Itemfm) %ARRAY Item(0:Max Item) {*----------------*------------*-------------------*} {| (labels) Max->|\\\\\\\\\\\\|<-Min (references) |} {*----------------*------------*-------------------*} %OWNRECORD (Itemfm) %NAME Z,Pitem,Parm List,Order %RECORD (Itemfm) Dummy %INTEGER Min,Max %INTEGER Total Ca,This Line %INTEGER Constant Size,Own Size !!! %ROUTINE Tell(%STRING(63) What) !!! Printstring(What) !!! Newline !!! %END %ROUTINE Fail(%STRING (63) Why) Select Output(0) Printstring("*Pass 3 fails -- ") Printstring(Why) %IF This Line#0 %START Printstring(" at source line") Write(This Line,1) %FINISH Newline %MONITOR %STOP %END %INTEGERFN Two Bytes %INTEGER Bl,Bh Readch(Bl) Readch(Bh) %RESULT = Bh<<8+Bl %END %INTEGERFN Two signed Bytes %INTEGER N N = Two bytes N = N!x'FFFF0000' %IF N&x'8000'#0 %RESULT = N %END %ROUTINE Get Text(%STRING (*) %NAME Text) %INTEGER j,l,s Text = "" Readch(L) %FOR J = 1,1,L %CYCLE Readch(S); S = S-32 %IF 'a'<=S<='z' Text = Text.Tostring(S) %REPEAT %END %ROUTINE Mark Use(%INTEGER N) Fail("Spec out of range") %UNLESS 0D(Sym) %IF 1<=Sym<=25 D(*): Fail("Unknown directive ".ItoS(Sym,0)) D(16): {Entry 1} D(17): {Entry 2} N = Two Bytes Lb <- Two signed Bytes; Ub <- Two signed Bytes Max = Ub %IF Ub>Max Get Pitem(Lb,Ub) %IF Sym=16 %START Pitem_Entry1 = N %FINISHELSESTART Pitem_Entry2 = N %FINISH %CONTINUE D(12): {Xdef: <> "Id"} D(13): {Ddef: <> "Id"} XMin = XMin-1 Fail("Too many externals") %IF Xmin=Xmax Xmap(Xmin) = Two Bytes Xused(Xmin) = Sym-12+Code Reloc Get Text(Xspec(Xmin)) %CONTINUE D(10): {Notex: <> "Id"} Xmax = Xmax+1 Fail("Too many external specs") %IF Xmax=Xmin Fail("Spec mismatch") %IF Xmax#Two Bytes>>1 Get Text(Xspec(Xmax)) Xused(Xmax) = 0 Xmap(Xmax) = 0 %CONTINUE D(8): {Spec: <>} Mark Use(Two Bytes>>1) %CONTINUE D(1): {Unconditional Jump: <> <>} Sym = Uncond; ->Common D(2): { Conditional Jump: <> <>} Sym = Cond; ->Common D(4): {Procedure Return: <<000>> <>} Sym = Return; ->Common D(14): {Mc Used: <> <>} Sym = McUsed; ->Common D(20): {Call: <> <>} Sym = Call; ->Common D(21): {Call prefix 1: <> <>} Sym = CallP1; ->Common D(22): {Call prefix 2: <> <>} Sym = CallP2; ->Common D(23): {JumpC: <> <>} Sym = JumpC; ->Common D(24): {JumpP1: <> <>} Sym = JumpP1; ->Common D(25): {JumpP2: <> <>} Sym = JumpP2; ->Common Common: Tag = Two Bytes Min = Min-1 Max = Tag %IF Tag>Max Fail("Jump tables full") %IF Min<=Max T == Item(Min) T_Ca = Two Bytes T_Label == Item(Tag) {redundant in the case of return} T_Flags = 0 T_Type = Sym Refs_Link == T Refs == T {add to end of item list} %CONTINUE D(19): {Switch: <> <> <>} Lb <- Two Signed Bytes Ub <- Two Signed Bytes Tag = Two Bytes %FOR N = Lb,1,Ub %CYCLE Tag = Tag+1 T == Item(Tag) T = 0 T_Type = Lab; T_Ca = N<<1+1 {ODD to give error} %REPEAT Max = Tag %IF Tag>Max %CONTINUE D(18): {Slab} D(5): {Tag definition: <> <>} Tag = Two Bytes; Ca = Two Bytes Max = Tag %IF Tag>Max Fail("Label tables full") %IF Min<=Max T == Item(Tag) T_Ca = Ca %IF Sym=18 %START %IF T_Type#0 %START {redefinition} N = T_Type %AND Fail("Corrupt switch") %IF T_Type#Slab Refs_Link == Null Q == Hold %CYCLE Fail("Switch def error") %IF Q==Null %EXITIF Q_Link==T Q == Q_Link %REPEAT Q_Link == T_Link Refs == Q %IF Refs==T {on the end} %FINISH T_Type = Slab %FINISHELSESTART T_Type = Lab %FINISH Refs_Link == T; Refs == T; {add to end of item list} %CONTINUE D(6): {Start of block: <>} Phase 1(Two Bytes) %CONTINUE %REPEAT D(7): {End of block: <><><><><>} B_Frame = Two Bytes B_Params = Two Bytes Bx_String = Two Bytes B_Attr = Two Bytes Head_Ca = Two Bytes Fail("Odd initial size") %IF Head_Ca&1#0 %OR B_Attr&255#0 %IF Head Tag=0 %START Bx = 0 B = 0 B_Link == Bx %FINISH Mark Use(SPMOVE) %IF Bx_String#0 Attr = B_Attr N = 0 N = N+2 %IF Attr&Attr R1#0 N = N+2 %IF Attr&Attr R2#0 B_Frame = B_Frame-B_Params B_Params = B_Params-N-Bx_String Fcode = 0 %IF B_Frame#0 %START %IF B_Frame<=4 %THEN Fcode = 2 %ELSE Fcode = 4 %FINISH %IF Attr&(Attr Uses locals!Attr Inner Uses)=0 %START Fcode = 0 N = 0 B_Frame = 0 Attr = 0 %FINISHELSEIF Attr&Attr Dynamic=0 %START Fcode = 0 B_Frame = 0 N = N+2 %IF Attr&Attr R2#0 Attr = Attr&(\Attr Inner Uses) !!!Tell("Non-dynamic") %FINISHELSESTART N = N+4 %FINISH N = N+4 %IF B_Params#0 N = N+6 %IF Bx_String#0 N = N+8 %IF Attr&Attr Inner Uses#0 B_Attr = Attr+N+Fcode Refs_Link == Null Head_Label == Hold_Link Process(Head) %END {of Phase 1} %ROUTINE Process Parameters %INTEGER Extra %RECORD (Itemfm) %NAME P,L,Next,H,L1,L2 P == Parm List %WHILE P##Null %CYCLE L1 == P_Label L2 == L1_Link Next == P_Link H == L1_Label {Block head} L == H_Link_Link {BX} L2_Link == H_Label; L2_Type = Lab L1_Link == L2; L1_Type = Lab H_Label == L1 L_Label == P Extra = 0 %IF P_Entry1#0 %START Extra = 2 Extra = 4 %UNLESS P_Entry1=1 %OR P_Entry1=x'FFFF' %FINISH L1_Ca = -Extra %IF P_Entry2#0 %START Extra = Extra+2 Extra = Extra+2 %UNLESS P_Entry2=1 %OR P_Entry2=x'FFFF' %FINISH L2_Ca = -Extra L_Ca = Extra {size of prefix} P == Next %REPEAT %END %ROUTINE Phase 2 {Minimise the connections} {Note: Refs are in increasing order of CA} %RECORD (Itemfm) %NAME Head,P,End %RECORD (Itemfm) All %INTEGER Ca %ROUTINE Stretch(%RECORD (Itemfm) %NAME Head, %INTEGER Attr) %RECORD (Itemfm) %NAME P,End,Old End,Ll %RECORD (Itemfm) Hold %INTEGER Mod,N,Old Mod = Attr&255 Fail("Odd mod") %IF Mod&1#0 %CYCLE P == Head_Label End == Hold %WHILE P##Null %CYCLE Old End == End End_Link == P; End == P {insert it provisionally} P_Ca = P_Ca+Mod %IF P_Type=Uncond %START {unconditional jump} N = P_Label_Ca-(P_Ca+2) N = N+Mod %IF P_Flags&Forward#0 {forward ref} %UNLESS-256<=N<=254 %START {must be long} P_Flags = P_Flags!Long Mod = Mod+2 End == Old End {remove it} %FINISHELSEIF N=0 %START {degenerate jump} P_Flags = P_Flags!Removed End == Old End Mod = Mod-2 !!!Tell("Degenerate jump removed") %FINISH %FINISHELSEIF P_Type=Cond %START {conditional jump} N = P_Label_Ca-(P_Ca+2) N = N+Mod %IF P_Flags&Forward#0 {forward ref} %UNLESS-256<=N<=254 %START {must be very long} P_Flags = P_Flags!Long Mod = Mod+4 End == Old End {remove it} %FINISHELSEIF N=0 %START {degenerate jump} P_Flags = P_Flags!Removed End == Old End Mod = Mod-2 !!!Tell("Degenerate jump removed") %FINISH %FINISHELSEIF Call<=P_Type<=CallP2 %START {call} P_Flags = P_Flags!Long Mod = Mod+2 {calls start short} End == Old End {always remove it} %FINISHELSEIF P_Type=Return %START {return} %IF Attr&255#0 %AND Attr&Attr Dynamic#0 %START Mod = Mod+4 Mod = Mod+4 %IF Attr&Attr Inner Uses#0 %FINISH End == Old End {always remove it} %FINISH P == P_Link %REPEAT End_Link == Null Head_Label == Hold_Link %EXITIF Mod=0 Head_Ca = Head_Ca+Mod Mod = 0 %REPEAT %END {Reorder the blocks if any gain is to be had} %ROUTINE Reorder Blocks %RECORD (Itemfm) %NAME End,P,First,Second,Next,Loop,N %RECORD (Itemfm) Total,Hold %INTEGER Again {Mark significant blocks} End == Hold P == Order %CYCLE First == P_First Second == P_Second_Label Second == Second_Label %IF Second_Type=Prefix %IF Second##First %START {beware of recursive ends} End_Link == P {back on the list} End == P P_Second == Second Second_Ca = Second_Ca!1 First_Ca = First_Ca!1 %FINISH P == P_Link %REPEATUNTIL P==Null End_Link == Null Order == Hold_Link %RETURNIF Order==Null {Pull off normal blocks} P == Z End == Total %WHILE P##Null %CYCLE Next == P_Link_Link %IF P_Ca&1=0 %START End_Link == P End == Next %FINISH P == Next_Link %REPEAT {Sort the order list - nasty if mutual recursion about} %CYCLE Hold_Link == Null Again = 0 %CYCLE Next == Order_Link First == Order_First Second == Order_Second Fail("Corrupt order") %IF First_Ca&1=0 %OR Second_Ca&1=0 P == Hold %CYCLE N == P_Link %EXITIF N==Null {put it on the end} %IF Second==N_First %START {a better position} Loop == N %CYCLE %EXITIF Loop_Second==First {loop detected} Loop == Loop_Link %REPEATUNTIL Loop==Null %IF Loop==Null %START {no loop} Again = 1 {reorder it} %EXIT %FINISH %FINISH P == N %REPEAT P_Link == Order; Order_Link == N Order == Next %REPEATUNTIL Order==Null Order == Hold_Link %REPEATUNTIL Again=0 {finally insert the blocks in the best positions} %CYCLE First == Order_First Second == Order_Second %IF First_Ca&1#0 %START {not yet placed} First_Ca = First_Ca-1 End_Link == First End == First_Link_Link %FINISH %IF Second_Ca&1#0 %START Second_Ca = Second_Ca-1 End_Link == Second End == Second_Link_Link %FINISH Order == Order_Link %REPEATUNTIL Order==Null End_Link == Null Z == Total_Link !!!Tell("Reordered") %END Reorder Blocks %IF Order##Null {Mark the forward references} %ROUTINE Mark Forward(%RECORD (itemfm) %NAME P) %WHILE p##Null %CYCLE %IF P_Type=Cond %OR P_Type=Uncond %START P_Flags = P_Flags!Forward %IF P_Ca>8) %END %ROUTINE Dump1(%INTEGER B) %RETURNIF Unreachable#0 Printch(Add Byte) Printch(B) Ca = Ca+1 %END %ROUTINE Dump2(%INTEGER V) %RETURNIF Unreachable#0 Printch(Add Word) Printch(V&255) Printch(V>>8) Ca = Ca+2 %END %ROUTINE Set loc(%INTEGER Area) Printch(Area) Put(Ca) %END %ROUTINE X Reloc(%INTEGER N) Fail("Zero relocation") %IF N=0 N = Xmap(N) Fail("External omitted") %IF N=0 Printch(Ext Reloc); Put(N) %END %ROUTINE Dump Header(%RECORD (Itemfm) %NAME B) %RECORD (Itemfm) %NAME V %INTEGER String %ROUTINE Insert(%INTEGER R,N) %IF N=1 %START Dump2(8_005200+R) {INC_R} %FINISHELSEIF N=x'FFFF' %START Dump2(8_005300+R) {DEC_R} %FINISHELSEIF N#0 %START Dump2(8_062700+R) {ADD_#N,R} Dump2(N) %FINISH %END V == B_Link %IF V_Ca#0 %START Ca = Ca-V_Ca Set Loc(Select Code) V == V_Label Insert(2,V_Entry2) Insert(1,V_Entry1) %FINISH %RETURNIF Attr=0 %IF Attr&Attr Dynamic#0 %START Dump2(8_010446) {MOV_LNB,-(SP)} Dump2(8_010504) {MOV_DS,LNB} %IF B_Params#0 %START Dump2(8_162704) {SUB_#P,LNB} Dump2(B_Params) %FINISHELSESTART %IF Attr&Attr R1#0 %START Dump2(8_010125) {MOV_R1,(DS)+} %IF Attr&Attr R2#0 %START Dump2(8_010225) {MOV_R2,(DS)+} %FINISH %FINISH %FINISH %FINISHELSESTART {no dynamic} %IF B_Params#0 %START Dump2(8_162705) {SUB_#P,DS} Dump2(B_Params) %FINISHELSEIF Attr&Attr R1#0 %START Dump2(8_010115) {MOV_R1,(DS)} %IF Attr&Attr R2#0 %START Dump2(8_010265) {MOV_R2,2(DS)} Dump2(2) %FINISH %FINISH %FINISH %IF Attr&Attr Inner Uses#0 %START Dump2(8_013746) {MOV_Display[Level],-(SP)} X Reloc(Display Reloc) Dump2(Level*2) Dump2(8_010437) {MOV_LNB,Display[Level]} X Reloc(Display Reloc) Dump2(Level*2) %FINISH String = B_Link_String %IF String#0 %START {final string parameter} Dump2(8_004737) {Jsr_@#SpMove} X Reloc(SPMOVE) Dump2(0) Dump2(String) %FINISH %IF B_Frame#0 %START %IF B_Frame=2 %START Dump2(8_005725) {TST_(DS)+} %FINISHELSEIF B_Frame=4 %START Dump2(8_022525) {CMP_(DS)+,(DS)+} %FINISHELSESTART Dump2(8_062705) {Add_#F,DS} Dump2(B_Frame) %FINISH %FINISH %END %ROUTINE Dump Return(%RECORD (Itemfm) %NAME B) %INTEGER Attr %RETURNIF Unreachable#0 Attr = B_Attr %IF Attr&255#0 %AND Attr&Attr Dynamic#0 %START Dump2(8_010405) {MOV_LNB,DS} %IF Attr&Attr Inner Uses#0 %START Dump2(8_012637) {MOV_(SP)+,Display[Level]} X Reloc(Display Reloc) Dump2(Level*2) %FINISH Dump2(8_012604) {MOV_(SP)+,DS} %FINISH Dump2(8_000207) {RTS_PC} %END %ROUTINE Put String(%STRING (*) %NAME S) %INTEGER L,J L = Length(S) Printch(L) Printch(Charno(S,J)) %FOR J = 1,1,L %END %ROUTINE Put Text(%INTEGER P) Put String(Xspec(P)) %END %ROUTINE Dump External Definitions %INTEGER N,C Put(Max External-Xmin+1) {Number of externals} %WHILE Xmin<=Max External %CYCLE N = Xmap(Xmin) C = Xused(Xmin) Printch(C) %IF C=Code Reloc %START {Code reference via label} Put(Item(N)_Ca) %FINISHELSESTART {Gla reference} Put(N) %FINISH Put Text(Xmin) Xmin = Xmin+1 %REPEAT %END %ROUTINE Dump External References %INTEGER P,N N = 0 Put(Xnum) P = Spec List %WHILE P#0 %CYCLE %IF Xspec(P)="@DISPLAY" %START Fail("Duplicate display") %IF Display Reloc#0 Display Reloc = P %FINISH Put Text(P) N = N+1 Fail("Corrupt spec") %IF Xmap(P)#N P = Xused(P) Xnum = Xnum-1 %REPEAT Fail("Spec lost") %IF Xnum#0 %END %ROUTINE Dump object file header Put(More) Put(Total Ca+Constant Size) Put(Own Size) Put(0) Put(0) Put(Events) Put String(Section) Dump External Definitions Dump External References %END %ROUTINE Next Min Min = Min-1 %END T == Null Bias = 0 Unreachable = 0 Dump object file header %IF Head Tag=0 Head == Item(Head Tag) Next Min; B == Item(Min) Next Min; Bx == Item(Min) Fail("Block phase error") %UNLESS Head_Label==B %AND B_Link==Bx Ca == Code Base Attr = B_Attr Ca = Head_Ca Set loc(Select Code) Dump Header(B) %CYCLE Readch(Sym) ->C(Sym) %IF 31<=Sym<=54 Fail("Unknown objective ".ItoS(Sym,0)) C(31): {Select <> <>} N = Two Bytes X = Two Bytes %IF N=0<<1+0 %START {code area - i.e. resume} N = Select Code Ca == Code Base %FINISHELSEIF N=1<<1+0 %START {constant area} N = Select Code Ca == Constant Base Ca = X+Total Ca %FINISHELSESTART {gla area} N = Select Gla Ca == Gla Base Ca = X %FINISH Set Loc(N) %CONTINUE C(34): {Byte: [B]} Readch(N); Dump1(N); %CONTINUE C(35): {Dummy} Next Min Fail("Dummy phase error") %UNLESS Item(Min)_Type=McUsed %CONTINUE C(37): {Switch} Lb <- Two signed Bytes; Ub <- Two signed Bytes; X = Two Bytes %FOR N = Lb,1,Ub %CYCLE X = X+1 T == Item(X) Printch(5); Dump2(T_Ca) %REPEAT %CONTINUE C(46): {Word: <>} Dump2(Two Bytes+Bias); Bias = 0 %CONTINUE C(47): {LNB1: <>} N = Two Bytes %IF Attr&Attr Dynamic=0 %START N = N+1 %IF N&7=4 {LNB->DS} %FINISH Dump2(N) %CONTINUE C(48): {LNB2: <>} N = Two Bytes %IF Attr&Attr Dynamic=0 %START N = N+1<<6 %IF N&7<<6=4<<6 {LNB->DS} N = N+1 %IF N&7=4 {LNB->DS} %AND N&k'70'#0 {leave R4 dest alone} %FINISH Dump2(N) %CONTINUE C(54): {LNB10: <>} N = Two Bytes %IF Attr&Attr Dynamic=0 %START N = N+1<<6 %IF N&7<<6=4<<6 %FINISH Dump2(N) %CONTINUE C(38): {Jump: } Readch(Cc) Next Min; T == Item(Min) Jump: %IF T_Flags&Removed=0 %START %IF T_Type=Return %START {jump to return} Fail("Conditional return") %IF Cc#7 Dump Return(B) %FINISHELSESTART Fail("Phase error") %IF %C (Cc#7 %AND T_Type=Uncond) %OR (Cc=7 %AND T_Type=Cond) Cc = Inverted(Cc) %IF T_Flags&Invert#0 N = T_Label_Ca-(Ca+2) {distance to go} %IF T_Flags&Long=0 %START {short branch required} Fail("Stretch error") %UNLESS-256<=N<=254 Dump2(Branch(Cc)+(N>>1)&255) %FINISHELSESTART %IF T_Type=Cond %START {long conditional} Cc = Inverted(Cc) Dump2(Branch(Cc)+2) {skip the long jump} N = N-2 %FINISH Dump2(8_000167); Dump2(N-2) %FINISH %FINISH %FINISH Unreachable = 1 %IF T_Flags&Unreach#0 %CONTINUE C(36): {Call} Next Min; T == Item(Min) %IF Call<=T_Type<=CallP2 %START Dump2(8_004767) {JSR_PC,@??} Ot == T_Label Dump2(T_Label_Ca-(Ca+2)) %CONTINUE %FINISH Cc = 7 {unconditional} ->Jump C(39): {Return} Next Min; T == Item(Min) Fail("Phase error") %UNLESS T_Type=Return Dump Return(B) %UNLESS T_Flags&Removed#0 %CONTINUE C(40): {Line: <>} Printch(Line No) This Line = Two Bytes Put(This Line) %CONTINUE C(42): {External: <>} N = Two Bytes Printch(Pc Reloc) %IF N&1#0 N = N>>1 %CONTINUEIF N=0 Fail("External out of range") %UNLESS N<=Xmax %IF N<=2 %START {local relocation} Bias = Total Ca %IF N=1 Printch(N-1+Code Reloc) %FINISHELSESTART X Reloc(N) %FINISH %CONTINUE C(44): {Block} Phase 3(Two Bytes,Level+1) Set Loc(Select Code) %CONTINUE C(45): {Label: <>} N = Two Bytes T == Item(N) Unreachable = 0 %IF T_Type#OldLab {can get here again} %CONTINUE C(49): {Branch: <> <>} Next Min N = Item(Two Bytes)_Ca-(Ca+2) Fail("Branch cannot reach label") %UNLESS-256<=N<=255 Dump2(Two Bytes+(N>>1)&255) %CONTINUE C(50): {Sob: <> <>} Next Min N = (Ca+2)-Item(Two Bytes)_Ca {Note reversed} Fail("Branch cannot reach label") %UNLESS 0<=N<=127 Dump2(Two Bytes+(N>>1)) %CONTINUE C(51): {Modlab: <> <>} Next Min T == Item(Two Bytes) Dump2(Two Bytes+T_Ca-(Ca+2)) %REPEAT C(33):{End} N = Two Bytes %IF N#0 %START {event mask} Printch(Event Block) Put(N) {events trapped} Put(Item(Two Bytes)_Ca) {event block address} Put(Item(Two Bytes)_Ca) {start of scope} Put(Ca) {end of scope} Event Count = Event Count-8 %FINISH Min = Min-1 %END Section = "" %CYCLE Z == Null Parm List == Null Xmin = Max External+1 Xmax = 2 Xnum = 0 Xmap(SpMove) = 0 Xspec(SpMove) = "P#SPMOVE" Xused(SpMove) = 0 Spec List = 0 Spec End == Spec List This Line = 0 Max = 0 Min = Max Item+1 Order == Null Select Input(Directives); Select Output(0); Phase 1(0) Spec End = 0 Phase 2 Own Size = (Two Bytes+1)&(\1) Constant Size = (Two Bytes+1)&(\1) Events = Two Bytes Event Count = Events Readch(More) More = More-NL {0=no more, 5=more} Get Text(New Section) %IF More#0 Min = Max Item+1 Select Input(Objectives); Select Output(Object); Phase 3(0,-1) Printch(Eof) Select Output(0) Fail("Corrupt events") %IF Event Count#0 Printstring(Section); Spaces(20-Length(Section)) Section = New Section; New Section = "" Printstring("Code"); Write(Total Ca,1) %IF Own Size#0 %START Printstring(" + Gla"); Write(Own Size,1) %FINISH %IF Constant Size#0 %START Printstring(" + Constants"); Write(Constant Size,1) %FINISH %IF Events#0 %START Printstring(" + Events"); Write(Events,1) %FINISH Printstring(" ="); Write(Total Ca+Own Size+Constant Size+Events,1) Printstring(" bytes") Newline %REPEATUNTIL More=0 %ENDOFPROGRAM