Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1317 lines
23 KiB

4 years ago
  1. /* asmdata.c -- microsoft 80x86 assembler
  2. **
  3. ** microsoft (r) macro assembler
  4. ** copyright (c) microsoft corp 1986. all rights reserved
  5. **
  6. ** randy nevin
  7. **
  8. ** 10/90 - Quick conversion to 32 bit by Jeff Spencer
  9. */
  10. #include <stdio.h>
  11. #include "asm86.h"
  12. #include "asmfcn.h"
  13. #include <ctype.h>
  14. #include "asmindex.h"
  15. #include "asmctype.h"
  16. #include "asmmsg.h"
  17. extern UCHAR mpRealType[];
  18. /* Dup tree is organized left to right horizonatally for each
  19. item in a DUP list at the same level( i. e. 5 DUP(1,2,3) ).
  20. This is considered the 'list' part. Any item in the list
  21. may be another DUP header instead of a data entry, in
  22. which case you go down a level and have another list.
  23. */
  24. char uninitialized[10];
  25. char fInDup;
  26. /*** scanstruc - scan structure tree and execute function
  27. *
  28. * scanstruc (dupr, disp);
  29. *
  30. * Entry *dupr = duprec structure entry
  31. * disp = pointer to function to execute at each node
  32. * Exit
  33. * Returns
  34. * Calls
  35. */
  36. VOID PASCAL CODESIZE
  37. scanstruc (
  38. struct duprec FARSYM *dupr,
  39. VOID (PASCAL CODESIZE *disp) (struct duprec FARSYM *)
  40. ){
  41. struct duprec FARSYM *ptr;
  42. struct duprec FARSYM *iptr;
  43. struct duprec FARSYM *fldptr;
  44. struct duprec FARSYM *initptr;
  45. OFFSET strucpc;
  46. /* save starting address of structure */
  47. strucpc = pcoffset;
  48. if (dupr)
  49. /* Output <n> DUP( */
  50. (*disp) (dupr);
  51. /* 1st default value for STRUC */
  52. fldptr = recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->duptype.dupnext.dup;
  53. /* 1st initialize value */
  54. initptr = strucoveride;
  55. if (initptr) {
  56. /* process initialization fields for structure */
  57. while (fldptr) {
  58. if (fldptr->itemcnt == 1 && fldptr->duptype.dupnext.dup->itemcnt == 0
  59. && initptr->duptype.dupitem.ddata)
  60. /* Use default */
  61. ptr = initptr;
  62. else
  63. /* Can't override field */
  64. ptr = fldptr;
  65. iptr = ptr->itemlst;
  66. ptr->itemlst = NULL;
  67. if (displayflag && !dupr) {
  68. offsetAscii (strucpc);
  69. listindex = 1;
  70. /* Display PC */
  71. copyascii ();
  72. listindex = LSTDATA;
  73. if (highWord(strucpc))
  74. listindex += 4;
  75. }
  76. if (ptr->rptcnt > 1 || ptr->itemcnt > 1)
  77. /* Output <n> DUP( */
  78. (*disp) (ptr);
  79. /* Display field */
  80. scanlist (ptr, disp);
  81. if (ptr->rptcnt > 1 || ptr->itemcnt > 1)
  82. enddupdisplay ();
  83. if (displayflag && !dupr) {
  84. /* Calc size of field */
  85. clausesize = calcsize (ptr);
  86. if (dupr)
  87. clausesize *= dupr->rptcnt;
  88. strucpc += clausesize;
  89. }
  90. /* Restore */
  91. ptr->itemlst = iptr;
  92. if (displayflag && (listbuffer[LSTDATA] != ' ' ||
  93. listbuffer[14] != ' ')) {
  94. resetobjidx ();
  95. }
  96. /* Advance default field */
  97. fldptr = fldptr->itemlst;
  98. /* Advance override field */
  99. initptr = initptr->itemlst;
  100. }
  101. }
  102. if (dupr)
  103. enddupdisplay ();
  104. }
  105. /*** scandup - scan DUP tree and execute function
  106. *
  107. * scandup (tree, disp);
  108. *
  109. * Entry *tree = DUP tree
  110. * *disp = function to execute at each node of tree
  111. * Exit
  112. * Returns
  113. * Calls
  114. */
  115. VOID PASCAL CODESIZE
  116. scandup (
  117. struct duprec FARSYM *tree,
  118. VOID (PASCAL CODESIZE *disp)(struct duprec FARSYM *)
  119. ){
  120. if (tree)
  121. if (strucflag && initflag)
  122. /* Want to skip STRUC heading */
  123. if (tree == recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody)
  124. /* This is not <n> DUP(<>) So no DUP prefix */
  125. scanstruc ((struct duprec FARSYM *)NULL, disp);
  126. else { /* must set itemcnt in DUP to # fields */
  127. tree->itemcnt = recptr->symu.rsmsym.rsmtype.rsmstruc.strucfldnum;
  128. scanstruc (tree, disp);
  129. }
  130. else /* Else is not STRUC */
  131. scanlist (tree, disp);
  132. }
  133. /*** oblitdup - delete DUP entry
  134. *
  135. * oblitdup (node);
  136. *
  137. * Entry *node = DUP entry
  138. * Exit
  139. * Returns
  140. * Calls
  141. */
  142. VOID PASCAL CODESIZE
  143. oblitdup (
  144. struct duprec FARSYM *node
  145. ){
  146. switch (node->dupkind) {
  147. case NEST:
  148. _ffree ((char FARSYM *)node);
  149. break;
  150. case ITEM:
  151. if (node->duptype.dupitem.ddata)
  152. dfree ((char *)node->duptype.dupitem.ddata );
  153. _ffree ((char FARSYM *)node);
  154. break;
  155. case LONG:
  156. if (node->duptype.duplong.ldata != uninitialized)
  157. free ((char *)node->duptype.duplong.ldata);
  158. _ffree ((char FARSYM *)node);
  159. break;
  160. default:
  161. TERMINATE(ER_FAT, 99);
  162. }
  163. }
  164. /*** displlong - display long constant
  165. *
  166. * displaylong (dup);
  167. *
  168. * Entry *dup = dup entry
  169. * Exit
  170. * Returns
  171. * Calls
  172. */
  173. VOID PASCAL CODESIZE
  174. displlong (
  175. struct duprec FARSYM *dup
  176. ){
  177. register USHORT cnt;
  178. register char *p;
  179. p = dup->duptype.duplong.ldata;
  180. for (cnt = dup->duptype.duplong.llen; cnt; cnt--) {
  181. if (optyp == TDW || optyp == TDD)
  182. emitopcode ((UCHAR)p[cnt-1]);
  183. else
  184. emitopcode ((UCHAR)*p++);
  185. if (optyp != TDB)
  186. listindex--;
  187. }
  188. if (optyp != TDB)
  189. listindex++;
  190. }
  191. /*** begdupdisplay - begin DUP display
  192. *
  193. * begdupdisplay (dup);
  194. *
  195. * Entry *dup = DUP entry
  196. * Exit
  197. * Returns
  198. * Calls
  199. */
  200. VOID PASCAL CODESIZE
  201. begdupdisplay (
  202. struct duprec FARSYM *dup
  203. ){
  204. /* flush line if data already displayed */
  205. if ((highWord(pcoffset) && listbuffer[LSTDATA+3] != ' ') ||
  206. listbuffer[LSTDATA] != ' ')
  207. resetobjidx ();
  208. listindex = LSTDATA + duplevel; /* Indent for DUP clause */
  209. if (highWord(pcoffset))
  210. listindex += 4;
  211. offsetAscii (dup->rptcnt); /* display repeat count in four bytes */
  212. copyascii ();
  213. listbuffer[listindex] = '[';
  214. duplevel++; /* Indent another level */
  215. resetobjidx (); /* Display DUP repeat line */
  216. }
  217. /*** enddupdisplay - end DUP display
  218. *
  219. * enddupdisplay ();
  220. *
  221. * Entry
  222. * Exit
  223. * Returns
  224. * Calls
  225. */
  226. VOID PASCAL CODESIZE
  227. enddupdisplay (
  228. ){
  229. if (duplevel) {
  230. duplevel--;
  231. if (displayflag) {
  232. listbuffer[LSTMAX - ((duplevel <= 8)? duplevel: 8)] = ']';
  233. resetobjidx ();
  234. }
  235. }
  236. }
  237. /*** itemdisplay - display DUP data item
  238. *
  239. * itemdisplay (dup);
  240. *
  241. * Entry *dup = dup record
  242. * Exit
  243. * Returns
  244. * Calls
  245. */
  246. VOID PASCAL CODESIZE
  247. itemdisplay (
  248. struct duprec FARSYM *dup
  249. ){
  250. if (listindex > LSTMAX)
  251. resetobjidx ();
  252. if (dup->dupkind == ITEM)
  253. emitOP (&dup->duptype.dupitem.ddata->dsckind.opnd);
  254. else
  255. displlong (dup);
  256. if (duplevel)
  257. resetobjidx ();
  258. }
  259. /*** dupdisplay - display DUP item on listing
  260. *
  261. * dupdisplay (ptr);
  262. *
  263. * Entry *ptr = DUP entry
  264. * Exit
  265. * Returns
  266. * Calls
  267. */
  268. VOID PASCAL CODESIZE
  269. dupdisplay (
  270. struct duprec FARSYM *ptr
  271. ){
  272. if (ptr->dupkind == NEST)
  273. begdupdisplay (ptr);
  274. else
  275. itemdisplay (ptr);
  276. }
  277. /*** linkfield - add item to list of DUP for current STRUC
  278. *
  279. * linkfield (nitem);
  280. *
  281. * Entry
  282. * Exit
  283. * Returns
  284. * Calls
  285. */
  286. VOID PASCAL CODESIZE
  287. linkfield (
  288. struct duprec FARSYM *nitem
  289. ){
  290. struct duprec FARSYM *ptr;
  291. if (strucprev->itemcnt++ == 0)/* 1st item in field */
  292. strucprev->duptype.dupnext.dup = nitem;
  293. else {
  294. ptr = strucprev->duptype.dupnext.dup;
  295. while (ptr->itemlst)
  296. ptr = ptr->itemlst;
  297. /* Add to end of list */
  298. ptr->itemlst = nitem;
  299. }
  300. }
  301. /*** longeval - evaluate long non-floating point, non-BCD constant
  302. *
  303. * longeval (base, p);
  304. *
  305. * Entry delim = delimiter character
  306. * Exit
  307. * Returns
  308. * Calls
  309. */
  310. #if !defined FLATMODEL
  311. # pragma alloc_text (FA_TEXT, longeval)
  312. #endif
  313. VOID PASCAL
  314. longeval (
  315. USHORT base,
  316. register struct realrec *p
  317. ){
  318. register char cc;
  319. char sign;
  320. USHORT carry;
  321. USHORT t;
  322. USHORT i;
  323. sign = ((cc = NEXTC ()) == '-')? TRUE: FALSE;
  324. if (ISSIGN (cc))
  325. cc = MAP (NEXTC ());
  326. do {
  327. if ((t = (cc - '0') - ('A' <= cc) * ('A' - '0' - 10)) >= base)
  328. ferrorc (E_NDN);
  329. carry = (t += p->num[0] * base) >> 8;
  330. p->num[0] = t & 255;
  331. for (i = 1; i < 10; i++) {
  332. carry = (t = p->num[i] * base + carry) >> 8;
  333. p->num[i] = t & 255;
  334. }
  335. if (carry)
  336. /* Overflow */
  337. ferrorc (E_DVZ);
  338. } while ((cc = MAP (NEXTC ())) != delim);
  339. if (cc == 0)
  340. BACKC ();
  341. if (sign) {
  342. carry = 1;
  343. for (i = 0; i < 10; i++) {
  344. p->num[i] = (t = (~p->num[i] & 0xff) + carry);
  345. carry = t >> 8;
  346. }
  347. if (datadsize[optyp - TDB] < i && carry)
  348. ferrorc (E_DVZ);
  349. }
  350. }
  351. /*** bcddigit - evaluate bcd digit
  352. *
  353. * bcddigit (p);
  354. *
  355. * Entry
  356. * Exit
  357. * Returns
  358. * Calls
  359. */
  360. #if !defined FLATMODEL
  361. # pragma alloc_text (FA_TEXT, bcddigit)
  362. #endif
  363. VOID PASCAL
  364. bcddigit (
  365. struct realrec *p
  366. ){
  367. USHORT v;
  368. register char cc;
  369. v = (cc = NEXTC ()) - '0';
  370. if (!isdigit (cc))
  371. ferrorc (E_NDN);
  372. if (isdigit (PEEKC ()))
  373. bcddigit (p);
  374. if (p->i & 1)
  375. v <<= 4;
  376. p->num[p->i / 2 ] = p->num[p->i / 2 ] + v;
  377. if (p->i < 18)
  378. p->i++;
  379. }
  380. /*** bcdeval - evaluate bcd constant
  381. *
  382. * bcdval (p);
  383. *
  384. * Entry
  385. * Exit
  386. * Returns
  387. * Calls
  388. * Note BCD numbers come out low digit 1st
  389. */
  390. #if !defined FLATMODEL
  391. # pragma alloc_text (FA_TEXT, bcdeval)
  392. #endif
  393. VOID PASCAL
  394. bcdeval (
  395. struct realrec *p
  396. ){
  397. register char cc;
  398. p->num[9] = ((cc = PEEKC ()) == '-')? 0x80: 0;
  399. p->i = 0;
  400. if (ISSIGN (cc))
  401. SKIPC ();
  402. bcddigit (p);
  403. if (p->num[9] & 15)
  404. ferrorc (E_DVZ);
  405. }
  406. /*** parselong - parse long constant
  407. *
  408. * parselong (p);
  409. *
  410. * Entry *p = data descriptor entry
  411. * Exit p->longstr = TRUE if long data entry parsed
  412. * Returns
  413. * Calls
  414. */
  415. VOID PASCAL CODESIZE
  416. parselong (
  417. register struct dsr *p
  418. ){
  419. struct realrec a;
  420. register UCHAR *cp;
  421. register UCHAR cc;
  422. register USHORT rbase;
  423. register char expflag;
  424. SHORT cb;
  425. char dseen = 0;
  426. char fNonZero;
  427. char fSigned = FALSE;
  428. if (ISBLANK (PEEKC ()))
  429. skipblanks ();
  430. p->dirscan = lbufp;
  431. if (ISSIGN(cc = (NEXTC ()))) {
  432. fSigned++;
  433. cc = NEXTC ();
  434. }
  435. if (isdigit (cc) || (cc == '.')) {
  436. /* Some numeric constant */
  437. p->floatflag = (cc == '.');
  438. expflag = FALSE;
  439. do {
  440. if ((cc = MAP (NEXTC ())) == 'E')
  441. expflag = TRUE;
  442. if (cc == '.')
  443. p->floatflag = TRUE;
  444. } while (isxdigit (cc) || isalpha (cc) ||
  445. (expflag && ISSIGN (cc)) || cc == '.');
  446. /* save address of end of string and check delimiter */
  447. BACKC ();
  448. cp = lbufp;
  449. p->longstr = ISTERM (cc = skipblanks ()) || cc == ',' ||
  450. cc == ')' || cc == '>';
  451. lbufp = cp;
  452. }
  453. cb = datadsize[optyp - TDB];
  454. if (p->longstr) {
  455. memset(a.num, 0, 10);
  456. BACKC ();
  457. switch (delim = MAP (NEXTC ())) {
  458. case 'B':
  459. rbase = 2;
  460. break;
  461. case 'D':
  462. rbase = 10;
  463. dseen++;
  464. break;
  465. case 'H':
  466. rbase = 16;
  467. break;
  468. case 'O':
  469. case 'Q':
  470. rbase = 8;
  471. break;
  472. case 'R':
  473. /* check width of real constant */
  474. rbase = lbufp - p->dirscan - 1;
  475. if (*(p->dirscan) == '0')
  476. rbase--;
  477. if (rbase != cb*2)
  478. errorc (E_IIS);
  479. rbase = 16;
  480. p->floatflag = TRUE;
  481. break;
  482. default:
  483. delim = PEEKC ();
  484. if (radixescape)
  485. rbase = 10;
  486. else {
  487. rbase = radix;
  488. if (p->floatflag)
  489. rbase = 10;
  490. else if (radix == 10 && expflag)
  491. p->floatflag = TRUE;
  492. }
  493. break;
  494. }
  495. lbufp = p->dirscan;
  496. if (p->floatflag && rbase != 16)
  497. realeval (&a);
  498. else if (rbase) {
  499. if (rbase == 10 && optyp == TDT && !dseen)
  500. bcdeval (&a);
  501. else {
  502. longeval (rbase, &a);
  503. if (delim == '>' || delim == ')' || delim ==',')
  504. BACKC ();
  505. }
  506. }
  507. p->dupdsc =
  508. (struct duprec FARSYM *) falloc( sizeof(*p->dupdsc), "parselong");
  509. p->dupdsc->dupkind = LONG;
  510. p->dupdsc->duptype.duplong.llen = cb;
  511. p->dupdsc->type = typeFet(cb);
  512. if (fSigned)
  513. p->dupdsc->type &= ~(BT_UNSIGNED << 2);
  514. if (p->floatflag)
  515. p->dupdsc->type = mpRealType[cb];
  516. cp = nalloc( cb, "parselong");
  517. p->dupdsc->duptype.duplong.ldata = cp;
  518. for (a.i = 0; a.i < cb; a.i++)
  519. *cp++ = a.num[a.i];
  520. /* size check if something less the max allowable # */
  521. if (cb != 10) {
  522. fNonZero = FALSE;
  523. for (cp = a.num,cc = 0; cc < cb; cc++, cp++)
  524. fNonZero |= *cp;
  525. /* Check for value that has overflowed the defined
  526. data types length or values that are entirly
  527. greater then the length - ie dw 0F0000H */
  528. for (; cc < 10; cc++, cp++)
  529. /* == 0xFF passes sign extended negative #'s */
  530. if (*cp &&
  531. (*cp != 0xFF || !fNonZero))
  532. errorc (E_DVZ);
  533. }
  534. }
  535. else
  536. /* reset character pointer to allow rescan of line */
  537. lbufp = p->dirscan;
  538. }
  539. /*** datadup - function
  540. *
  541. * datadup ();
  542. *
  543. * Entry
  544. * Exit
  545. * Returns
  546. * Calls
  547. */
  548. struct duprec FARSYM * PASCAL CODESIZE
  549. datadup (
  550. struct dsr *p
  551. ){
  552. register char cc;
  553. register struct psop *pso;
  554. struct duprec FARSYM *dupptr;
  555. struct duprec FARSYM *listend;
  556. struct duprec FARSYM *dupdsc;
  557. struct datarec drT;
  558. /* dup count must be constant and not forward reference */
  559. fInDup = TRUE;
  560. forceimmed (p->valrec);
  561. errorforward (p->valrec);
  562. pso = &(p->valrec->dsckind.opnd);
  563. if (pso->dsign || pso->doffset == 0) {
  564. /* force repeat count to be > 0 */
  565. pso->doffset = 1;
  566. errorc (E_IDV);
  567. }
  568. dupptr = (struct duprec FARSYM *) falloc (sizeof (*dupptr), "datadup");
  569. /* No items in DUP list */
  570. dupptr->itemcnt = 0;
  571. dupptr->type = 0;
  572. dupptr->dupkind = NEST;
  573. dupptr->itemlst = NULL;
  574. dupptr->duptype.dupnext.dup = NULL;
  575. /* copy repeat count and release parse stack descriptor */
  576. dupptr->rptcnt = pso->doffset;
  577. dfree ((char *)p->valrec );
  578. listend = NULL;
  579. if (ISBLANK (PEEKC ()))
  580. skipblanks ();
  581. if ((cc = NEXTC ()) != '(') {
  582. error (E_EXP,"(");
  583. BACKC ();
  584. }
  585. /* Now parse DUP list */
  586. do {
  587. dupdsc = datascan (&drT);
  588. if (! dupptr->type)
  589. dupptr->type = dupdsc->type;
  590. if (!listend)
  591. dupptr->duptype.dupnext.dup = dupdsc;
  592. else
  593. listend->itemlst = dupdsc;
  594. listend = dupdsc;
  595. dupptr->itemcnt++;
  596. if (ISBLANK (PEEKC ()))
  597. skipblanks ();
  598. if ((cc = PEEKC ()) == ',')
  599. SKIPC ();
  600. else if (cc != ')') {
  601. error (E_EXP,")");
  602. if (!ISTERM(cc))
  603. *lbufp = ' ';
  604. }
  605. } while ((cc != ')') && !ISTERM (cc));
  606. if (ISTERM (cc))
  607. error (E_EXP,")");
  608. else
  609. SKIPC ();
  610. fInDup = FALSE;
  611. return (dupptr);
  612. }
  613. /*** datacon - data constant not string
  614. *
  615. * datacon (p);
  616. *
  617. * Entry *p = parse stack entry
  618. * Exit
  619. * Returns
  620. * Calls
  621. */
  622. VOID PASCAL CODESIZE
  623. datacon (
  624. struct dsr *p
  625. ){
  626. register struct psop *psor;
  627. /* See if expr or DUP */
  628. /* Not <n> DUP() */
  629. p->flag = FALSE;
  630. if (initflag && (PEEKC () == '<'))
  631. initrs (p);
  632. else {
  633. /* Not initialize list */
  634. p->dirscan = lbufp;
  635. p->valrec = expreval (&nilseg);
  636. psor = &(p->valrec->dsckind.opnd);
  637. if (strucflag && !initflag &&
  638. (psor->dflag == FORREF || psor->dflag == UNDEFINED))
  639. /* Forward in struc body */
  640. errorc (E_IFR);
  641. if (psor->mode !=4 && !isdirect(psor))
  642. errorc (E_IOT);
  643. if (psor->seg != NOSEG)
  644. errorc (E_IOT);
  645. if (dupflag) {
  646. /* Have DUP operator */
  647. getatom ();
  648. p->flag = TRUE;
  649. }
  650. else if (strucflag && initflag && !p->initlist) {
  651. lbufp = p->dirscan;
  652. symptr = recptr;
  653. p->dupdsc = strucparse ();
  654. p->initlist = TRUE;
  655. }
  656. }
  657. if (p->flag)
  658. p->dupdsc = datadup (p);
  659. else {
  660. if (!p->initlist || !initflag)
  661. subr1 (p);
  662. }
  663. }
  664. /*** subr1 -
  665. *
  666. * subr1 (p);
  667. *
  668. * Entry
  669. * Exit
  670. * Returns
  671. * Calls
  672. */
  673. VOID PASCAL CODESIZE
  674. subr1 (
  675. struct dsr *p
  676. ){
  677. USHORT i;
  678. register struct psop *psor;
  679. char *cp;
  680. long l;
  681. psor = &(p->valrec->dsckind.opnd);
  682. if (fSimpleSeg)
  683. makeGrpRel (psor);
  684. /* Not init list */
  685. if (optyp == TDB)
  686. valuecheck (&psor->doffset, 0xff);
  687. else if (optyp == TDW)
  688. valuecheck (&psor->doffset, (USHORT)0xffff);
  689. if ((optyp != TDW) && (optyp != TDD) && optyp != TDF) {
  690. if ((psor->mode != 3) && (psor->mode != 4))
  691. errorc (E_CXP);
  692. psor->mode = 4;
  693. psor->w = FALSE;
  694. psor->fixtype = FCONSTANT;
  695. }
  696. if (initflag)
  697. errorc (E_OIL);
  698. p->dupdsc = (struct duprec FARSYM *) falloc (sizeof(*p->dupdsc), "subr1");
  699. if (!(fInDup && psor->dflag == INDETER) &&
  700. !(psor->dsegment || psor->dflag == XTERNAL)) {
  701. p->dupdsc->dupkind = LONG;
  702. psor->dsize = p->dupdsc->duptype.duplong.llen = datadsize[optyp - TDB];
  703. p->dupdsc->type = typeFet(psor->dsize);
  704. if (ISSIGN(*p->dirscan))
  705. p->dupdsc->type &= ~(BT_UNSIGNED << 2);
  706. if (psor->dflag == INDETER || psor->doffset == 0) {
  707. p->dupdsc->duptype.duplong.ldata = uninitialized;
  708. }
  709. else {
  710. cp = nalloc (p->dupdsc->duptype.duplong.llen, "subr1");
  711. p->dupdsc->duptype.duplong.ldata = cp;
  712. if (psor->dsign && psor->doffset)
  713. psor->doffset = ~psor->doffset + 1;
  714. l = psor->doffset;
  715. for (i = 0; i < p->dupdsc->duptype.duplong.llen; i++){
  716. *cp++ = l;
  717. l >>= 8;
  718. }
  719. }
  720. dfree ((char *)p->valrec );
  721. }
  722. else {
  723. if (psor->mode != 4 && !isdirect(psor))
  724. /* Immediate or direct only */
  725. errorc (E_IOT);
  726. if ((psor->fixtype == FGROUPSEG || psor->fixtype == FOFFSET) &&
  727. ((optyp == TDD && wordsize == 2 && !(psor->dtype&M_EXPLOFFSET)) ||
  728. optyp == TDF))
  729. psor->fixtype = FPOINTER;
  730. /* Size of item */
  731. varsize = psor->dsize;
  732. psor->dsize = datadsize[optyp - TDB];
  733. /* If item size is byte, make link output byte too */
  734. psor->w = TRUE;
  735. if (psor->dsize == 1) {
  736. psor->w--;
  737. if (psor->fixtype != FHIGH &&
  738. (psor->dflag == XTERNAL || psor->dsegment ||
  739. psor->dcontext))
  740. psor->fixtype = FLOW;
  741. }
  742. mapFixup(psor);
  743. *naim.pszName = NULL;
  744. if (psor->fixtype == FCONSTANT)
  745. p->dupdsc->type = typeFet(psor->dsize);
  746. else
  747. p->dupdsc->type = fnPtr(psor->dsize);
  748. p->dupdsc->dupkind = ITEM;
  749. p->dupdsc->duptype.dupitem.ddata = p->valrec;
  750. }
  751. }
  752. /*** initrs - initialize record/structure
  753. *
  754. * initrs (p);
  755. *
  756. * Entry
  757. * Exit
  758. * Returns
  759. * Calls
  760. */
  761. VOID PASCAL CODESIZE
  762. initrs (
  763. struct dsr *p
  764. ){
  765. register char *cp;
  766. SHORT cb;
  767. /* Initializing RECORD/STRUC */
  768. symptr = recptr;
  769. if (strucflag)
  770. p->dupdsc = strucparse ();
  771. else {
  772. /* Get value of record */
  773. p->i = recordparse ();
  774. /* Make long constant */
  775. p->dupdsc =
  776. (struct duprec FARSYM *)falloc (sizeof (*p->dupdsc), "initrs");
  777. p->dupdsc->dupkind = LONG;
  778. p->dupdsc->duptype.duplong.llen = cb = recptr->symtype;
  779. cp = nalloc (cb, "initrs");
  780. p->dupdsc->duptype.duplong.ldata = cp;
  781. p->dupdsc->type = typeFet(cb);
  782. while(cb--){
  783. *cp++ = p->i;
  784. p->i >>= 8;
  785. }
  786. }
  787. p->initlist = TRUE;
  788. }
  789. /*** datadb - process <db> directive
  790. *
  791. * datadb ();
  792. *
  793. * Entry *lbufp = beginning quote (\'|\") of string
  794. * Exit
  795. * Returns
  796. * Calls
  797. */
  798. VOID PASCAL CODESIZE
  799. datadb (
  800. register struct dsr *p
  801. ){
  802. register USHORT i;
  803. register char *cp;
  804. /* Save ptr to start of string */
  805. p->dirscan = lbufp;
  806. delim = NEXTC ();
  807. /* Compute string length */
  808. i = 0;
  809. while (!endstring ()) {
  810. SKIPC ();
  811. i++;
  812. }
  813. /* reset scan pointer */
  814. lbufp = p->dirscan;
  815. if (i == 0)
  816. errorc (E_EMS);
  817. else if (i > 1) {
  818. SKIPC ();
  819. /* Long string */
  820. p->longstr = TRUE;
  821. /* Create entry for long string */
  822. p->dupdsc =
  823. (struct duprec FARSYM *)falloc (sizeof (*p->dupdsc), "datadb");
  824. /* Initialize text area for data */
  825. p->dupdsc->dupkind = LONG;
  826. p->dupdsc->type = makeType(BT_ASCII, BT_DIRECT, BT_sz1);
  827. p->dupdsc->duptype.duplong.llen = i;
  828. cp = nalloc ( (USHORT)(p->dupdsc->duptype.duplong.llen + 1), "datadb");
  829. p->dupdsc->duptype.duplong.ldata = cp;
  830. for (; i; i--)
  831. if (!endstring ())
  832. *cp++ = NEXTC ();
  833. *cp = 0;
  834. SKIPC ();
  835. }
  836. }
  837. /*** dataitem - parse next data item from line
  838. *
  839. * dataitem (p);
  840. *
  841. * Entry p = pointer to datarec structure
  842. * Exit
  843. * Returns
  844. * Calls
  845. */
  846. VOID PASCAL CODESIZE
  847. dataitem (
  848. struct datarec *p
  849. ){
  850. struct duprec FARSYM *topitem;
  851. /* Scan , may recurse on DUP */
  852. topitem = datascan (p);
  853. /* Display scan now */
  854. displayflag = TRUE;
  855. /* Display data */
  856. scandup (topitem, dupdisplay);
  857. displayflag = FALSE;
  858. if (p->datalen == 0)
  859. p->datalen = topitem->rptcnt;
  860. if (topitem->dupkind == NEST) {
  861. /* This item was a DUP */
  862. resvspace = TRUE;
  863. /* Get size of DUP list */
  864. clausesize = calcsize (topitem);
  865. if (strucflag && initflag)
  866. resvspace = FALSE;
  867. if (pass2 && !(resvspace || p->buildfield))
  868. /* Send to linker */
  869. if (!emitdup (topitem))
  870. errorc (E_DTL);
  871. if (! p->type)
  872. p->type = topitem->type;
  873. if (p->buildfield)
  874. linkfield (topitem);
  875. else if (strucflag && initflag) {
  876. /* Allocating STRUC */
  877. strucflag = FALSE;
  878. /* Free overrides */
  879. scandup (strucoveride, oblitdup);
  880. /* Turn back on */
  881. strucflag = TRUE;
  882. }
  883. else /* Not STRUC allocate */
  884. scandup (topitem, oblitdup);
  885. }
  886. else {
  887. /* Some kind of list */
  888. clausesize = (topitem->dupkind == ITEM)
  889. ? topitem->duptype.dupitem.ddata->dsckind.opnd.dsize
  890. : topitem->duptype.duplong.llen;
  891. if (pass2 && !p->buildfield) {
  892. if (topitem->dupkind == ITEM)
  893. emitobject (&topitem->duptype.dupitem.ddata->dsckind.opnd);
  894. else
  895. emitlong (topitem);
  896. }
  897. if (! p->type)
  898. p->type = topitem->type;
  899. if (p->buildfield)
  900. linkfield (topitem);
  901. else
  902. oblitdup (topitem);
  903. }
  904. /* Add in size of this item */
  905. pcoffset += clausesize;
  906. skipblanks ();
  907. }
  908. /*** datadefine -
  909. *
  910. * datadefine ();
  911. *
  912. * Entry
  913. * Exit
  914. * Returns
  915. * Calls
  916. */
  917. VOID PASCAL CODESIZE
  918. datadefine (
  919. ){
  920. struct datarec a;
  921. short cc;
  922. strucoveride = NULL;
  923. a.buildfield = (strucflag && !initflag)? TRUE: FALSE;
  924. a.type = 0;
  925. if (labelflag) { /* Have label */
  926. labelcreate ( (USHORT)2, (UCHAR) (a.buildfield ? (UCHAR) STRUCFIELD : (UCHAR) CLABEL));
  927. if (errorcode == (E_ERRMASK & E_SDK))
  928. return;
  929. if (strucflag && initflag){
  930. a.type = recptr->symu.rsmsym.rsmtype.rsmstruc.type;
  931. }
  932. }
  933. else
  934. pcdisplay ();
  935. a.labelptr = symptr; /* Save ptr to entry */
  936. a.datalen = 0; /* Don't know length */
  937. emittext = FALSE; /* Prevent link emitter */
  938. duplevel = 0;
  939. /* Scan item list */
  940. if (ISTERM (PEEKC ()))
  941. errorc (E_OPN);
  942. else {
  943. BACKC ();
  944. do {
  945. SKIPC ();
  946. if ((cc = skipblanks ()) == ',' || cc == ';' || ISTERM(cc))
  947. errorc(E_MDZ);
  948. dataitem (&a);
  949. } while (PEEKC () == ',');
  950. }
  951. if (labelflag) {
  952. a.labelptr->symtype = datadsize[optyp - TDB];
  953. if (a.buildfield) {
  954. /* Making STRUC body */
  955. if (a.labelptr->symkind == STRUCFIELD) {
  956. if (struclabel)
  957. struclabel->symu.struk.strucnxt = a.labelptr;
  958. else
  959. recptr->symu.rsmsym.rsmtype.rsmstruc.struclist = a.labelptr;
  960. /* Constant, no segment */
  961. a.labelptr->symsegptr = NULL;
  962. /* End of named list */
  963. a.labelptr->symu.struk.strucnxt = NULL;
  964. a.labelptr->symu.struk.type = a.type;
  965. struclabel = a.labelptr;
  966. }
  967. }
  968. else
  969. a.labelptr->symu.clabel.type = a.type;
  970. /* Set length */
  971. a.labelptr->length = a.datalen;
  972. }
  973. emittext = TRUE;
  974. }
  975. /*** commDefine - define a communal variable
  976. *
  977. * Format: comm {far|near} name:size[:#Ofitems],....
  978. *
  979. */
  980. VOID PASCAL CODESIZE
  981. commDefine (
  982. ){
  983. USHORT distance;
  984. char cT, *pT;
  985. USHORT symtype;
  986. SYMBOL FARSYM *pSY;
  987. getatom ();
  988. distance = (farData[10] > '0')? CSFAR: CSNEAR;
  989. if (fnsize ()){ /* look for optional near | far */
  990. distance = varsize;
  991. getatom ();
  992. if (distance < CSFAR)
  993. errorc (E_UST);
  994. }
  995. cT = symFet (); /* fetch name and save for later */
  996. pSY = symptr;
  997. if (*naim.pszName == NULL){
  998. errorc(E_OPN);
  999. return;
  1000. }
  1001. if (NEXTC() != ':')
  1002. errorc (E_SYN);
  1003. /* get the size of the item */
  1004. pT = lbufp;
  1005. switchname ();
  1006. getatom();
  1007. if (symFet() && symptr->symkind == STRUC){
  1008. varsize = symptr->symtype;
  1009. }
  1010. else {
  1011. lbufp = pT;
  1012. if (pT = (char *)strchr(pT, ':'))
  1013. *pT = NULL;
  1014. varsize = exprconst();
  1015. if (pT)
  1016. *pT = ':';
  1017. }
  1018. if (!varsize)
  1019. errorc(E_IIS &~E_WARN1);
  1020. if (cT)
  1021. symptr = pSY;
  1022. externflag (DVAR, cT);
  1023. pSY = symptr;
  1024. pSY->symu.ext.length = 1;
  1025. pSY->symu.ext.commFlag++;
  1026. if (skipblanks() == ':'){ /* optional size given */
  1027. fArth32++; /* allow >64 items */
  1028. SKIPC();
  1029. if ((pSY->symu.ext.length = exprconst()) == 0) /* get the # items */
  1030. errorc(E_CXP);
  1031. fArth32--;
  1032. if (pSY->symu.ext.length * pSY->symtype > 0xffff)
  1033. pSY->symu.ext.commFlag++; /* for >64K convert to far */
  1034. }
  1035. if (distance == CSFAR)
  1036. pSY->symu.ext.commFlag++; /* 2 means far commdef */
  1037. }