summaryrefslogtreecommitdiffstats
path: root/private/sdktools/masm/asmdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/sdktools/masm/asmdata.c')
-rw-r--r--private/sdktools/masm/asmdata.c1317
1 files changed, 1317 insertions, 0 deletions
diff --git a/private/sdktools/masm/asmdata.c b/private/sdktools/masm/asmdata.c
new file mode 100644
index 000000000..3d177f26c
--- /dev/null
+++ b/private/sdktools/masm/asmdata.c
@@ -0,0 +1,1317 @@
+/* asmdata.c -- microsoft 80x86 assembler
+**
+** microsoft (r) macro assembler
+** copyright (c) microsoft corp 1986. all rights reserved
+**
+** randy nevin
+**
+** 10/90 - Quick conversion to 32 bit by Jeff Spencer
+*/
+
+#include <stdio.h>
+#include "asm86.h"
+#include "asmfcn.h"
+#include <ctype.h>
+#include "asmindex.h"
+#include "asmctype.h"
+#include "asmmsg.h"
+
+extern UCHAR mpRealType[];
+
+/* Dup tree is organized left to right horizonatally for each
+ item in a DUP list at the same level( i. e. 5 DUP(1,2,3) ).
+ This is considered the 'list' part. Any item in the list
+ may be another DUP header instead of a data entry, in
+ which case you go down a level and have another list.
+ */
+
+
+char uninitialized[10];
+char fInDup;
+
+
+/*** scanstruc - scan structure tree and execute function
+ *
+ * scanstruc (dupr, disp);
+ *
+ * Entry *dupr = duprec structure entry
+ * disp = pointer to function to execute at each node
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+scanstruc (
+ struct duprec FARSYM *dupr,
+ VOID (PASCAL CODESIZE *disp) (struct duprec FARSYM *)
+){
+ struct duprec FARSYM *ptr;
+ struct duprec FARSYM *iptr;
+ struct duprec FARSYM *fldptr;
+ struct duprec FARSYM *initptr;
+ OFFSET strucpc;
+
+ /* save starting address of structure */
+ strucpc = pcoffset;
+ if (dupr)
+ /* Output <n> DUP( */
+ (*disp) (dupr);
+ /* 1st default value for STRUC */
+ fldptr = recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->duptype.dupnext.dup;
+ /* 1st initialize value */
+ initptr = strucoveride;
+ if (initptr) {
+ /* process initialization fields for structure */
+ while (fldptr) {
+ if (fldptr->itemcnt == 1 && fldptr->duptype.dupnext.dup->itemcnt == 0
+ && initptr->duptype.dupitem.ddata)
+ /* Use default */
+ ptr = initptr;
+ else
+ /* Can't override field */
+ ptr = fldptr;
+ iptr = ptr->itemlst;
+ ptr->itemlst = NULL;
+ if (displayflag && !dupr) {
+ offsetAscii (strucpc);
+ listindex = 1;
+ /* Display PC */
+ copyascii ();
+
+ listindex = LSTDATA;
+ if (highWord(strucpc))
+ listindex += 4;
+ }
+ if (ptr->rptcnt > 1 || ptr->itemcnt > 1)
+ /* Output <n> DUP( */
+ (*disp) (ptr);
+ /* Display field */
+ scanlist (ptr, disp);
+ if (ptr->rptcnt > 1 || ptr->itemcnt > 1)
+ enddupdisplay ();
+ if (displayflag && !dupr) {
+ /* Calc size of field */
+ clausesize = calcsize (ptr);
+ if (dupr)
+ clausesize *= dupr->rptcnt;
+ strucpc += clausesize;
+ }
+ /* Restore */
+ ptr->itemlst = iptr;
+ if (displayflag && (listbuffer[LSTDATA] != ' ' ||
+ listbuffer[14] != ' ')) {
+
+ resetobjidx ();
+ }
+ /* Advance default field */
+ fldptr = fldptr->itemlst;
+ /* Advance override field */
+ initptr = initptr->itemlst;
+ }
+ }
+ if (dupr)
+ enddupdisplay ();
+}
+
+
+
+
+
+/*** scandup - scan DUP tree and execute function
+ *
+ * scandup (tree, disp);
+ *
+ * Entry *tree = DUP tree
+ * *disp = function to execute at each node of tree
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+scandup (
+ struct duprec FARSYM *tree,
+ VOID (PASCAL CODESIZE *disp)(struct duprec FARSYM *)
+){
+ if (tree)
+ if (strucflag && initflag)
+ /* Want to skip STRUC heading */
+ if (tree == recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody)
+
+ /* This is not <n> DUP(<>) So no DUP prefix */
+
+ scanstruc ((struct duprec FARSYM *)NULL, disp);
+
+ else { /* must set itemcnt in DUP to # fields */
+
+ tree->itemcnt = recptr->symu.rsmsym.rsmtype.rsmstruc.strucfldnum;
+ scanstruc (tree, disp);
+ }
+ else /* Else is not STRUC */
+
+ scanlist (tree, disp);
+}
+
+
+
+
+/*** oblitdup - delete DUP entry
+ *
+ * oblitdup (node);
+ *
+ * Entry *node = DUP entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+oblitdup (
+ struct duprec FARSYM *node
+){
+ switch (node->dupkind) {
+ case NEST:
+ _ffree ((char FARSYM *)node);
+ break;
+ case ITEM:
+ if (node->duptype.dupitem.ddata)
+ dfree ((char *)node->duptype.dupitem.ddata );
+ _ffree ((char FARSYM *)node);
+ break;
+ case LONG:
+ if (node->duptype.duplong.ldata != uninitialized)
+ free ((char *)node->duptype.duplong.ldata);
+
+ _ffree ((char FARSYM *)node);
+ break;
+ default:
+ TERMINATE(ER_FAT, 99);
+ }
+}
+
+
+
+
+/*** displlong - display long constant
+ *
+ * displaylong (dup);
+ *
+ * Entry *dup = dup entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+displlong (
+ struct duprec FARSYM *dup
+){
+ register USHORT cnt;
+ register char *p;
+
+ p = dup->duptype.duplong.ldata;
+
+ for (cnt = dup->duptype.duplong.llen; cnt; cnt--) {
+
+ if (optyp == TDW || optyp == TDD)
+
+ emitopcode ((UCHAR)p[cnt-1]);
+ else
+ emitopcode ((UCHAR)*p++);
+
+ if (optyp != TDB)
+ listindex--;
+ }
+ if (optyp != TDB)
+ listindex++;
+}
+
+
+
+
+/*** begdupdisplay - begin DUP display
+ *
+ * begdupdisplay (dup);
+ *
+ * Entry *dup = DUP entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+begdupdisplay (
+ struct duprec FARSYM *dup
+){
+ /* flush line if data already displayed */
+
+ if ((highWord(pcoffset) && listbuffer[LSTDATA+3] != ' ') ||
+ listbuffer[LSTDATA] != ' ')
+
+ resetobjidx ();
+
+ listindex = LSTDATA + duplevel; /* Indent for DUP clause */
+ if (highWord(pcoffset))
+ listindex += 4;
+
+ offsetAscii (dup->rptcnt); /* display repeat count in four bytes */
+ copyascii ();
+ listbuffer[listindex] = '[';
+ duplevel++; /* Indent another level */
+ resetobjidx (); /* Display DUP repeat line */
+}
+
+
+
+
+/*** enddupdisplay - end DUP display
+ *
+ * enddupdisplay ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+VOID PASCAL CODESIZE
+enddupdisplay (
+){
+ if (duplevel) {
+ duplevel--;
+
+ if (displayflag) {
+ listbuffer[LSTMAX - ((duplevel <= 8)? duplevel: 8)] = ']';
+ resetobjidx ();
+ }
+ }
+}
+
+
+/*** itemdisplay - display DUP data item
+ *
+ * itemdisplay (dup);
+ *
+ * Entry *dup = dup record
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+itemdisplay (
+ struct duprec FARSYM *dup
+){
+ if (listindex > LSTMAX)
+ resetobjidx ();
+
+ if (dup->dupkind == ITEM)
+
+ emitOP (&dup->duptype.dupitem.ddata->dsckind.opnd);
+ else
+ displlong (dup);
+
+ if (duplevel)
+ resetobjidx ();
+}
+
+
+
+
+/*** dupdisplay - display DUP item on listing
+ *
+ * dupdisplay (ptr);
+ *
+ * Entry *ptr = DUP entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+dupdisplay (
+ struct duprec FARSYM *ptr
+){
+ if (ptr->dupkind == NEST)
+ begdupdisplay (ptr);
+ else
+ itemdisplay (ptr);
+}
+
+
+
+
+/*** linkfield - add item to list of DUP for current STRUC
+ *
+ * linkfield (nitem);
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+linkfield (
+ struct duprec FARSYM *nitem
+){
+ struct duprec FARSYM *ptr;
+
+ if (strucprev->itemcnt++ == 0)/* 1st item in field */
+ strucprev->duptype.dupnext.dup = nitem;
+ else {
+ ptr = strucprev->duptype.dupnext.dup;
+ while (ptr->itemlst)
+ ptr = ptr->itemlst;
+ /* Add to end of list */
+ ptr->itemlst = nitem;
+ }
+}
+
+
+
+/*** longeval - evaluate long non-floating point, non-BCD constant
+ *
+ * longeval (base, p);
+ *
+ * Entry delim = delimiter character
+ * Exit
+ * Returns
+ * Calls
+ */
+
+#if !defined FLATMODEL
+# pragma alloc_text (FA_TEXT, longeval)
+#endif
+
+VOID PASCAL
+longeval (
+ USHORT base,
+ register struct realrec *p
+){
+ register char cc;
+ char sign;
+ USHORT carry;
+ USHORT t;
+ USHORT i;
+
+ sign = ((cc = NEXTC ()) == '-')? TRUE: FALSE;
+ if (ISSIGN (cc))
+ cc = MAP (NEXTC ());
+ do {
+ if ((t = (cc - '0') - ('A' <= cc) * ('A' - '0' - 10)) >= base)
+ ferrorc (E_NDN);
+ carry = (t += p->num[0] * base) >> 8;
+ p->num[0] = t & 255;
+ for (i = 1; i < 10; i++) {
+ carry = (t = p->num[i] * base + carry) >> 8;
+ p->num[i] = t & 255;
+ }
+ if (carry)
+ /* Overflow */
+ ferrorc (E_DVZ);
+ } while ((cc = MAP (NEXTC ())) != delim);
+
+ if (cc == 0)
+ BACKC ();
+ if (sign) {
+ carry = 1;
+ for (i = 0; i < 10; i++) {
+ p->num[i] = (t = (~p->num[i] & 0xff) + carry);
+ carry = t >> 8;
+ }
+ if (datadsize[optyp - TDB] < i && carry)
+ ferrorc (E_DVZ);
+ }
+}
+
+
+
+
+/*** bcddigit - evaluate bcd digit
+ *
+ * bcddigit (p);
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+#if !defined FLATMODEL
+# pragma alloc_text (FA_TEXT, bcddigit)
+#endif
+
+VOID PASCAL
+bcddigit (
+ struct realrec *p
+){
+ USHORT v;
+ register char cc;
+
+ v = (cc = NEXTC ()) - '0';
+ if (!isdigit (cc))
+ ferrorc (E_NDN);
+
+ if (isdigit (PEEKC ()))
+ bcddigit (p);
+
+ if (p->i & 1)
+ v <<= 4;
+
+ p->num[p->i / 2 ] = p->num[p->i / 2 ] + v;
+ if (p->i < 18)
+ p->i++;
+}
+
+
+
+
+/*** bcdeval - evaluate bcd constant
+ *
+ * bcdval (p);
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ * Note BCD numbers come out low digit 1st
+ */
+
+
+#if !defined FLATMODEL
+# pragma alloc_text (FA_TEXT, bcdeval)
+#endif
+
+VOID PASCAL
+bcdeval (
+ struct realrec *p
+){
+ register char cc;
+
+
+ p->num[9] = ((cc = PEEKC ()) == '-')? 0x80: 0;
+ p->i = 0;
+ if (ISSIGN (cc))
+ SKIPC ();
+
+ bcddigit (p);
+ if (p->num[9] & 15)
+ ferrorc (E_DVZ);
+}
+
+
+/*** parselong - parse long constant
+ *
+ * parselong (p);
+ *
+ * Entry *p = data descriptor entry
+ * Exit p->longstr = TRUE if long data entry parsed
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+parselong (
+ register struct dsr *p
+){
+ struct realrec a;
+ register UCHAR *cp;
+ register UCHAR cc;
+ register USHORT rbase;
+ register char expflag;
+ SHORT cb;
+ char dseen = 0;
+ char fNonZero;
+ char fSigned = FALSE;
+
+ if (ISBLANK (PEEKC ()))
+ skipblanks ();
+
+ p->dirscan = lbufp;
+ if (ISSIGN(cc = (NEXTC ()))) {
+ fSigned++;
+ cc = NEXTC ();
+ }
+
+ if (isdigit (cc) || (cc == '.')) {
+
+ /* Some numeric constant */
+
+ p->floatflag = (cc == '.');
+ expflag = FALSE;
+
+ do {
+ if ((cc = MAP (NEXTC ())) == 'E')
+ expflag = TRUE;
+ if (cc == '.')
+ p->floatflag = TRUE;
+
+ } while (isxdigit (cc) || isalpha (cc) ||
+ (expflag && ISSIGN (cc)) || cc == '.');
+
+ /* save address of end of string and check delimiter */
+ BACKC ();
+ cp = lbufp;
+ p->longstr = ISTERM (cc = skipblanks ()) || cc == ',' ||
+ cc == ')' || cc == '>';
+ lbufp = cp;
+ }
+ cb = datadsize[optyp - TDB];
+
+ if (p->longstr) {
+
+ memset(a.num, 0, 10);
+ BACKC ();
+ switch (delim = MAP (NEXTC ())) {
+ case 'B':
+ rbase = 2;
+ break;
+ case 'D':
+ rbase = 10;
+ dseen++;
+ break;
+ case 'H':
+ rbase = 16;
+ break;
+ case 'O':
+ case 'Q':
+ rbase = 8;
+ break;
+ case 'R':
+ /* check width of real constant */
+ rbase = lbufp - p->dirscan - 1;
+ if (*(p->dirscan) == '0')
+ rbase--;
+
+ if (rbase != cb*2)
+ errorc (E_IIS);
+
+ rbase = 16;
+ p->floatflag = TRUE;
+ break;
+ default:
+ delim = PEEKC ();
+ if (radixescape)
+ rbase = 10;
+ else {
+ rbase = radix;
+ if (p->floatflag)
+ rbase = 10;
+ else if (radix == 10 && expflag)
+ p->floatflag = TRUE;
+ }
+ break;
+ }
+ lbufp = p->dirscan;
+ if (p->floatflag && rbase != 16)
+ realeval (&a);
+
+ else if (rbase) {
+ if (rbase == 10 && optyp == TDT && !dseen)
+ bcdeval (&a);
+ else {
+ longeval (rbase, &a);
+ if (delim == '>' || delim == ')' || delim ==',')
+ BACKC ();
+ }
+ }
+
+ p->dupdsc =
+ (struct duprec FARSYM *) falloc( sizeof(*p->dupdsc), "parselong");
+
+ p->dupdsc->dupkind = LONG;
+ p->dupdsc->duptype.duplong.llen = cb;
+
+ p->dupdsc->type = typeFet(cb);
+
+ if (fSigned)
+ p->dupdsc->type &= ~(BT_UNSIGNED << 2);
+
+ if (p->floatflag)
+ p->dupdsc->type = mpRealType[cb];
+
+ cp = nalloc( cb, "parselong");
+
+ p->dupdsc->duptype.duplong.ldata = cp;
+ for (a.i = 0; a.i < cb; a.i++)
+ *cp++ = a.num[a.i];
+
+ /* size check if something less the max allowable # */
+
+ if (cb != 10) {
+
+ fNonZero = FALSE;
+ for (cp = a.num,cc = 0; cc < cb; cc++, cp++)
+ fNonZero |= *cp;
+
+ /* Check for value that has overflowed the defined
+ data types length or values that are entirly
+ greater then the length - ie dw 0F0000H */
+
+ for (; cc < 10; cc++, cp++)
+
+ /* == 0xFF passes sign extended negative #'s */
+
+ if (*cp &&
+ (*cp != 0xFF || !fNonZero))
+ errorc (E_DVZ);
+ }
+ }
+ else
+ /* reset character pointer to allow rescan of line */
+ lbufp = p->dirscan;
+}
+
+
+
+
+/*** datadup - function
+ *
+ * datadup ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+struct duprec FARSYM * PASCAL CODESIZE
+datadup (
+ struct dsr *p
+){
+ register char cc;
+ register struct psop *pso;
+ struct duprec FARSYM *dupptr;
+ struct duprec FARSYM *listend;
+ struct duprec FARSYM *dupdsc;
+ struct datarec drT;
+
+ /* dup count must be constant and not forward reference */
+ fInDup = TRUE;
+ forceimmed (p->valrec);
+ errorforward (p->valrec);
+ pso = &(p->valrec->dsckind.opnd);
+ if (pso->dsign || pso->doffset == 0) {
+ /* force repeat count to be > 0 */
+ pso->doffset = 1;
+ errorc (E_IDV);
+ }
+ dupptr = (struct duprec FARSYM *) falloc (sizeof (*dupptr), "datadup");
+
+ /* No items in DUP list */
+ dupptr->itemcnt = 0;
+ dupptr->type = 0;
+ dupptr->dupkind = NEST;
+ dupptr->itemlst = NULL;
+ dupptr->duptype.dupnext.dup = NULL;
+
+ /* copy repeat count and release parse stack descriptor */
+ dupptr->rptcnt = pso->doffset;
+ dfree ((char *)p->valrec );
+ listend = NULL;
+ if (ISBLANK (PEEKC ()))
+ skipblanks ();
+ if ((cc = NEXTC ()) != '(') {
+ error (E_EXP,"(");
+ BACKC ();
+ }
+ /* Now parse DUP list */
+ do {
+ dupdsc = datascan (&drT);
+
+ if (! dupptr->type)
+ dupptr->type = dupdsc->type;
+
+ if (!listend)
+ dupptr->duptype.dupnext.dup = dupdsc;
+ else
+ listend->itemlst = dupdsc;
+
+ listend = dupdsc;
+ dupptr->itemcnt++;
+
+ if (ISBLANK (PEEKC ()))
+ skipblanks ();
+
+ if ((cc = PEEKC ()) == ',')
+ SKIPC ();
+
+ else if (cc != ')') {
+ error (E_EXP,")");
+
+ if (!ISTERM(cc))
+ *lbufp = ' ';
+ }
+ } while ((cc != ')') && !ISTERM (cc));
+ if (ISTERM (cc))
+ error (E_EXP,")");
+ else
+ SKIPC ();
+
+ fInDup = FALSE;
+ return (dupptr);
+}
+
+
+
+
+
+/*** datacon - data constant not string
+ *
+ * datacon (p);
+ *
+ * Entry *p = parse stack entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+datacon (
+ struct dsr *p
+){
+ register struct psop *psor;
+
+ /* See if expr or DUP */
+ /* Not <n> DUP() */
+ p->flag = FALSE;
+ if (initflag && (PEEKC () == '<'))
+ initrs (p);
+ else {
+
+ /* Not initialize list */
+
+ p->dirscan = lbufp;
+ p->valrec = expreval (&nilseg);
+ psor = &(p->valrec->dsckind.opnd);
+
+ if (strucflag && !initflag &&
+ (psor->dflag == FORREF || psor->dflag == UNDEFINED))
+ /* Forward in struc body */
+ errorc (E_IFR);
+
+ if (psor->mode !=4 && !isdirect(psor))
+ errorc (E_IOT);
+
+ if (psor->seg != NOSEG)
+ errorc (E_IOT);
+
+ if (dupflag) {
+ /* Have DUP operator */
+ getatom ();
+ p->flag = TRUE;
+ }
+ else if (strucflag && initflag && !p->initlist) {
+ lbufp = p->dirscan;
+ symptr = recptr;
+ p->dupdsc = strucparse ();
+ p->initlist = TRUE;
+ }
+ }
+ if (p->flag)
+ p->dupdsc = datadup (p);
+ else {
+ if (!p->initlist || !initflag)
+ subr1 (p);
+ }
+}
+
+
+
+
+/*** subr1 -
+ *
+ * subr1 (p);
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+subr1 (
+ struct dsr *p
+){
+ USHORT i;
+ register struct psop *psor;
+ char *cp;
+ long l;
+
+ psor = &(p->valrec->dsckind.opnd);
+
+ if (fSimpleSeg)
+ makeGrpRel (psor);
+
+ /* Not init list */
+ if (optyp == TDB)
+ valuecheck (&psor->doffset, 0xff);
+
+ else if (optyp == TDW)
+ valuecheck (&psor->doffset, (USHORT)0xffff);
+
+ if ((optyp != TDW) && (optyp != TDD) && optyp != TDF) {
+
+ if ((psor->mode != 3) && (psor->mode != 4))
+ errorc (E_CXP);
+
+ psor->mode = 4;
+ psor->w = FALSE;
+ psor->fixtype = FCONSTANT;
+ }
+
+ if (initflag)
+ errorc (E_OIL);
+
+ p->dupdsc = (struct duprec FARSYM *) falloc (sizeof(*p->dupdsc), "subr1");
+
+ if (!(fInDup && psor->dflag == INDETER) &&
+ !(psor->dsegment || psor->dflag == XTERNAL)) {
+
+ p->dupdsc->dupkind = LONG;
+ psor->dsize = p->dupdsc->duptype.duplong.llen = datadsize[optyp - TDB];
+ p->dupdsc->type = typeFet(psor->dsize);
+
+ if (ISSIGN(*p->dirscan))
+ p->dupdsc->type &= ~(BT_UNSIGNED << 2);
+
+ if (psor->dflag == INDETER || psor->doffset == 0) {
+
+ p->dupdsc->duptype.duplong.ldata = uninitialized;
+ }
+ else {
+
+ cp = nalloc (p->dupdsc->duptype.duplong.llen, "subr1");
+
+ p->dupdsc->duptype.duplong.ldata = cp;
+ if (psor->dsign && psor->doffset)
+ psor->doffset = ~psor->doffset + 1;
+
+ l = psor->doffset;
+ for (i = 0; i < p->dupdsc->duptype.duplong.llen; i++){
+ *cp++ = l;
+ l >>= 8;
+ }
+ }
+
+ dfree ((char *)p->valrec );
+ }
+ else {
+ if (psor->mode != 4 && !isdirect(psor))
+ /* Immediate or direct only */
+ errorc (E_IOT);
+
+ if ((psor->fixtype == FGROUPSEG || psor->fixtype == FOFFSET) &&
+ ((optyp == TDD && wordsize == 2 && !(psor->dtype&M_EXPLOFFSET)) ||
+ optyp == TDF))
+
+ psor->fixtype = FPOINTER;
+
+ /* Size of item */
+ varsize = psor->dsize;
+
+ psor->dsize = datadsize[optyp - TDB];
+
+ /* If item size is byte, make link output byte too */
+
+ psor->w = TRUE;
+
+ if (psor->dsize == 1) {
+ psor->w--;
+
+ if (psor->fixtype != FHIGH &&
+ (psor->dflag == XTERNAL || psor->dsegment ||
+ psor->dcontext))
+
+ psor->fixtype = FLOW;
+ }
+ mapFixup(psor);
+
+ *naim.pszName = NULL;
+ if (psor->fixtype == FCONSTANT)
+ p->dupdsc->type = typeFet(psor->dsize);
+ else
+ p->dupdsc->type = fnPtr(psor->dsize);
+
+ p->dupdsc->dupkind = ITEM;
+ p->dupdsc->duptype.dupitem.ddata = p->valrec;
+ }
+}
+
+
+
+
+/*** initrs - initialize record/structure
+ *
+ * initrs (p);
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+initrs (
+ struct dsr *p
+){
+ register char *cp;
+ SHORT cb;
+
+ /* Initializing RECORD/STRUC */
+ symptr = recptr;
+ if (strucflag)
+ p->dupdsc = strucparse ();
+ else {
+ /* Get value of record */
+ p->i = recordparse ();
+ /* Make long constant */
+ p->dupdsc =
+ (struct duprec FARSYM *)falloc (sizeof (*p->dupdsc), "initrs");
+ p->dupdsc->dupkind = LONG;
+ p->dupdsc->duptype.duplong.llen = cb = recptr->symtype;
+
+ cp = nalloc (cb, "initrs");
+
+ p->dupdsc->duptype.duplong.ldata = cp;
+ p->dupdsc->type = typeFet(cb);
+
+ while(cb--){
+ *cp++ = p->i;
+ p->i >>= 8;
+ }
+ }
+ p->initlist = TRUE;
+}
+
+
+
+
+/*** datadb - process <db> directive
+ *
+ * datadb ();
+ *
+ * Entry *lbufp = beginning quote (\'|\") of string
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+datadb (
+ register struct dsr *p
+){
+ register USHORT i;
+ register char *cp;
+
+ /* Save ptr to start of string */
+ p->dirscan = lbufp;
+ delim = NEXTC ();
+ /* Compute string length */
+ i = 0;
+ while (!endstring ()) {
+ SKIPC ();
+ i++;
+ }
+ /* reset scan pointer */
+ lbufp = p->dirscan;
+ if (i == 0)
+ errorc (E_EMS);
+ else if (i > 1) {
+ SKIPC ();
+ /* Long string */
+ p->longstr = TRUE;
+
+ /* Create entry for long string */
+ p->dupdsc =
+ (struct duprec FARSYM *)falloc (sizeof (*p->dupdsc), "datadb");
+
+ /* Initialize text area for data */
+ p->dupdsc->dupkind = LONG;
+ p->dupdsc->type = makeType(BT_ASCII, BT_DIRECT, BT_sz1);
+ p->dupdsc->duptype.duplong.llen = i;
+ cp = nalloc ( (USHORT)(p->dupdsc->duptype.duplong.llen + 1), "datadb");
+ p->dupdsc->duptype.duplong.ldata = cp;
+ for (; i; i--)
+ if (!endstring ())
+ *cp++ = NEXTC ();
+ *cp = 0;
+ SKIPC ();
+ }
+}
+
+
+/*** dataitem - parse next data item from line
+ *
+ * dataitem (p);
+ *
+ * Entry p = pointer to datarec structure
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+dataitem (
+ struct datarec *p
+){
+ struct duprec FARSYM *topitem;
+
+ /* Scan , may recurse on DUP */
+ topitem = datascan (p);
+ /* Display scan now */
+ displayflag = TRUE;
+ /* Display data */
+ scandup (topitem, dupdisplay);
+ displayflag = FALSE;
+
+ if (p->datalen == 0)
+ p->datalen = topitem->rptcnt;
+
+ if (topitem->dupkind == NEST) {
+
+ /* This item was a DUP */
+ resvspace = TRUE;
+ /* Get size of DUP list */
+ clausesize = calcsize (topitem);
+ if (strucflag && initflag)
+ resvspace = FALSE;
+
+ if (pass2 && !(resvspace || p->buildfield))
+ /* Send to linker */
+ if (!emitdup (topitem))
+ errorc (E_DTL);
+
+ if (! p->type)
+ p->type = topitem->type;
+
+ if (p->buildfield)
+ linkfield (topitem);
+
+ else if (strucflag && initflag) {
+ /* Allocating STRUC */
+ strucflag = FALSE;
+ /* Free overrides */
+ scandup (strucoveride, oblitdup);
+ /* Turn back on */
+ strucflag = TRUE;
+ }
+ else /* Not STRUC allocate */
+ scandup (topitem, oblitdup);
+ }
+ else {
+ /* Some kind of list */
+ clausesize = (topitem->dupkind == ITEM)
+ ? topitem->duptype.dupitem.ddata->dsckind.opnd.dsize
+ : topitem->duptype.duplong.llen;
+
+ if (pass2 && !p->buildfield) {
+ if (topitem->dupkind == ITEM)
+
+ emitobject (&topitem->duptype.dupitem.ddata->dsckind.opnd);
+ else
+ emitlong (topitem);
+ }
+ if (! p->type)
+ p->type = topitem->type;
+
+ if (p->buildfield)
+ linkfield (topitem);
+ else
+ oblitdup (topitem);
+ }
+ /* Add in size of this item */
+ pcoffset += clausesize;
+ skipblanks ();
+}
+
+
+
+
+/*** datadefine -
+ *
+ * datadefine ();
+ *
+ * Entry
+ * Exit
+ * Returns
+ * Calls
+ */
+
+
+VOID PASCAL CODESIZE
+datadefine (
+){
+ struct datarec a;
+ short cc;
+
+ strucoveride = NULL;
+ a.buildfield = (strucflag && !initflag)? TRUE: FALSE;
+ a.type = 0;
+
+ if (labelflag) { /* Have label */
+ labelcreate ( (USHORT)2, (UCHAR) (a.buildfield ? (UCHAR) STRUCFIELD : (UCHAR) CLABEL));
+ if (errorcode == (E_ERRMASK & E_SDK))
+ return;
+
+ if (strucflag && initflag){
+ a.type = recptr->symu.rsmsym.rsmtype.rsmstruc.type;
+ }
+ }
+ else
+ pcdisplay ();
+
+ a.labelptr = symptr; /* Save ptr to entry */
+ a.datalen = 0; /* Don't know length */
+ emittext = FALSE; /* Prevent link emitter */
+ duplevel = 0;
+
+ /* Scan item list */
+ if (ISTERM (PEEKC ()))
+ errorc (E_OPN);
+ else {
+ BACKC ();
+ do {
+ SKIPC ();
+
+ if ((cc = skipblanks ()) == ',' || cc == ';' || ISTERM(cc))
+ errorc(E_MDZ);
+
+ dataitem (&a);
+
+ } while (PEEKC () == ',');
+ }
+ if (labelflag) {
+ a.labelptr->symtype = datadsize[optyp - TDB];
+
+ if (a.buildfield) {
+ /* Making STRUC body */
+ if (a.labelptr->symkind == STRUCFIELD) {
+
+ if (struclabel)
+ struclabel->symu.struk.strucnxt = a.labelptr;
+ else
+ recptr->symu.rsmsym.rsmtype.rsmstruc.struclist = a.labelptr;
+
+ /* Constant, no segment */
+ a.labelptr->symsegptr = NULL;
+ /* End of named list */
+ a.labelptr->symu.struk.strucnxt = NULL;
+ a.labelptr->symu.struk.type = a.type;
+ struclabel = a.labelptr;
+ }
+ }
+ else
+ a.labelptr->symu.clabel.type = a.type;
+
+ /* Set length */
+ a.labelptr->length = a.datalen;
+ }
+ emittext = TRUE;
+}
+
+
+/*** commDefine - define a communal variable
+ *
+ * Format: comm {far|near} name:size[:#Ofitems],....
+ *
+ */
+
+
+VOID PASCAL CODESIZE
+commDefine (
+){
+ USHORT distance;
+ char cT, *pT;
+ USHORT symtype;
+ SYMBOL FARSYM *pSY;
+
+ getatom ();
+
+ distance = (farData[10] > '0')? CSFAR: CSNEAR;
+
+ if (fnsize ()){ /* look for optional near | far */
+
+ distance = varsize;
+ getatom ();
+
+ if (distance < CSFAR)
+ errorc (E_UST);
+ }
+
+ cT = symFet (); /* fetch name and save for later */
+ pSY = symptr;
+
+ if (*naim.pszName == NULL){
+ errorc(E_OPN);
+ return;
+ }
+
+ if (NEXTC() != ':')
+ errorc (E_SYN);
+ /* get the size of the item */
+ pT = lbufp;
+ switchname ();
+ getatom();
+
+
+ if (symFet() && symptr->symkind == STRUC){
+
+ varsize = symptr->symtype;
+ }
+ else {
+ lbufp = pT;
+ if (pT = (char *)strchr(pT, ':'))
+ *pT = NULL;
+
+ varsize = exprconst();
+
+ if (pT)
+ *pT = ':';
+ }
+ if (!varsize)
+ errorc(E_IIS &~E_WARN1);
+
+ if (cT)
+ symptr = pSY;
+
+ externflag (DVAR, cT);
+ pSY = symptr;
+ pSY->symu.ext.length = 1;
+ pSY->symu.ext.commFlag++;
+
+ if (skipblanks() == ':'){ /* optional size given */
+
+ fArth32++; /* allow >64 items */
+ SKIPC();
+
+ if ((pSY->symu.ext.length = exprconst()) == 0) /* get the # items */
+ errorc(E_CXP);
+
+ fArth32--;
+ if (pSY->symu.ext.length * pSY->symtype > 0xffff)
+ pSY->symu.ext.commFlag++; /* for >64K convert to far */
+ }
+
+ if (distance == CSFAR)
+ pSY->symu.ext.commFlag++; /* 2 means far commdef */
+
+}