$title ('DECODE LINE MODULE') decodel: do; /* modified 3/26/81 R. Silberstein modified 3/30/81 R. Silberstein modified 4/9/81 R. Silberstein modified 4/10/81 R. Silberstein modified 7/24/81 R. Silberstein */ /* This is the module to decode each logical sourceline. The module takes care of all symbol definitions, and activates the PSEUDO-module and the INSTRUCTION-module to perform the assembly of the current non-empty source- line. */ $include (:f1:macro.lit) $include (:f1:struc.lit) $include (:f1:equals.lit) $include (:f1:ermod.lit) $include (:f1:subr1.ext) $include (:f1:subr2.ext) $include (:f1:scan.ext) $include (:f1:print.ext) $include (:f1:instr.ext) $include (:f1:pseud1.ext) $include (:f1:pseud2.ext) $include (:f1:ermod.ext) $include (:f1:symb.ext) $include (:f1:exglob.ext) $include (:f1:dline.x86) $include (:f1:cm.ext) saveaccum: proc; acclensave=acclen; call copy(acclen,.accum(0),.accumsave(0)); end saveaccum; exchangeaccum: proc; dcl locacclen byte,locaccum(80) byte; locacclen=acclensave; call copy(acclensave,.accumsave(0),.locaccum(0)); call saveaccum; acclen=locacclen; call copy(locacclen,.locaccum(0),.accum(0)); end exchangeaccum; clearsymbol: proc; CALL FILL (0, .CURRENTSYMBOL.BASEINDEX-.CURRENTSYMBOL+1, .CURRENTSYMBOL); end clearsymbol; pseudotype: proc(lg,ptr) byte; dcl (lg,i,lvalue) byte,ptr address,pstable based ptr (1) byte; if token.type <> pseudo then return lg+1; i=0ffh; do while (i:=i+1) < lg; lvalue=token.value; if lvalue=pstable(i) then$do call scan; /* skip found pseudo */ return i; end$if; end$while; return i; end pseudotype; /* test if symbol if double defined or "neglected" symbol */ not$doub$negl: proc(errno) byte; dcl (errno,errfl) byte; if pass = 0 then$do if findsymbol(acclensave,.accumsave,.symbtabadr) then$do call getattributes(symbtabadr,.currentsymbol); if currentsymbol.stype <> neglected then$do currentsymbol.stype=doubledefined; call enterattributes(symbtabadr,.currentsymbol); end$if; return false; end$if; else$do /* pass 1 and pass 2 */ if not findsymbol(acclensave,.accumsave,.symbtabadr) then return false; call getattributes(symbtabadr,.currentsymbol); errfl=true; if currentsymbol.stype=neglected then$do errno=neglecterr; else$do if currentsymbol.stype<>doubledefined then errfl=false; end$if; if errfl then$do call exchangeaccum; call errmsg(errno); call exchangeaccum; return false; end$if; end$if; return true; end not$doub$negl; newsym: proc byte; /* enter new symbol into table */ if pass=0 then$do if not newsymbol(acclensave,.accumsave,.symbtabadr) then$do fullsymbtab=true; return false; end$if; end$if; return true; end newsym; /* set up symbol attributes for label,DB,DW,DD,RS */ setupattr: proc (styp,sfla); dcl (styp,sfla,segtyp) byte; segtyp=shl(csegtype,segtypecount) and segtypebit; currentsymbol.stype=styp; if csegspec then sfla=sfla or segmbit; currentsymbol.sflag=sfla or segtyp; currentsymbol.segment=csegvalue; currentsymbol.offset=cip; end setupattr; entatr: proc; /* enter attributes of current symbol into table */ if pass <> 2 then$do call enter$attributes(symbtabadr,.currentsymbol); end$if; end entatr; /* decode instruction */ decodeinstr: proc; if csegtype <> rcs then$do call errmsg(instrerr); call skip$rest$of$line; else$do CALL LISTCIP; call instruction; /* decode instruction */ end$if; end decodeinstr; labinstruction: proc; /* scan labelled instruction */ dcl symb based codemacroptr symbolstruc; call saveaccum; /* enter label into symbol table */ if not$doub$negl(doubledeflab) then$do if newsym then$do call setupattr(lab,wrd); call entatr; end$if; end$if; call scan; /* skip ":" */ call scan; /* allow empty instruction */ if emptyline then$do call skip$rest$of$line; else$do if findcodemacro(acclen,.accum(0),.codemacroptr) then$do call scan; /* skip codemacro */ call decode$instr; else$do call errmsg(illegalmacro); end$if; end$if; end labinstruction; no$ident$pseudo: proc; /* branch to correct pseudo routine */ dcl ptable(*) byte data( /* define legal unnamed pseudos */ pif,pendif,pinclude,pcseg,pdseg,psseg,peseg,porg,pdb, pdw,pdd,prb,prs,prw,pend,ppagesize,ppagewidth, ptitle,peject,psimform,pcodemacro,plist,pnolist,PIFLIST,PNOIFLIST, psegfix,pnosegfix,pmodrm,prelb,prelw,pdbit,pendm); do case pseudotype(length(ptable),.ptable); /* branch */ call IFrout; call ENDIFrout; call INCLUDErout; call CSEGrout; call DSEGrout; call SSEGrout; call ESEGrout; call ORGrout; if codemacro$flag then call db$cm$rout; else call DBrout; if codemacro$flag then call dw$cm$rout; else call DWrout; if codemacro$flag then call dd$cm$rout; else call DDrout; call RSrout(byt); /* RB */ call RSrout(byt); /* RS */ call RSrout(wrd); /* RW */ call ENDrout; call PAGESIZErout; call PAGEWIDTHrout; call TITLErout; call EJECTrout; call SIMFORMrout; call CODEMACROrout; call LISTrout; call NOLISTrout; CALL IFLISTROUT; CALL NOIFLISTROUT; call segfix$cm$rout; /* cm */ call nosegfix$cm$rout; /* cm */ call modrm$cm$rout; /* cm */ call relb$cm$rout; /* cm */ call relw$cm$rout; /* cm */ call dbit$cm$rout; /* cm */ call end$cm$rout; /* cm */ do; /* error, illegal pseudo */ call errmsg(illegalpseudo); call skip$rest$of$line; end; end$case; end no$ident$pseudo; identpseudo: proc(normal); /* scan a named pseudo instruction */ dcl (noerr,normal) byte,symb based codemacroptr symbolstruc; entervar: proc(typ); dcl typ byte; noerr=false; if not$doub$negl(doubledefvar) then$do if newsym then$do call setupattr(variable,typ); noerr=true; end$if; end$if; end entervar; enter: proc; if noerr then call entatr; end enter; /* legal pseudos: DB,DW,DD,RB,RS,RW,EQU */ dcl pseudotable(7) byte data(pdb,pdw,pdd,prb,prs,prw,pequ); call clearsymbol; /* clear attributes of current symbol */ if normal then$do /* unormal if EQU with instruction parameter */ call saveaccum; call scan; /* scan actual pseudo */ end$if; do case pseudotype(length(pseudotable),.pseudotable); do; /* DB */ call entervar(byt); call DBrout; call enter; end; do; /* DW */ call entervar(wrd); call DWrout; call enter; end; do; /* DD */ call entervar(dwrd); call DDrout; call enter; end; do; /* RB */ call entervar(byt); call RSrout(byt); call enter; end; do; /* RS */ call entervar(byt); call RSrout(byt); call enter; end; do; /* RW */ call entervar(wrd); call RSrout(wrd); call enter; end; do; /* EQU */ if not$doub$negl(doubledefsymb) then$do if newsym then$do call EQUrout; else$do call skip$rest$of$line; end$if; else$do call skip$rest$of$line; end$if; end; do; /* illegal pseudo instruction */ call errmsg(illegalpseudo); call skip$rest$of$line; end; do; /* missing pseudo instruction */ call errmsg(missingpseudo); call skip$rest$of$line; end; end$case; end identpseudo; decodeline: proc public; first$item$type: proc byte; dcl typ byte; typ=token.type; if typ=pseudo then return 3; if typ=ident and nextch=':' then return 2; if (typ=ident) or (typ=operator) then$do if findcodemacro(acclen,.accum(0),.codemacroptr) then$do call saveaccum; call scan; /* skip found codemacro */ typ=token.value; if (token.type=pseudo) and (typ=pequ) then return 5; return 4; end$if; end$if; if typ <> ident then return 0; /* error */ return 1; end first$item$type; if accum(0) <> cr then$do /* skip blank lines */ do case first$item$type; do; /* error,skip rest of line */ call errmsg(first$item); /* error handler */ call skip$rest$of$line; end; call ident$pseudo(true); /* named pseudo instruction */ call lab$instruction; /* label (followed by instruction) */ call no$ident$pseudo; /* pseudo instruction */ call decodeinstr; /* code instruction */ call identpseudo(false); /* EQU with instruction parameter */ end$case; end$if; end decodeline; end$module decodel;