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.

1238 lines
20 KiB

  1. title asmhelp - assembler helpers
  2. page ,132
  3. ;--------------------------------------------------------------------
  4. ;
  5. ; asmhelp fast assembly language helpers for masm
  6. ;
  7. ; (C)Copyright 1985 Microsoft Corp.
  8. ;
  9. ; Revision history
  10. ;
  11. ; 04/02/85 Greg Whitten
  12. ; initial version
  13. ; scanatom speedups
  14. ;
  15. ;--------------------------------------------------------------------
  16. ifndef MSDOS
  17. ifndef CPDOS
  18. .286
  19. endif
  20. endif
  21. .model medium,c
  22. if1
  23. alignCode macro
  24. align 4
  25. endm
  26. .xlist
  27. include mixed.inc
  28. .list
  29. .lall
  30. endif
  31. cLang = 1
  32. CASEL = 1
  33. SYMMAX = 31
  34. TSYMSIZE = 451 ; from asmsym.c
  35. LEGAL1ST = 08h ; legal 1st token character mask
  36. TOKLEGAL = 10h ; legal token character mask
  37. .code A_TEXT
  38. extrn Pascal ERRORC:near
  39. extrn Pascal CREFNEW:far
  40. extrn Pascal CREFOUT:far
  41. extrn Pascal OFFSETASCII:far
  42. extrn Pascal listline:far
  43. extrn Pascal crefline:far
  44. extrn Pascal tryOneFile:far
  45. extrn _ffree:far
  46. ifndef MSDOS
  47. extrn read:proc
  48. extrn write:proc
  49. extrn lseek:proc
  50. extrn free:proc
  51. endif
  52. ifdef CPDOS
  53. extrn Pascal DosRead:far
  54. extrn Pascal DosChgFilePtr:far
  55. extrn Pascal DosWrite:far
  56. endif
  57. .data
  58. extrn _asmctype_:byte
  59. extrn _asmcupper_:byte
  60. extrn _asmTokenMap_:byte
  61. extrn caseflag:byte
  62. extrn fCrefline:byte
  63. extrn fNeedList:byte
  64. extrn objing:byte
  65. extrn srceof:byte
  66. extrn crefing:byte
  67. extrn emitrecordtype:byte
  68. extrn linebp:word
  69. extrn linelength:byte
  70. extrn linebuffer:byte
  71. extrn linessrc:word
  72. extrn listconsole:byte
  73. extrn begatom:word
  74. extrn endatom:word
  75. extrn errorlineno:word
  76. extrn errorcode:word
  77. extrn oOMFCur:dword
  78. extrn handler:byte
  79. extrn lbufp:word
  80. extrn pass2:byte
  81. extrn save:byte
  82. extrn svname:word
  83. extrn obj:word
  84. extrn pFCBCur:word
  85. extrn naim:word
  86. extrn objerr:word
  87. extrn objectascii:word
  88. extrn iProcCur:word
  89. extrn symptr:dword
  90. extrn lsting:byte
  91. extrn lbuf:byte
  92. ifdef BCBOPT
  93. extrn hash:word
  94. extrn lcname:word
  95. extrn svhash:word
  96. extrn svlcname:word
  97. extrn fNoCompact:byte
  98. endif
  99. @CurSeg ends
  100. assume ds:nothing
  101. extrn tsym:dword
  102. assume ds:@data
  103. .data?
  104. mapstr db 10 dup(?) ; use this if /Ml
  105. ifdef M8086OPT
  106. qlcname db SYMMAX+1 dup(?)
  107. dw 1 dup(?) ;hash for name
  108. db 1 dup(?) ;cb for name
  109. qname db SYMMAX+1 dup(?)
  110. qsvlcname db SYMMAX+1 dup(?)
  111. dw 1 dup(?) ;hash for name
  112. db 1 dup(?) ;cb for name
  113. qsvname db SYMMAX+1 dup(?)
  114. endif
  115. ifdef M8086OPT
  116. public qlcname, qname, qsvlcname, qsvname
  117. endif
  118. .data
  119. fEatBlanks db 1 ; flag for common getatom & getatomend
  120. cbLeft dw 0 ; count of bytes left in lbuf
  121. rarea dw 0 ; area for DosRead/Write to tell how much it read
  122. .code A_TEXT
  123. ifdef M8086OPT
  124. ;*** getatom () ( hash = scanatom() )
  125. nulToken:
  126. mov lbufp,si ; update buffer pointer
  127. mov [di+SYMMAX+4],bh
  128. pop di
  129. pop si
  130. retn
  131. getatomComm:
  132. hProc <getatom near>, <uses si di>
  133. mov ax,ds
  134. mov es,ax
  135. mov di,lbufp
  136. mov ax,0920H ; load tab|space into AX
  137. or cx,0FFFFH ; large count to CX
  138. alignCode
  139. skipbeg:
  140. repe scasb ; look for space
  141. xchg al,ah
  142. dec di
  143. repe scasb ; then tab
  144. dec di
  145. cmp byte ptr [di],ah
  146. je skipbeg ; repeat if still space
  147. xor ax,ax
  148. xor bx,bx
  149. mov si,di
  150. mov di,lcname
  151. mov bl,[si]
  152. test byte ptr _asmctype_[bx],LEGAL1ST
  153. jz nulToken
  154. xor dx,dx ; initial hash value
  155. mov cx,SYMMAX
  156. mov begatom,si ; start of atom
  157. cmp bl,'.' ;special case for token starting
  158. jne notDot ;with .
  159. inc si
  160. dec cx
  161. mov al,bl
  162. mov dx,ax
  163. stosb
  164. mov [di+SYMMAX+3],al
  165. notDot:
  166. mov bx,offset _asmTokenMap_ ; character translation table
  167. cmp caseflag,CASEL
  168. je short tokloop ; Mu or Mx - use MAP version
  169. alignCode
  170. Mtokloop:
  171. rept 3
  172. lodsb ; al = get next character
  173. stosb ; *lcname++ = cc
  174. xlat
  175. mov [di+SYMMAX+3],al ; *naim++ = cc
  176. add dx,ax ; swapped hash += MAP(cc)
  177. dec cx
  178. or al,al
  179. jz short tokdone
  180. jcxz skiptok
  181. endm
  182. lodsb
  183. stosb
  184. xlat
  185. mov [di+SYMMAX+3],al
  186. add dx,ax
  187. or al,al
  188. loopnz Mtokloop
  189. jz tokdone
  190. jmp skiptok
  191. tokloop:
  192. rept 3
  193. lodsb ; al = get next character
  194. stosb ; *lcname++ = cc
  195. mov [di+SYMMAX+3],al ; *naim++ = cc
  196. xlat
  197. add dx,ax ; swapped hash += MAP(cc)
  198. dec cx
  199. or al,al
  200. jz short tokdone0
  201. jcxz skiptok
  202. endm
  203. lodsb
  204. stosb
  205. mov [di+SYMMAX+3],al
  206. xlat
  207. add dx,ax
  208. or al,al
  209. loopnz tokloop
  210. jz tokdone0
  211. jmp short skiptok
  212. tokdone0:
  213. mov [di+SYMMAX+3],al ; terminate
  214. tokdone:
  215. mov [di-1],al
  216. dec si
  217. mov endatom,si
  218. jmp short skipend
  219. skiptok:
  220. dec cx
  221. skipnext:
  222. lodsb ; eat extra characters in token
  223. xlat
  224. or al,al
  225. jnz skipnext ; skip token
  226. mov endatom,si
  227. mov [di],al
  228. inc di
  229. mov [di+SYMMAX+3],al ; terminate
  230. dec si
  231. skipend: ; skip for getatom only
  232. mov bx,cx
  233. mov di,si
  234. cmp fEatBlanks,0
  235. jz noEatSemie
  236. mov ax,0920H ; load tab|space into AX
  237. or cx,0FFFFH ; large count to CX
  238. alignCode
  239. skipend1:
  240. repe scasb ; look for space
  241. xchg al,ah
  242. dec di
  243. repe scasb ; then tab
  244. dec di
  245. cmp byte ptr [di],ah
  246. je skipend1 ; repeat if still space
  247. skipend2: ; skip trailing white space
  248. mov lbufp,di ; update buffer pointer
  249. xor ax,ax
  250. mov al,SYMMAX-1 ; compute token length
  251. sub al,bl
  252. mov bx,naim
  253. mov byte ptr [bx-1],al ; save prefixed cb
  254. mov word ptr [bx-3],dx ; save prefixed hash
  255. hRet
  256. noEatSemie:
  257. mov fEatBlanks,1
  258. jmp skipend2
  259. hEndp
  260. ;*** getatomend () ; get an token without skiping trailing spaces
  261. hProc <getatomend near>
  262. mov fEatBlanks,0
  263. jmp getatomComm
  264. hEndp
  265. endif ;M8086OPT
  266. ifdef M8086OPT
  267. ;*** inset (value, setptr)
  268. hProc <inset near>, <uses si di>, value:byte, setptr:word
  269. mov ax,ds
  270. mov es,ax
  271. cld
  272. mov al,value
  273. mov di,setptr
  274. mov cl,[di]
  275. inc di
  276. xor ch,ch ; cx = set length
  277. repne scasb ; scan for al in es:di
  278. je insetT ; yes - return TRUE
  279. xor ax,ax ; return FALSE
  280. insetexit:
  281. hRet
  282. insetT: mov ax,1 ; return TRUE
  283. jmp short insetexit
  284. hEndp
  285. endif ;M8086OPT
  286. ;*** strffcmp (far1, far2)
  287. hProc <strffcmp far>, <uses si di>, far1:dword, far2:dword
  288. cld
  289. les di,far2
  290. lds si,far1
  291. mov bx,di ; save start of string
  292. cmpsb ; fast 1st char check
  293. jnz ffne
  294. dec si
  295. xor ax,ax ; search for 0 terminator
  296. mov cx,-1
  297. repne scasb
  298. neg cx ; cx = byte count for compare
  299. mov di,bx
  300. repz cmpsb
  301. ffne: mov al,[si-1]
  302. sub al,es:[di-1] ; ax = 0 if equal
  303. cbw
  304. push ss
  305. pop ds
  306. hRet
  307. hEndp
  308. ;*** strnfcmp (near1, far2)
  309. hProc <strnfcmp near>, <uses di si>, near1:word, far2:dword
  310. cld
  311. mov si,near1
  312. les di,far2
  313. mov bx,di ; save start of string
  314. cmpsb ; fast check on 1st character
  315. jnz nfne
  316. dec si
  317. xor ax,ax ; search for 0 terminator
  318. mov cx,-1
  319. repne scasb
  320. neg cx ; cx = byte count for compare
  321. mov di,bx
  322. repz cmpsb
  323. nfne: mov al,[si-1]
  324. sub al,es:[di-1] ; ax = 0 if equal
  325. hRet
  326. hEndp
  327. ifdef M8086OPT
  328. ;*** switchname ()
  329. hProc <switchname near>
  330. alignCode
  331. mov ax,naim ;; (naim) <--> (svname)
  332. xchg ax,svname
  333. mov naim,ax
  334. mov ax,lcname ;; (lcname) <--> (svlcname)
  335. xchg ax,svlcname
  336. mov lcname,ax
  337. hRet
  338. hEndP
  339. endif ;M8086OPT
  340. ifdef M8086OPT
  341. ;*** I/O routines: readmore, getline, ebuffer, etc.
  342. objfile struc
  343. ofh dw ?
  344. ifdef MSDOS
  345. pos dd ?
  346. buf dd ?
  347. else
  348. pos dw ?
  349. buf dw ?
  350. endif ;MSDOS
  351. cnt dw ?
  352. siz dw ?
  353. oname dw ?
  354. objfile ends
  355. endif ;M8086OPT
  356. ifdef M8086OPT
  357. ;*** ebuffer - write out object buffer
  358. ;
  359. ; ebuffer (rectype, bufpos, buffer)
  360. ebyte macro
  361. dec [bx].cnt
  362. jge short $+5
  363. call edump ; dump buffer
  364. stosb
  365. add ah,al
  366. endm
  367. hProc <ebuffer near>, <uses si di>, rectype:byte, bufpos:word, buffer:word
  368. mov si,buffer
  369. mov cx,bufpos
  370. sub cx,si ; cx = buffer count
  371. jz ebufdone
  372. cmp objing,0
  373. je ebufdone ; return if no object file
  374. mov ax,cx
  375. add ax,4
  376. add word ptr oOMFCur,ax ; oOMFCur += cbBuffer + 3
  377. adc word ptr oOMFCur.2,0
  378. ifndef MSDOS
  379. mov ax,ds
  380. mov es,ax
  381. endif
  382. cld
  383. xor ax,ax ; ah = 0 (initial checksum)
  384. mov al,rectype
  385. mov bx,OFFSET obj ; bx = obj file data structure pointer
  386. ifdef MSDOS
  387. les di,[bx].pos ; es:di = output buffer position
  388. else
  389. mov di,[bx].pos ; di = output buffer position
  390. endif
  391. ebyte ; output record type
  392. inc cx ; + 1 for record length
  393. mov al,cl
  394. ebyte
  395. mov al,ch
  396. ebyte ; output record length
  397. dec cx ; - 1 for buffer loop
  398. alignCode
  399. ebufloop: ; output buffer
  400. lodsb
  401. ebyte
  402. loop ebufloop
  403. mov al,ah ; output checksum
  404. neg al
  405. ebyte
  406. ifdef MSDOS
  407. mov word ptr [bx].pos,di ; reset buffer position
  408. else
  409. mov [bx].pos,di ; reset buffer position
  410. endif
  411. ebufdone:
  412. mov emitrecordtype,0
  413. hRet
  414. hEndp
  415. ; edump
  416. ;
  417. ; Save:
  418. ; bx = obj file descriptor pointer
  419. ; ax = (checksum,outputbyte)
  420. ; cx = possible count
  421. ; si = emit buffer position
  422. edump: push ax
  423. push cx
  424. push bx ; save src file descriptor pointer
  425. ifdef MSDOS
  426. push ds
  427. mov cx,[bx].siz
  428. mov ax,[bx].ofh
  429. lds dx,[bx].buf
  430. mov bh,40h
  431. xchg ax,bx
  432. ifdef CPDOS
  433. push bx ; file handle
  434. push ds ; buffer (selector)
  435. push dx ; buffer (offset)
  436. push cx ; # bytes to read
  437. mov ax,@data
  438. push ax ; reply area (selector)
  439. mov ax,offset rarea
  440. push ax ; reply area (offset)
  441. call DosWrite
  442. else
  443. int 21h
  444. endif
  445. pop ds
  446. ifdef CPDOS
  447. or ax,ax
  448. mov ax,rarea
  449. jnz writerr
  450. else
  451. jc writerr
  452. endif
  453. pop bx
  454. push bx
  455. cmp ax,[bx].siz
  456. je writeok
  457. writerr:
  458. mov objerr,-1
  459. writeok:
  460. else
  461. push [bx].siz
  462. push [bx].buf
  463. push [bx].ofh
  464. call write ; write (ofh,buf,siz)
  465. add sp,6
  466. pop bx ; need to get bx back.
  467. push bx ; write trashes it. -Hans
  468. cmp ax,[bx].siz
  469. je writeok
  470. mov objerr,-1
  471. writeok:
  472. mov ax,ds
  473. mov es,ax
  474. cld ; in case
  475. endif
  476. pop bx
  477. mov ax,[bx].siz
  478. dec ax
  479. mov [bx].cnt,ax ; reset buffer position
  480. ifdef MSDOS
  481. mov di,word ptr [bx].buf ; di = start of buffer
  482. else
  483. mov di,[bx].buf ; di = start of buffer
  484. endif
  485. pop cx
  486. pop ax
  487. ret
  488. endif ;M8086OPT
  489. hProc <fMemcpy near>, <uses si di>, pDest:dword, pSource:dword, cb:word
  490. mov cx,cb
  491. jcxz fM1
  492. mov dx,ds
  493. lds si,pSource
  494. les di,pDest
  495. shr cx,1
  496. rep movsw
  497. jnc fM01
  498. movsb
  499. fM01:
  500. mov ds,Dx
  501. fM1:
  502. hRet
  503. hEndp
  504. ifdef M8086OPT
  505. ; Native code version of symsrch as in asmsym.c
  506. hProc <symsrch near>, <uses si di>
  507. mov si,naim
  508. xor Dx,Dx
  509. cmp byte ptr[si-1],dl
  510. jne sy001
  511. jmp sy99
  512. sy001:
  513. mov Ax,word ptr[si-3]
  514. mov Cx,TSYMSIZE
  515. div Cx
  516. mov Bx,Dx ;index into hash table
  517. shl Bx,1
  518. shl Bx,1
  519. mov Ax,SEG tsym
  520. mov Es,Ax
  521. les di,dword ptr es:[Bx].tsym
  522. mov Ax,es
  523. or Ax,Ax ;if segment 0
  524. jne sy002
  525. jmp sy991
  526. sy002:
  527. mov Ax,word ptr[si-3]
  528. mov Dx,si
  529. xor Cx,Cx
  530. jmp short syLook
  531. alignCode
  532. syNext:
  533. les di,es:[di] ; next symbol
  534. mov Bx,es
  535. or Bx,Bx ; continue if segment not 0
  536. jnz sylook
  537. jmp sy99
  538. syLook:
  539. mov bx,es:[di].12 ; pointer to name
  540. cmp Ax,es:[Bx] ; check hash values
  541. jne syNext
  542. xchg Bx,di
  543. mov cl,[si-1] ; lenght to cl
  544. inc Cx
  545. inc di
  546. inc di ; skip hash
  547. repz cmpsb ; check actual strings
  548. mov di,Bx ; restore pointers
  549. mov si,Dx
  550. jnz syNext
  551. syFound:
  552. cmp byte ptr es:[bx].1bH,12 ; if (p->symkind == CLABEL)
  553. jne @F
  554. @@:
  555. mov cx,iProcCur
  556. jcxz noNest
  557. push ax
  558. cmp byte ptr es:[bx].1bH,2 ; if (p->symkind == CLABEL)
  559. jne sy1
  560. mov Ax,word ptr es:[bx].22h ; if (p->iProc)
  561. sy01:
  562. or ax,ax
  563. jz noNest0
  564. cmp cx,Ax ; if (p->iProc != iProcCur)
  565. je noNest0
  566. pop ax
  567. xor cx,cx
  568. jmp syNext
  569. sy1:
  570. cmp byte ptr es:[bx].1bH,6 ; if (p->symkind == EQU)
  571. jne noNest0
  572. mov Ax,word ptr es:[bx].1eh ; AX = p->csassume
  573. jmp sy01
  574. noNest0:
  575. pop ax
  576. noNest:
  577. mov word ptr symptr,Bx
  578. mov word ptr symptr+2,es
  579. mov Ax,1
  580. cmp crefing,al
  581. je syCref
  582. hRet ;Return true
  583. syCref:
  584. push Ax ;call crefing routines
  585. call crefnew
  586. call crefout
  587. mov al,1
  588. jmp short sy991
  589. sy99:
  590. xor Ax,Ax
  591. sy991:
  592. hRet
  593. hEndp
  594. endif ;M8086OPT
  595. ifdef M8086OPT
  596. ;int PASCAL iskey (table)
  597. hProc <iskey near>, <uses si di>, table:dword
  598. hLocal l1:word, l2:word
  599. cld
  600. mov si,naim
  601. cmp caseflag,1 ;if (caseflag == CASEL) {
  602. jne noComputeHash
  603. xor Dx,Dx ;nhash = 0;
  604. ;|*** for (uc = mapstr, lc = str; *lc; )
  605. push ds
  606. pop es
  607. mov di,OFFSET mapstr
  608. xor bh,bh
  609. mov ah,bh
  610. alignCode
  611. $F791:
  612. lodsb
  613. or al,al
  614. jz $L2001
  615. mov bl,al
  616. mov al,BYTE PTR _asmcupper_[bx]
  617. stosb
  618. add Dx,Ax
  619. jmp short $F791
  620. $L2001:
  621. ;|*** *uc = 0;
  622. stosb ;0 terminate string
  623. ;|*** uc = mapstr;
  624. mov si,OFFSET mapstr
  625. mov Cx,di
  626. sub Cx,si ;cb of string into Cx
  627. mov Ax,Dx ;hash to Ax
  628. jmp SHORT storeNhash ;Ax has computed hash
  629. noComputeHash:
  630. xor cx,cx
  631. mov cl,[si-1]
  632. inc Cx ;include NULL
  633. mov ax,[si-3]
  634. storeNhash:
  635. mov l1,ax ;nhash
  636. mov l2,Cx ;cb
  637. ;|*** for (p = table->kttable[nhash % table->ktsize]; p; p = p->knext)
  638. les bx,table
  639. mov di,es:[bx] ;es now contains symbol table segment
  640. cwd
  641. idiv WORD PTR es:[bx+2]
  642. shl dx,1
  643. add di,dx
  644. mov Bx,si ;save uc name
  645. alignCode
  646. isLook:
  647. cmp word ptr es:[di],0
  648. je isNotFound
  649. mov di,es:[di]
  650. ;|*** if ((nhash == p->khash) && (!strcmp (p->kname,uc)))
  651. mov Ax,l1 ;nhash
  652. cmp es:[di+4],Ax
  653. jne isLook
  654. ; do an inline string compare
  655. mov Dx,di ; save p
  656. mov Cx,l2 ;cB
  657. mov di,WORD PTR es:[di+2] ;Es:di = p->kname
  658. repe cmpsb ; compare while equal
  659. jcxz isFound
  660. mov di,Dx ;restore registers
  661. mov si,Bx
  662. jmp isLook
  663. ;|*** return (p->ktoken);
  664. isFound:
  665. mov di,Dx
  666. mov Ax,es:[di+6]
  667. jmp SHORT isReturn
  668. isNotFound:
  669. alignCode
  670. mov ax,-1
  671. isReturn:
  672. hRet
  673. hEndp
  674. endif ;M8086OPT
  675. ifdef M8086OPT
  676. hProc <skipblanks near>
  677. mov bx,lbufp
  678. dec bx
  679. alignCode
  680. ik1: ; skip leading white space
  681. inc bx
  682. mov al,[Bx]
  683. cmp al,' '
  684. je ik1
  685. cmp al,9
  686. je ik1
  687. mov lbufp,bx
  688. hRet
  689. hEndp
  690. endif
  691. MC struc ;structure for macro call, see asm86.h for full comments
  692. pTSHead dd ?
  693. pTSCur dd ?
  694. flags db ?
  695. iLocal db ?
  696. cbParms dw ?
  697. locBase dw ?
  698. countMC dw ?
  699. pParmNames dw ?
  700. pParmAct dw ?
  701. svcondlevel db ?
  702. svlastcond db ?
  703. svelseflag db ?
  704. db ?
  705. rgPV dw ?
  706. MC ends
  707. ifdef M8086OPT
  708. leOverflow2:
  709. pop ax
  710. leOverflow:
  711. push ss
  712. pop ds
  713. xor Ax,Ax
  714. stosb ; terminate line
  715. mov ax, 100 ; E_LTL
  716. push AX ; print error message
  717. call ERRORC
  718. jmp leFin2
  719. ; fast version to expand macro bodies / coded in C in asmirp.c
  720. hProc <lineExpand near>, <uses si di>, pMC:word, pMacroLine:dword
  721. assume es:@data
  722. ifdef BCBOPT
  723. mov fNoCompact, 0
  724. endif
  725. mov cbLeft, 511 ; LBUFMAX (asm86.h) - 4
  726. les si,pMacroLine ; get pointer to macro prototype
  727. mov bx,pMC
  728. mov dl,[bx].iLocal ; dl: local base index
  729. mov dh,080H ; dh: local base with high bit set
  730. add dh,dl
  731. lea bp,[bx].rgPV ; bp: pointer to actual arg array
  732. mov di,offset lbuf ; si: pointer to new line
  733. push ds
  734. mov Ax,Es
  735. mov ds,Ax ; set seg regs for ds:si & es:di
  736. pop es
  737. xor ah,ah
  738. xor ch,ch ; set loop invariate
  739. le1:
  740. lodsb ; fetch next prefix
  741. test al,080H ; check for parm
  742. jnz leParmFound
  743. mov cl,al
  744. jcxz leFinished
  745. sub es:[cbLeft],ax
  746. jc leOverflow
  747. repz movsb ; move non parameter entry
  748. jmp le1
  749. leParmFound: ; argment found
  750. mov bl,al ; compute index
  751. shl bx,1
  752. shl bx,1
  753. and bx,01FFH ; remove shifted high bit
  754. add Bx,Bp
  755. push ds
  756. push es
  757. pop ds ; save current ds and set to near
  758. cmp al,dh ; determine parm type
  759. jae leLocalFound
  760. mov Bx,word ptr[Bx] ; fetch pointer to actual
  761. xchg Bx,si ; save pMacroLine
  762. lodsb
  763. mov cl,al
  764. jcxz leNullArg
  765. sub cbLeft,ax
  766. jnc le2
  767. jmp leOverflow2
  768. le2:
  769. repz movsb ; move parameter entry
  770. leNullArg:
  771. mov si,Bx ; restore saved pMacroLine
  772. pop ds
  773. xor ah, ah
  774. jmp le1
  775. leLocalFound:
  776. cmp word ptr[Bx],0 ; check to see if the local
  777. jz leBuildLocal ; is defined
  778. leLocalMove:
  779. xchg Bx,si ; save pMacroLine
  780. sub cbLeft,6
  781. jnc le3
  782. jmp leOverflow2
  783. le3:
  784. mov Ax,'??' ; store leading ??
  785. stosw
  786. movsw ; and then remaining xxxx
  787. movsw
  788. jmp leNullArg
  789. leBuildLocal:
  790. push Dx ; call runtime helper to generate name
  791. push Bx
  792. push Es
  793. xor ah,ah
  794. sub al,dh
  795. mov Bx,Sp ; fetch pMC
  796. mov Bx,[Bx+8+4+4]
  797. add Ax,[Bx].locBase
  798. xor Bx,BX
  799. push Bx ; offsetAscii((long) .. )
  800. push Ax
  801. call offsetAscii
  802. pop Es
  803. pop Bx
  804. pop Dx
  805. mov Ax,objectascii ; copy 4 byte local name to cach
  806. mov [Bx],AX
  807. mov Ax,objectascii+2
  808. mov [Bx].2,AX
  809. jmp leLocalMove
  810. leFinished:
  811. mov ax,es ; restore ds
  812. mov ds,ax
  813. leFin2:
  814. mov linebp,di ; set linebp
  815. mov si,offset lbuf
  816. mov lbufp,si ; lbufp= lbuf
  817. sub di,si
  818. mov cx, di
  819. mov linelength, al ; linelength = linbp - lbuf
  820. cmp fNeedList,0 ;for listing copy to list buffer
  821. je @F
  822. mov di,offset linebuffer
  823. shr cx,1
  824. rep movsw
  825. rcl cx,1
  826. rep movsb
  827. @@:
  828. .8086
  829. hRet
  830. ifndef MSDOS
  831. .286
  832. endif
  833. hEndp
  834. endif ;M8086OPT
  835. ifdef M8086OPT
  836. ;*** expandTM - expand text macro in naim in lbuf/lbufp
  837. ;*
  838. ;* expandTM (equtext);
  839. ;*
  840. ;* Entry equtext = replacement string
  841. ;* naim = text macro
  842. ;* begatom = first character in lbuf to replace
  843. ;* endatom = first character in lbuf after string to replace
  844. ;* Exit lbuf = new line to be parsed
  845. ;* Returns
  846. ;* Calls
  847. ;* Note Shifts characters from lbufp to make substitution of TM.
  848. ;* Inserts replacement string at begatom
  849. ;*/
  850. hProc <expandTM near>, <uses si di>, equtext:word
  851. hLocal cbEndatom:word, cbNaim:word, cbText:word, fShifted:byte
  852. cld ; String instructions go forward
  853. mov ax, ds ; Set es to @data
  854. mov es, ax ;
  855. xor ax, ax ; Will stop scanning when [di] == [al] == 0
  856. mov fshifted, 0 ; Haven't shifted line yet
  857. mov cx, linebp ; Calculate cbEndatom == strlen(endatom)
  858. sub cx, endatom ; but use (linebp - endatom + 1) as method
  859. inc cx ;
  860. mov cbEndatom, cx ; Store result in cbEndatom
  861. mov cx, endatom ; Calculate cbNaim == strlen(naim)
  862. sub cx, begatom ; but use (endatom - begatom) as method
  863. mov cbNaim, cx ; Store result in cbNaim
  864. mov di, equtext ; Calculate cbText == strlen(equtext)
  865. mov cx, -1 ;
  866. repne scasb ;
  867. not cx ; [cx] == length of equtext
  868. dec cx ; don't count NULL
  869. mov cbText, cx ; Store result in cbText
  870. cmp cbNaim, cx ; Q: Is replacement longer than name?
  871. jl shiftline ; Y: Must shift endatom string to the right
  872. copytext:
  873. mov di, begatom ; Copy replacement text into lbuf
  874. mov si, equtext ;
  875. mov cx, cbText ; Number of bytes to copy
  876. shr cx, 1 ;
  877. rep movsw ;
  878. jnc etm2 ;
  879. movsb ;
  880. etm2:
  881. cmp fShifted, 0 ; Q: Have already shifted line right?
  882. jne etmEnd ; Y: Done
  883. mov si, endatom ; Q: Is cbNaim == cbText?
  884. cmp di, si ;
  885. je etmEnd ; Y: Done
  886. mov cx, cbEndatom ; N: Must shift endatom string left
  887. shr cx, 1 ;
  888. rep movsw ;
  889. jnc etm3 ;
  890. movsb ;
  891. etm3:
  892. mov linebp, di ;
  893. jmp etmEnd ; Done
  894. shiftline: ; Shift string at endatom to right
  895. mov cx, cbEndatom ; Number of bytes to move
  896. mov si, linebp ; [si] = end of string in lbuf
  897. mov di, si ;
  898. add di, cbText ;
  899. sub di, cbNaim ; di == si + amount to shift string right
  900. mov linebp, di ;
  901. mov dx, di ; check if line too long
  902. sub dx, OFFSET lbuf ;
  903. cmp dx, 512 ; LBUFMAX (asm86.h)
  904. jge eltl ; line too long
  905. std ; String instructions go backwards
  906. rep movsb ; Shift line
  907. inc fShifted ;
  908. cld ; String instructions go forward again
  909. jmp copytext ;
  910. eltl:
  911. mov ax,100 ; Error E_LTL Line too long
  912. push ax ;
  913. call ERRORC ;
  914. mov di, begatom
  915. mov byte ptr [di], 0 ; Truncate line
  916. etmEnd:
  917. mov ax, begatom ; Reset lbufp to point to start of next
  918. mov lbufp, ax ; token
  919. hRet
  920. hEndp
  921. endif ;M8086OPT
  922. ifdef MSDOS
  923. ifdef M8086OPT
  924. ;*** farwrite - write with far buffer
  925. ; farwrite(ofh,buf,count);
  926. hProc <farwrite far>, handle:word, buffer:dword, count:word
  927. mov ax,handle
  928. mov cx,count
  929. push ds
  930. lds dx,buffer
  931. mov bh,40h ; write
  932. xchg ax,bx
  933. ifdef CPDOS
  934. push bx ; file handle
  935. push ds ; buffer (selector)
  936. push dx ; buffer (offset)
  937. push cx ; # bytes to read
  938. mov ax,@data
  939. push ax ; reply area (selector)
  940. mov ax,offset rarea
  941. push ax ; reply area (offset)
  942. call DosWrite
  943. else
  944. int 21h
  945. endif
  946. pop ds
  947. ifdef CPDOS
  948. or ax,ax
  949. mov ax, word ptr rarea
  950. jnz fwriterr
  951. else
  952. jc fwriterr
  953. endif
  954. cmp ax,count
  955. je fwriteok
  956. fwriterr:
  957. mov objerr,-1
  958. fwriteok:
  959. hRet
  960. hEndp
  961. endif ;M8086OPT
  962. endif
  963. ;*** farAvail ()
  964. ifdef MSDOS
  965. ifndef CPDOS
  966. hProc <farAvail far>
  967. or Bx,0FFFFH ;request max memory from dos
  968. mov ah,48H ;paragraphs left in Bx
  969. int 21H
  970. mov ah,48H ;then allocate it
  971. int 21H
  972. jnc noMem
  973. xor Bx,Bx
  974. noMem:
  975. mov Ax,16
  976. cwd
  977. mul Bx ;return paragraphs * 16
  978. hRet
  979. hEndp
  980. endif
  981. endif
  982. end