! File: LISTC.BLI ! ! This work was supported by the Advanced Research ! Projects Agency of the Office of the Secretary of ! Defense (F44620-73-C-0074) and is monitored by the ! Air Force Office of Scientific Research. ! Module LISTC= Begin ! LISTC MODULE ! ------------ ! ! J. APPERSON ! S. HOBBS ! MODIFIED BY: ! P. KNUEVEN ! Require 'Bliss'; Own CNT : Integer, ALDON : Boolean, DLABEL : Integer; ! THE FOLLOWING SECTION HANDLES LISTING OBJECT CODE External OPERTYPE : Vector[,Byte]; Forward Routine OUTCODE : Novalue, OUTLAB : Novalue, OUTNAME : Novalue, OUTNAMOFF : Novalue, OUTOPD : Novalue, OUTCSECT : Novalue, OUTPLIT : Novalue, OUTSTORAGE : Novalue, OUTGLBINDS : Novalue, OUTVARS : Novalue, OUTDLAB : Novalue, PLACENXTDLAB : Novalue, OUTDNUM : Novalue, ODADR : Novalue, DTYPE, OUTDEBSYMTAB : Novalue, OUTDEBNAMTAB : Novalue; Own PDP11PRT : Vector[75] Initial(AZ( '; UUO', 'MOV', 'MOVB','CMP', 'CMPB', 'BIT', 'BITB', 'BIC', 'BICB','BIS', 'BISB', 'ADD', 'SUB', 'CLR', 'CLRB','COM', 'COMB', 'INC', 'INCB', 'DEC', 'DECB','NEG', 'NEGB', 'ADC', 'ADCB', 'SBC', 'SBCB','TST', 'TSTB', 'ROR', 'RORB', 'ROL', 'ROLB','ASR', 'ASRB', 'ASL', 'ASLB', 'JMP', 'SWAB','JSR', 'RTS', 'HALT','WAIT', 'RTI', 'IOT', 'RESET','EMT', 'TRAP', 'BR', 'BR', 'BNE', 'BEQ', 'BGE', 'BLT','BLE','BGT', 'BPL', 'BMI', 'BHI', 'BLOS', 'BVC', 'BVS','BHIS','BLO', 'NOP', 'CLC', '00243','.WORD','.WORD', 'MFPI','MFPD','MTPI', 'MTPD')); Own REGNAMES : Vector[8] Initial(AZ( 'R0', 'R1', 'R2', 'R3', 'R4', 'R5', 'SP', 'PC') ); Global Routine OUTINST(p : Ref CELL) : Novalue = Begin If .p[cel_code] Eql PINLINE Then Begin If .p[cel_inl_comment] Then Print(AZ('\n;')); Print(AZ('%w\n'),.p[cel_inl_arg]); If .p[cel_inl_comment] Then Print(AZ('\n')) Else Begin NINLINES = .NINLINES+1; CODESIZE = .CODESIZE-129; FINRTNSIZE = .FINRTNSIZE-129 End; Return End; Print(AZ('\t%s\t'),.PDP11PRT[.p[cel_code]]); Case .OPERTYPE[.p[cel_code]] From LO_OPTYPE To HI_OPTYPE Of Set [ OPTYPE_NOP ]: 0; [ OPTYPE_ONE ]: OUTOPD(p[cel_src]); [ OPTYPE_TWO ]: Begin OUTOPD(p[cel_src]); OUTPUT(','); OUTOPD(p[cel_dst]) End; [ OPTYPE_BR ]: OUTOPD(p[cel_src]); [ OPTYPE_JSR ]: Begin Print(AZ('%s,'),.REGNAMES[.p[cel_src_reg]]); OUTOPD(p[cel_dst]) End; [ OPTYPE_RTS ]: Print(AZ('%s'),.REGNAMES[.p[cel_src_reg]]); [ OPTYPE_TRAP ]: PRint(AZ('%d'),.p[cel_src_disp]); [ OPTYPE_WORD ]: OUTNAMOFF(p[cel_src]); [ OPTYPE_CASE ]: Begin OUTNAMOFF(p[cel_src]); OUTPUT('-'); OUTNAMOFF(p[cel_dst]) End Tes; Print(AZ('\n')) End; Routine OUTCODE : Novalue = Begin Local CASEFLAG : Boolean, CODE2 : Integer, L : Ref CELL, CODEPTR : Ref CELL; CASEFLAG = FALSE; If Not .ALDON Then Begin Print(AZ('\t.TITLE %s\n\n'),.MODNAME); If .IDENTFLG Then Begin Print(AZ('\t.IDENT /%s/\n\n'),.IDENTLEX); IDENTFLG = FALSE End; OUTCSECT('C'); CSFLAG = FALSE; Print(AZ('\n')); Incr I From 0 To 7 Do Print(AZ('\t%s = %d\n'),.REGNAMES[.I],.I); ALDON = TRUE End; If .CSFLAG Then Begin Print(AZ('\n')); OUTCSECT('C'); CSFLAG = FALSE; Print(AZ('\n')) End; Print(AZ('\n')); If .swit_debug And Not .MODDONE Then If .CODENAME[4] Neq 0 Then Begin Local RNAME : Ref GT; RNAME = .CODENAME[4]; Print(AZ('\t')); OUTDLAB(.RNAME[st_unique]); Print(AZ('\n')); CODESIZE = .CODESIZE+1; FINRTNSIZE = .FINRTNSIZE+1 End; CODE2 = .CODENAME[2]; If .CODE2 Gtr 0 Then OUTPUT(';'); If .BRAK1[cel_next] Neq .BRAK2 Then Begin Print(AZ('%s:\n'),.CODENAME[0]); If .CODE2 Neq 0 Then Print(AZ('$%D:\n'),Abs(.CODE2)) End; If .MODDONE And .MAINDECL And .SSTKLEN Gtr 0 Then Begin Print(AZ('\tMOV\t#S$TK-2,SP\n')); Print(AZ('\tMOV\t#S$TK,$BREG\n')); CODESIZE = .CODESIZE+5; FINRTNSIZE = .FINRTNSIZE+5 End; CODEPTR = .BRAK1[cel_next]; Until .CODEPTR Eql .BRAK2 Do Begin Case .CODEPTR[cel_type] From LO_CELL_TYPE To HI_CELL_TYPE Of Set [Inrange]: 0; [CELL_CODE]: OUTINST(.CODEPTR); [CELL_LABEL]: Begin L = .CODEPTR[cel_next]; If .swit_i_d And .L[cel_type] Eql CELL_CODE And .L[cel_code] Eql PCASE Then Begin CASEFLAG = TRUE; OUTCSECT('G'); Print(AZ('\n')) End; OUTLAB(.CODEPTR); OUTPUT(':') End Tes; CODEPTR = .CODEPTR[cel_next]; If .CASEFLAG And Not .CODEPTR[cel_type] Eql CELL_CODE Then Begin CASEFLAG = FALSE; OUTCSECT('C'); Print(AZ('\n')) End End; Print(AZ('\n')); If .swit_statistics And Not .flg_tty And .FINRTNSIZE Gtr 0 Then Print(AZ('%b%1m%s %d\n%e'),.CODENAME[0],.FINRTNSIZE); If .swit_debug Then If .CODE2 Neq 0 Then Print(AZ('$$%d:\n'),Abs(.CODE2)) Else Print(AZ('$%s:\n'),.CODENAME[0]); If .FINRTNSIZE Gtr 0 Then Print(AZ('; ROUTINE SIZE: %d\n'),.FINRTNSIZE) End; Routine OUTLAB(LAB : Ref CELL) : Novalue = Begin Case .LAB[cel_lab_type] From LO_LAB_TYPE To HI_LAB_TYPE Of Set [LAB_ROUTINE]: Print(AZ('$%s'),NT[.ST[.LAB[cel_lab_name],st_name],nt_data]); [LAB_USER]: Begin OUTNAME(.LAB[cel_lab_name]); ST[.LAB[cel_lab_name],st_lab_used] = TRUE End; [LAB_COMP]: Print(AZ('L%d'),.LAB[cel_lab_name]) Tes End; Routine OUTNAME(S : Ref ST) : Novalue = Begin If .S[st_v_unique] Then If ONEOF(.S[gt_type],S_LABEL,S_OWN,S_ROUTINE,S_GBL_ROUTINE,S_FORWARD) Then Print(AZ('$%d'),.S[st_unique]) Else Print(AZ('%s'),NT[.S[st_name],nt_data]) Else Print(AZ('%s'),NT[.S[st_name],nt_data]) End; Routine OUTNAMOFF(OPRND : Ref ADRVARSTR) : Novalue = Begin If .OPRND[adr_name] Gtr 1 Then Begin If .OPRND[adr_name_type] Eql NAME_NORMAL Then OUTNAME(.OPRND[adr_name]) Else If .OPRND[adr_name_type] Eql NAME_LABEL Then OUTLAB(.ST[.OPRND[adr_name],cel_ref_ef]) Else Print(AZ('$TN')); If .OPRND[adr_disp] Eql 0 Then Return Else If .OPRND[adr_disp] Gtr 0 Then OUTPUT('+') Else OUTPUT('-'); Print(AZ('%d'),Abs(.OPRND[adr_disp])) End Else If .OPRND[adr_type] Eql ADDR_IMMED Then Print(AZ('%d'),.OPRND[adr_disp]) Else Begin If .OPRND[adr_disp] Lss 0 Then OUTPUT ('-'); Print(AZ('%d'),Abs(.OPRND[adr_disp])) End End; Routine OUTOPD(OPRND : Ref ADRVARSTR) : Novalue = Begin Local XMODE; XMODE = .OPRND[adr_mode]; If .XMODE Then OUTPUT('@'); XMODE<0,1> = 0; If .XMODE Eql GENREG Then Print(AZ('%s'),.REGNAMES[.OPRND[adr_reg]]) Else If .OPRND[adr_reg] Neq 7 Then Selectone .XMODE Of Set [AUTODECR]: Print(AZ('-(%s)'),.REGNAMES[.OPRND[adr_reg]]); [INDEXED]: Begin OUTNAMOFF(.OPRND); Print(AZ('(%s)'),.REGNAMES[.OPRND[adr_reg]]) End; [AUTOINCR]: Print(AZ('(%s)+'),.REGNAMES[.OPRND[adr_reg]]); Tes Else Begin If .XMODE Eql IMMEDIATE Then OUTPUT('#'); OUTNAMOFF(.OPRND) End End; Routine OUTNAMEDISP(S : Ref ST) : Novalue = Begin Local B : Ref ST, N; If .S[st_v_namexp] Then Begin B = .S[st_var_base]; N = .S[gt_disp]-.B[gt_disp]; If .N Neq 0 Then Print(AZ('%c%d'),If .N Gtr 0 Then '+' Else '-',Abs(.N)) End End; Routine OUTCSECT(X) : Novalue = Begin Local FLAG : Ref Vector[,Byte], NAME : Ref Vector[,Byte]; Own SECTPLIT : Vector[6*3] Initial( 'C',CSCFLG,CSCNAME, 'G',CSGFLG,CSGNAME, 'O',CSOFLG,CSONAME, 'P',CSPFLG,CSPNAME, 'S',CSDFLG,CSDNAME, 'N',CSDFLG,CSDNAME); Incr I From 0 To 5*3 By 3 Do If .SECTPLIT[.I] Eql .X Then Begin FLAG = .SECTPLIT[.I+1]; NAME = .(.SECTPLIT[.I+2]); Exitloop End; Case .FLAG[0] From 0 To 2 Of Set [ 0 ]: Begin If .CSFLG Leq 1 Then Print(AZ('\t.CSECT ')) Else Print(AZ('\t.PSECT ')); Print(AZ('%s.%c'),.CSNAME,.X) End; [ 1 ]: Print(AZ('\t.CSECT %w'),.NAME); [ 2 ]: Print(AZ('\t.PSECT %w'),.NAME) Tes End; Routine OUTPLIT(NAM : Ref ST,PP : Ref ST) : Novalue = Begin Local NL : Ref ST, LEX : Ref GT, NPAD; Routine OUTSEP : Novalue = Begin CNT = .CNT + 1; If .CNT Geq 3 Then Begin CNT = 0; Print(AZ('\n\t.WORD\t')) End Else If .CNT Neq 0 Then OUTPUT(',') End; If .NAM Neq 0 Then Begin If .NAM[st_v_counted] Then Print(AZ('\t.WORD\t%d\n'),.PP[plit_length]); OUTNAME(.NAM); Print(AZ(':\t.WORD\t')); CNT = -1 End; NL = .PP[cel_top]; Until .NL Eql .PP Do Begin If .NL[cel_type] Eql PL_DUPLICATOR Then Incr I From 1 To .NL[plit_replicator] Do OUTPLIT(0,.NL) Else Begin LEX = .NL[plit_lexeme]; Case .LEX From T_LITERAL To T_STRING_L Of Set [Inrange,Outrange]: 0; ! DELIMITER [T_LITERAL]: Begin OUTSEP(); PRint(AZ('%d'),.LEX) End; [T_SYMBOL]: Begin OUTSEP(); OUTNAME(.LEX); OUTNAMEDISP(.LEX) End; [T_STRING_L]: OUTPLIT(0,.LEX) Tes End; NL = .NL[cel_next] End; If .NAM Neq 0 Then Begin Print(AZ('\n')); NPAD = .NAM[st_var_size]-.PP[plit_length]*2; If .NPAD Gtr 0 Then Print(AZ('\t. = . + %d\n'),.NPAD) End End; Routine OUTSTORAGE(TYPE : Integer,REGION : Integer,MUSTBEPLIT : Boolean) : Novalue = Begin Local BYT : Integer, DOLABEL : Boolean, L : Ref GT, P : Ref ST, R : Ref ST; Label aaa; DOLABEL = TRUE; BYT = 0; R = .PURGED; While (P = .R) Neqa 0 Do aaa: Begin R = .P[st_next]; If .P[gt_type] Neq .TYPE Then Leave aaa; If .P[st_v_printed] Then Leave aaa; If .P[st_v_plit] Neq .MUSTBEPLIT Then Leave aaa; If .DOLABEL Then Begin OUTCSECT(.REGION); CSFLAG = TRUE; Print(AZ('\n')); DOLABEL = FALSE End; L = .P[gt_len]; If .BYT And .L Mod WRDSZ Eql 0 Then Begin Print(AZ('\t.EVEN\n')); BYT = 0 End; If .P[st_v_init] Then OUTPLIT(.P,.P[st_var_init]) Else Begin OUTNAME(.P); Print(AZ(':\t. = . + %d\n'),.P[st_var_size]) End; BYT = .BYT+.P[st_var_size]; If .P[st_v_plit] And .P[st_v_counted] Then BYT = .BYT+2; P[st_v_printed] = TRUE End; If .BYT Then Print(AZ('\t.EVEN\n')); If .MODDONE And .MAINDECL And .REGION Eql 'G' Then Begin If .DOLABEL Then Begin OUTCSECT('G'); CSFLAG = TRUE; Print(AZ('\n')) End; Print(AZ('%n:\t. = . + 2\n'),.LEXBREG) End End; Routine OUTGLBINDS : Novalue = Begin Local LEX : Ref GT, PUR : Ref ST; PUR = .PURGED; While .PUR Neqa 0 Do Begin If .PUR[gt_type] Eql S_BIND And .PUR[st_v_gbl_bind] Then Begin Print(AZ('%n\t=\t'),.PUR); LEX = .PUR[st_bind_data]; If .LEX Eql T_LITERAL Then Print(AZ('%d'),.LEX) Else Begin OUTNAME(.LEX); OUTNAMEDISP(.LEX) End; Print(AZ('\n\t.GLOBL\t%s\n'),NT[.PUR[st_name],nt_data]) End; PUR = .PUR[st_next] End End; Routine OUTVARS : Novalue = Begin Local SAVPTR : Ref ST; Bind OUTL=PLIT( LEXMUL,LEXDIV,LEXMOD,LEXROT,LEXSHIFT, LEXCREATE,LEXEXCHJ, LXSIGV,LXSIGR,LXSIGL,LXSIG1,LXENAB, LXSAV2,LXSAV3,LXSAV4,LXSAV5, LXINT612,LXE612,LXX612,LXY612, LXHLNK,LXHLTB,LXIHLNK ) : Vector; Print(AZ('\n')); ! output own storage OUTSTORAGE(S_OWN,'O',FALSE); If .NEXTOWN Then NEXTOWN = .NEXTOWN+1; ! output global storage OUTSTORAGE(S_GLOBAL,'G',FALSE); If .NEXTGLOBAL Then NEXTGLOBAL = .NEXTGLOBAL+1; ! output plits OUTSTORAGE(S_OWN,'O',TRUE); OUTSTORAGE(S_GLOBAL,'P',TRUE); ! output global binds OUTGLBINDS(); SAVPTR = .PURGED; While .SAVPTR Neqa 0 Do Begin If ONEOF(.SAVPTR[gt_type],S_EXTERNAL,S_GLOBAL,S_GBL_ROUTINE) Then If Not (.SAVPTR[st_v_listed_external] Or .SAVPTR[st_v_plit] Or .SAVPTR[st_v_namexp]) Then Begin Print(AZ('\t.GLOBL\t%s\n'),NT[.SAVPTR[st_name],nt_data]); SAVPTR[st_v_listed_external] = TRUE End; SAVPTR = .SAVPTR[st_next] End; If .PURGED Neqa 0 Then Print(AZ('\n')); If .MODDONE Then Begin DATASIZE = .DATASIZE+(.NEXTOWN+.NEXTGLOBAL)/2; Decr I From .OUTL[-1]-1 To 0 Do Begin SAVPTR = ..OUTL[.I]; If .SAVPTR[st_v_listed_external] Then Begin Print(AZ('\t.GLOBL\t%s\n'),NT[.SAVPTR[st_name],nt_data]); SAVPTR[st_v_listed_external] = FALSE End End; If .MAINDECL Then Print(AZ('\t.GLOBL\t%s\n'),NT[.LEXBREG[st_name],nt_data]); End; If .MODDONE And .MAINDECL Then Begin If .SSTKLEN Gtr 0 Then Begin Print(AZ('\t.ASECT\n')); Print(AZ('\t. = 400\n')); Print(AZ('\t. = . + %d\n'),2 * .SSTKLEN); Print(AZ('S$TK\t= . - 2\n\n')); DATASIZE = .DATASIZE+.SSTKLEN End End End; Routine OUTDLAB(L) : Novalue = Begin If .L Eql 0 Then Print(AZ('+0')) Else Print(AZ('D$%d'),.L) End; Routine PLACENXTDLAB(L : Ref GT) : Novalue = Begin DLABEL = .L[st_v_unique]; OUTDLAB(.DLABEL); OUTPUT(':') End; Routine OUTDNUM(X) : Novalue = Begin Print(AZ(',%d'),.X<0,15>) End; Routine ODADR(X) : Novalue = Begin OUTPUT(','); OUTNAME(.X) End; ! calculate the debugger data type ! ! 0 unrecognized ! 1 module name ! 2 routine ! 3 own ! 4 global ! 5 local ! 6 local in a register ! 7 register ! 8 bind to name/literal ! 9 label ! 10 unused ! 11 linkage ! 12 structure ! 13 macro ! 14 bind to expression ! 15 bind to expression in a register ! 16 formal ! 17 formal in a register Routine DTYPE(L : Ref GT) = Begin Local X : Ref GT, N : Ref NT; Selectone .L[gt_type] Of Set [S_ROUTINE]: Return 2; [S_GBL_ROUTINE]: Return 2; [S_OWN]: Return 3; [S_GLOBAL]: Return (If .L[st_v_plit] Then 0 Else 4); [S_LOCAL]: Return 5; [S_REGISTER]: Return 7; [S_BIND]: Begin X = .L[st_bind_data]; If .X Eql T_LITERAL Then Return 0; ! USED TO BE 8 If .X Eql T_NODE Then Return 14; If .X[st_v_namexp] Then Return (If .X[gt_reg] Eql SP Then DTYPE(.X)+(-1)^32 Else 8); Return 0 End; [S_LABEL]: Begin If Not .L[st_lab_used] Then Return 0; If .NT[.L[st_name],nt_data] Eql '$' Then Return 0; Return 9 End; [S_FORMAL]: Return 16; [Otherwise]: Return 0 Tes End; Routine OUTDEBSYMTAB : Novalue = Begin Local L : Ref ST, M : Ref ST, NAME : Ref GT, T : Ref GT, LT : Ref GT, PC; Macro OUTLINKTB= Begin Print(AZ(',%s'),NT[.LXHLTB[st_name],nt_data]) End %; Label aaa; Routine BITCOUNT(N : Integer) = ! COUNT THE ONE BITS Begin Local COUNT : Integer; COUNT = 0; While .N Neq 0 Do Begin If .N Then COUNT = .COUNT+1; N = .N^(-1) End; Return .COUNT End; If Not .swit_debug Then Return; M = L = .PURGED; PC = -1; While .L Neqa 0 Do Begin T = DTYPE(.L); If .T Neq 0 Then aaa: Begin If .L[st_v_namexp] Or Not .L[st_v_debug] Then Leave aaa; If .T Lss 0 Then ! LEFT HALF SET BY DTYPE Begin T = .T; L = .L[st_bind_data] End; If .PC Neq 0 Then Begin OUTCSECT('S'); CSFLAG = TRUE; PC = 0 End; Print(AZ('\n')); PLACENXTDLAB(.M); Print(AZ('\t')); Selectone .T Of Set [5]: If .L[st_var_reg_index] Neq SP Then T = 6; [14]: If .L[st_var_reg_index] Eql SP Then T = 15; [16]: If .L[gt_reg] Neq SP Then T = 17 Tes; NAME = .M[st_name]; OUTDLAB(.NAME[nt_debug]); NAME[nt_debug] = .DLABEL; OUTDNUM(.M[st_unique]); OUTDNUM(.T); Print(AZ('\n\t')); If .MODDONE Then OUTPUT('0') Else OUTDLAB(Abs(.CODENAME[3])); Case .T From 0 To 17 Of Set [Inrange]: 0; [2]: Begin ODADR(.L); OUTLINKTB; Print(AZ('\n\t$')); OUTNAME(.L); OUTPUT('-'); OUTNAME(.L); OUTDNUM(.L[st_rout_argc]+.L[st_var_reg_save]^8); OUTDNUM(.GT[.L[st_var_linkage],st_lnk_type]) End; [3]: ! own Begin ODADR(.L); OUTLINKTB; Print(AZ('\n\t%d'),.L[st_var_size]) End; [4]: ! global Begin Print(AZ(',%s'),NT[.L[st_name],nt_data]); OUTLINKTB; Print(AZ('\n\t%d'),.L[st_var_size]) End; [5]: ! stack local Begin T = .CODENAME[4]; If .T Neq 0 Then T = BITCOUNT(.T[st_var_reg_save]); ! NOTE TO WHOEVER PUT IN THAT CODE FOR ! THE $SAV-N PC WORD: DEBSW *FORCES* ! INLINE REGISTER SAVING. -TL OUTDNUM(.L[gt_disp]-(.T+.VTN)*2); OUTDNUM(0); Print(AZ('\n\t%d'),.L[st_var_size]) End; [6]: ! register local OUTDNUM(.L[st_var_reg_index]); [7]: ! register OUTDNUM(.L[st_var_reg_index]); [8]: ! simple bind Begin LT = .L[st_bind_data]; If .LT Eql T_LITERAL Then OUTDNUM(.LT) Else Begin OUTPUT(','); OUTNAME(.LT); OUTNAMEDISP(.LT) End End; [9]: ! label Begin ODADR(.L); OUTLINKTB End; [14]: ! dynamic bind in a register OUTDNUM(.L[st_var_reg_index]); [15]: ! dynamic bind in a stack temporary Begin T = .CODENAME[4]; If .T Neq 0 Then T = BITCOUNT(.T[st_var_reg_save]); OUTDNUM(.L[gt_disp]-(.T+.VTN)*2); End; [16]: ! stack formal OUTDNUM(.L[gt_disp]); [17]: ! register formal OUTDNUM(.L[st_var_reg_index]) Tes End; M = L = .M[st_next] End End; Routine OUTDEBNAMTAB : Novalue = Begin Local L : Ref ST, PC : Boolean; If Not .MODDONE Then Return; If Not .swit_debug Then Return; PC = TRUE; Print(AZ('\n')); Incr I From 0 To 124 Do Begin L = .HT_NAME[.I]; While .L Neqa 0 Do Begin If .L[nt_debug] Neq 0 Then Begin If .PC Then Begin Print(AZ('\n')); If .swit_list And Not .flg_tty Then ! MUST NOT CROSS PAGE If .NLINES Gtr 44 Then PAGE(); OUTCSECT('N'); CSFLAG = TRUE; PC = FALSE; Print(AZ('\n\n.MACRO $NTE X,Y\n')); Print(AZ('\t.RAD50 /X/\n')); Print(AZ('\t.WORD Y\n')); Print(AZ('\t.ENDM\n\n')); Print(AZ('$NMTAB:')) End; Print(AZ('\n\t$NTE\t')); Print(AZ('^''%s'''),.l); OUTPUT(','); OUTDLAB(.L[nt_debug]); L[nt_debug] = 0 End; L = .L[nt_next] End End End; Global Routine FINALDRIV : Novalue = Begin Local SAVLST : Boolean; FINAL(); SAVLST = .swit_list; swit_list = TRUE; !ALWAYS LIST CODE OUTCODE(); ERASELIST(.NLHEAD); ERASEDET(.NLHEAD); ERASELIST(.BRAK1); ERASEDET(.BRAK1); OUTVARS(); OUTDEBSYMTAB(); OUTDEBNAMTAB(); swit_list = .SAVLST End; End Eludom