Source code of Windows XP (NT5)
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.

1319 lines
24 KiB

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